python中的按位和图像分辨率计算。有人可以解释代码吗?
Bitwise and image resolution calculation in python. Can someone explain the code?
with open("image.jpg",'rb') as file:
file.seek(163)
a = file.read(2)
height = (a[0] << 8) - a[1]
a = file.read(2)
width = (a[0] << 8) - a[1]
print(str(height) + " x " + str(width))
我还在学习python。我知道按位运算符左移和右移。但是我不明白这段代码。
我的理解是:
- 我们打开二进制读取的图像作为文件。
- 用
file.seek()
移动光标到163。为什么是 163?
- 读取大小为2字节的文件。为什么?
第4行和第6行我完全看不懂。打印功能没问题
我尝试使用 Pillow 和 cv2。但是以防万一,我不能使用那些模块,我想我应该知道这个。
它粗糙而丑陋,但阅读 SOF0
其中包含图像的高度和宽度,请参阅 this 文章的末尾。其实也是不对的。应该是:
with open("image.jpg",'rb') as file:
file.seek(163)
a = file.read(2)
height = (a[0] << 8) | a[1] # It should be ORed in not subtracted
print(height)
a = file.read(2)
width = (a[0] << 8) | a[1] # It should be ORed in not subtracted
print(width)
另请参阅 Wikipedia JPEG 条目。
作为一个小例子,让我们用 ImageMagick 制作一个 640x480 的红色 JPEG:
magick -size 640x480 xc:red image.jpg
现在让我们寻找 SOF0
标记,即 FF C0
:
xxd -c16 -g1 -u image.jpg | grep -A2 "FF C0"
00000090: 10 10 10 10 10 10 10 10 10 10 10 10 10 10 FF C0 ................
000000a0: 00 11 08 01 E0 02 80 03 01 11 00 02 11 01 03 11 ................
000000b0: 01 FF C4 00 15 00 01 01 00 00 00 00 00 00 00 00 ................
如果我们检查 640 和 480 的十六进制形式:
printf "%x %x" 480 640
1e0 280
您可以在文件中的偏移量 163 处看到它们,因为偏移量 a0
是 160,我们距离它有 3 个字节。
这是简单语言的代码:
- 以读取模式打开 image.jpg 文件作为二进制变量 'file'
- 将光标移动到 163(以到达存储第 0 帧大小的位置(JPEG 文件的内部结构的一部分,不一定总是在该位置))
- 将存储高度的2个字节读入变量a
- 通过将第一个字节左移 8 位然后左移然后减去第二个字节来获得高度(注意这没有给出正确答案,- 应该是 | 而不是)
- 将存放宽度的2个字节读入变量a
- 通过将第一个字节左移 8 位然后减去第二个字节来获得宽度(请注意,这不会给出正确答案,- 应该是 | 而不是)
- 将高度和宽度打印为 'height x width' 格式的字符串
这里有一篇关于解码 JPEG 的好文章1
with open("image.jpg",'rb') as file:
file.seek(163)
a = file.read(2)
height = (a[0] << 8) - a[1]
a = file.read(2)
width = (a[0] << 8) - a[1]
print(str(height) + " x " + str(width))
我还在学习python。我知道按位运算符左移和右移。但是我不明白这段代码。
我的理解是:
- 我们打开二进制读取的图像作为文件。
- 用
file.seek()
移动光标到163。为什么是 163? - 读取大小为2字节的文件。为什么?
第4行和第6行我完全看不懂。打印功能没问题
我尝试使用 Pillow 和 cv2。但是以防万一,我不能使用那些模块,我想我应该知道这个。
它粗糙而丑陋,但阅读 SOF0
其中包含图像的高度和宽度,请参阅 this 文章的末尾。其实也是不对的。应该是:
with open("image.jpg",'rb') as file:
file.seek(163)
a = file.read(2)
height = (a[0] << 8) | a[1] # It should be ORed in not subtracted
print(height)
a = file.read(2)
width = (a[0] << 8) | a[1] # It should be ORed in not subtracted
print(width)
另请参阅 Wikipedia JPEG 条目。
作为一个小例子,让我们用 ImageMagick 制作一个 640x480 的红色 JPEG:
magick -size 640x480 xc:red image.jpg
现在让我们寻找 SOF0
标记,即 FF C0
:
xxd -c16 -g1 -u image.jpg | grep -A2 "FF C0"
00000090: 10 10 10 10 10 10 10 10 10 10 10 10 10 10 FF C0 ................
000000a0: 00 11 08 01 E0 02 80 03 01 11 00 02 11 01 03 11 ................
000000b0: 01 FF C4 00 15 00 01 01 00 00 00 00 00 00 00 00 ................
如果我们检查 640 和 480 的十六进制形式:
printf "%x %x" 480 640
1e0 280
您可以在文件中的偏移量 163 处看到它们,因为偏移量 a0
是 160,我们距离它有 3 个字节。
这是简单语言的代码:
- 以读取模式打开 image.jpg 文件作为二进制变量 'file'
- 将光标移动到 163(以到达存储第 0 帧大小的位置(JPEG 文件的内部结构的一部分,不一定总是在该位置))
- 将存储高度的2个字节读入变量a
- 通过将第一个字节左移 8 位然后左移然后减去第二个字节来获得高度(注意这没有给出正确答案,- 应该是 | 而不是)
- 将存放宽度的2个字节读入变量a
- 通过将第一个字节左移 8 位然后减去第二个字节来获得宽度(请注意,这不会给出正确答案,- 应该是 | 而不是)
- 将高度和宽度打印为 'height x width' 格式的字符串
这里有一篇关于解码 JPEG 的好文章1