Python StringIO对象的MD5sum与保存文件的差异?

Python StringIO对象的MD5sum与保存文件的差异?,python,md5,python-imaging-library,cstring,Python,Md5,Python Imaging Library,Cstring,我有一段python代码,如下所示: def make_portrait(self, image_name): im = Image.open(str(image_name)) output = StringIO.StringIO() im.save(output, 'JPEG', quality=70) self.portrait_md5 = hashlib.md5(output.getvalue()).hexdigest() output.clos

我有一段python代码,如下所示:

def make_portrait(self, image_name):

    im = Image.open(str(image_name))

    output = StringIO.StringIO()
    im.save(output, 'JPEG', quality=70)
    self.portrait_md5 = hashlib.md5(output.getvalue()).hexdigest()
    output.close()
    self.portrait_asset = self.portrait_md5 + '.jpg'
    self.portrait_xml = '<net.rptools.maptool.model.Asset>\n  <id>\n    <id>' + self.portrait_md5 + \
                        '</id>\n  </id>\n  <name>' + self.name + \
                        '</name>\n  <extension>jpg</extension>\n  <image/>\n</net.rptools.maptool.model.Asset>\n'
    self.portrait = im
def make_肖像(自我、图像名称):
im=Image.open(str(Image\u name))
输出=StringIO.StringIO()
保存(输出“JPEG”,质量=70)
self.trait_md5=hashlib.md5(output.getvalue()).hexdigest()
output.close()
self.grait_asset=self.grait_md5+'.jpg'
self.trait_xml='\n\n'+self.trait_md5+\
'\n\n'+self.name+\
“\n jpg\n\n\n”
自画像
它的工作是读取给定的图像文件,以70%的质量将图像转换为JPG格式,然后为转换后的数据计算MD5校验和。在程序的其他地方,转换后的图像数据被写入磁盘上的实际文件,附带一个包含元数据的文件(如MD5 sum)

代码运行正常,但校验和与最终输出不匹配。假设我给它一个图像,它进行转换,得到“ce5d1126ba52ba1618c402a13bee1c0c”作为校验和。如果我稍后检查保存到磁盘的最后一个文件,md5sum说它的校验和是“bb5ae2fdfea6294267b7ffdc226e21fa”

这会导致问题,因为本应使用此代码生成的文件的程序会检查实际文件的MD5和,并将其与元数据中报告的MD5和进行比较。如果两者不匹配,它就会窒息

我对Python非常陌生。如何使其生成一个MD5和,该和将保存到磁盘的映像文件的和匹配


如果需要,很乐意提供更多详细信息。

我假设这与PIL编写文件有关,因为来自
StringIO()
的md5和文件如下所示:

>>> import StringIO
>>> import string
>>> import random
>>> import hashlib
>>> import subprocess
>>>
>>> sample = StringIO.StringIO()
>>> data = "".join([random.choice(string.lowercase) for _ in range(10000)])
>>> sample.write(data)
>>> sample.seek(0)
>>> md5 = hashlib.md5()
>>> md5.update(sample.read())
>>> md5.hexdigest()
'1b0d867b8e5aa66de816285076b7d457'
>>> sample.seek(0)
>>> with open("as_file.txt", "w") as f:
...     f.write(sample.read())
...
>>> subprocess.call("md5 as_file.txt".split())
MD5 (as_file.txt) = 1b0d867b8e5aa66de816285076b7d457
在生成散列之前,可以尝试查找输出的开头

im.save(output, "JPEG", quality=70)
output.seek(0)
self.portrait_md5 = hashlib.md5(output.getvalue()).hexdigest()  
编辑 这正是我所期望的,本质上与您的代码相同。您在哪里将文件写入磁盘

from PIL import Image
import StringIO
import hashlib
import subprocess

im = Image.open("foo.png")
data = StringIO.StringIO()
im.save(data, "JPEG", quality=70)
md5 = hashlib.md5(data.getvalue()).hexdigest()
with open("foo.jpg", "w") as f:
    im.save(f, "JPEG", quality=70)

print md5
print subprocess.call("md5 foo.jpg".split())
输出
要写入文件的代码在哪里?你把
输出
扔掉了。真的吗?我不确定。我认为这只是将数据保存为self的一个属性,以便稍后由其他地方编写。我正在修改一个现有的程序(),而不是从头开始,因此有相当多的代码的函数我不清楚。然后,你不能确定你保存的文件是否与你计算的md5和相同。可能JPEG包含一个时间戳,如果再次保存,会给出另一个md5。请参见下面答案下面的我的评论-这不是一个时间戳,而是对PNG数据的二次转换,我没有进行调整,因此我最终得到了一个自称是JPG但实际上包含PNG数据的文件。对不起,天啊。我只是找到了将文件保存到磁盘的代码。在询问之前我应该这样做-它将输出从JPG转换为PNG,因此最终结果与最初制作肖像时的数据不同。facepalm很抱歉在未正确完成调试的情况下询问:-/
e5954ce7fb4d22dfac63372bfc948903
MD5 (foo.jpg) = e5954ce7fb4d22dfac63372bfc948903