Python 如何使用图像哈希作为下载图像的文件名?

Python 如何使用图像哈希作为下载图像的文件名?,python,python-requests,python-imaging-library,imagehash,Python,Python Requests,Python Imaging Library,Imagehash,在Python中,我想将图像保存到文件中。文件名应该是哈希,由imagehash.average\u hash()生成。使用ls-l我可以看到文件,但它们是空的: -rw-r--r--1 lorem lorem 0 8 Sep 16:20 c4c0bcb49890bcfc.jpg -rwxr-xr-x 1 lorem lorem 837 8 Sep 16:19 minimal.py 代码: 导入请求 从PIL导入图像 导入imagehash 进口舒蒂尔 def safe_to_文件(url):

在Python中,我想将图像保存到文件中。文件名应该是哈希,由
imagehash.average\u hash()
生成。使用
ls-l
我可以看到文件,但它们是空的:

-rw-r--r--1 lorem lorem 0 8 Sep 16:20 c4c0bcb49890bcfc.jpg
-rwxr-xr-x 1 lorem lorem 837 8 Sep 16:19 minimal.py
代码:

导入请求
从PIL导入图像
导入imagehash
进口舒蒂尔
def safe_to_文件(url):
标题={
“用户代理”:“Mozilla/5.0(Macintosh;英特尔Mac OS X 10_11_6)AppleWebKit/537.36(KHTML,如Gecko)Chrome/53.0.2785.143 Safari/537.36”
图像\u哈希=“”
r=requests.get(url,headers=headers,timeout=10,stream=True)
尝试:
如果r.status_code==200:
image_hash=str(imagehash.average_hash(image.open(r.raw)))+'.jpg'
打印(图像\u散列)
将open(image_hash,'wb')作为f:
r、 raw.decode_content=True
shutil.copyfileobj(r.raw,f)
例外情况除外,例如:
打印(str(ex))
最后:
返回图像散列
#随机jpg图片
url='1〕https://cdn.ebaumsworld.com/mediaFiles/picture/1035099/85708057.jpg'
安全到文件(url)

我希望图像不是空的。我做错了什么?

正如我所怀疑的那样,创建
PIL.Image
对象会消耗并下载url中的所有图像数据,因此
shutil.copyfileobj()
没有什么可消耗的

下面的代码似乎通过使用所需的基于哈希的文件名显式保存
图像
对象来避免该问题。我添加了注释,以说明重大变化

import imagehash
from PIL import Image
import requests
#import shutil


def safe_to_file(url):
    headers = {'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) '
                             'AppleWebKit/537.36 (KHTML, like Gecko) '
                             'Chrome/53.0.2785.143 Safari/537.36'}
    image_hash = ''
    r = requests.get(url, headers=headers, timeout=10, stream=True)
    try:
        if r.status_code == 200:
            img = Image.open(r.raw)  # ADDED
            image_hash = str(imagehash.average_hash(img)) + '.jpg'  # CHANGED.
            print('saving image:', image_hash)
            img.save(image_hash)  # ADDED
#            with open(image_hash, 'wb') as f:  # REMOVED
#                r.raw.decode_content = True    # REMOVED
#                shutil.copyfileobj(r.raw, f)   # REMOVED
    except Exception as ex:
        print(str(ex))
    finally:
        return image_hash

# Random jpg picture
url = 'https://cdn.ebaumsworld.com/mediaFiles/picture/1035099/85708057.jpg'
safe_to_file(url)
c4c0bcb49890bcfc.jpg它创建的文件:


如果没有打印任何异常,我会假设这是因为
r.raw
不是
copyfileobj()
所需的“类文件对象”(如果是空的话,则为空)。也可能是
Image.open(r.raw)
消耗了所有图像数据,因此没有任何内容可供
copyfileobj()
读取。没有,也很难说…@martineau:当然,就是这样:任何图像分析都必须至少读取部分流,然后才能使用
copyfileobj
。抱歉,刚才添加了一个最小可复制的示例@马提诺