在JPEG文件中更新JFIF缩略图

时间:2014-05-08 09:19:52

标签: python image jpeg exif jfif

我正在尝试使用Python更新JPEG文件中的嵌入式JFIF缩略图。

这是应该实现这个目标的(略微hackish)方法:

def set_thumbnail(self, data):
    # Data of the updated thumbnail
    data = bytearray(data)
    # Get offset of the old thumbnail data
    offset = (self._exif_start +
              self._unpack('I', self._get_tag_offset(0x201)+8))
    # Get size of the old thumbnail
    old_size = self._unpack('I', self._get_tag_offset(0x202)+8)
    try:
        # Strip everything between the JFIF APP1 and the quant table
        jfif_start = data.index('\xff\xe0')
        quant_start = data.index('\xff\xdb')
        stripped_data = data[0:jfif_start] + data[quant_start:]
    except ValueError:
        stripped_data = data
    # Writes the new length to the buffer
    self._pack('I', self._get_tag_offset(0x202)+8, len(stripped_data))
    # Writes the new data to the image buffer
    self._buf[offset:offset+old_size] = stripped_data

当我重写旧缩略图时,此功能正常工作,即缩略图数据的大小不会改变。但是,一旦我对它应用了一些转换(例如裁剪或旋转)并再次存储它,结果文件似乎不再有效。

我上传了original imageone with an updated thumbnail,以便更好地进行比较。

我从中获得的错误,例如identify如下:

identify.im6: Invalid JPEG file structure: two SOI markers `/tmp/thumb_rotated.jpg' @ error/jpeg.c/JPEGErrorHandler/316.

在对两个图像进行差异处理时,0x202尺寸标记中的值与嵌入的缩略图数据的大小相匹配,因此文件也相应较大。

2 个答案:

答案 0 :(得分:1)

这是图像文件的结构。请注意,APP1标记后面有第二个SOI标记。

{图片开始}

{APP0 Marker   长度:16   版本:1.1   密度单位:(每英寸像素数)   X密度:72   Y密度:72   缩略图宽度:0   缩略图高度:0 }

{APP1 Marker   长度:7678 EXIF }

{图片开始}

{定义量化表   长度:67   表索引:0   表精度:0   表值:         8 6 6 7 6 5 8 7         7 7 9 9 8 10 12 20         13 12 11 11 12 25 18 19         15 20 29 26 31 30 29 26         28 28 32 36 46 39 32 34         44 35 28 28 40 55 41 44         48 49 52 52 52 31 39 57         61 56 50 60 46 51 52 50 }

{定义量化表   长度:67   表索引:1   表精度:0   表值:         9 9 9 12 11 12 24 13         13 24 50 33 28 33 50 50         50 50 50 50 50 50 50 50         50 50 50 50 50 50 50 50         50 50 50 50 50 50 50 50         50 50 50 50 50 50 50 50         50 50 50 50 50 50 50 50         50 50 50 50 50 50 50 50 }

{Start Of Frame   类型:基线(霍夫曼)   长度:17   精度:8   身高:360   宽度:480   组件数:3    组件1    水平频率:2    垂直频率:2    量化表:0    第2部分    水平频率:1    垂直频率:1    量化表:1    组件3    水平频率:1    垂直频率:1    量化表:1 }

{定义霍夫曼表   长度:28    表索引0    表类:DC    代码计数:0 1 5 1 1 1 0 0 0 0 0 0 0 0 0 0    代码值:3 1 2 4 5 6 0 7 8 }

{定义霍夫曼表   长度:65    表索引0    表类:AC    代码计数:0 2 1 3 2 4 4 4 4 4 5 3 3 4 3 0    代码值:1 2 3 0 4 11 12 21 5 31 41 51 13 22 61 71 6 32 81 91 14 42 a1 b1 23 52 c1 d1 7 15 33 62 e1 43 72 f0 24 92 f1 16 34 53 82 25 83 c2 }

{定义霍夫曼表   长度:26    表索引1    表类:DC    代码计数:0 3 1 1 1 1 0 0 0 0 0 0 0 0 0 0    代码值:0 1 2 3 4 5 6 }

{定义霍夫曼表   长度:45    表索引1    表类:AC    代码计数:0 2 2 1 4 1 4 2 2 2 1 5 0 0 0 0    代码值:0 1 2 11 3 4 12 21 31 41 13 22 51 61 32 71 5 14 23 91 f0 33 42 81 a1 b1 }

{开始扫描   长度:12   组件ID:1   交流熵表:0   直流熵表:0   组件ID:2   交流熵表:1   直流熵表:1   组件ID:3   交流熵表:1   直流熵表:1  光谱选择开始:0  光谱选择结束:63  成功逼近高:0  过度逼近低:0 }

{图像结束}

答案 1 :(得分:1)

我刚刚找到答案:

问题在于,当我更新TIFF标签中缩略图的大小时,我没有更新APP1长度。一旦更新,图像加载正确。

相关问题