【问题标题】:Can't get file extension of temp image file grabbed using Image.open(requests.get())无法获取使用 Image.open(requests.get()) 抓取的临时图像文件的文件扩展名
【发布时间】:2020-02-16 07:25:43
【问题描述】:

这是我在这里提出的第一个问题,请原谅没有经验:-)

我有以下文件用于保存图像,然后返回文件路径/URL:

import os, requests
import secrets
from PIL import Image
from flask import url_for, current_app

def save_picture(google_url):
    random_hex = secrets.token_hex(8)
    i = Image.open(requests.get(google_url, stream=True).raw)
    f_ext = (i.format).lower()
    picture_fn = random_hex + f_ext
    picture_path = os.path.join(current_app.root_path, 'static/experience_images', picture_fn)

    output_size = (600, 600)
    i.thumbnail(output_size)
    i.show()
    i.save(picture_path)

    return picture_fn

我收到以下错误

raise ValueError("未知文件扩展名:{}".format(ext))

google_url 参数是一个 API URL,用于从 Google Places API 获取图像。下面当我调用i.show() 时,图像会打开,因此我知道图像正在通过,并且我可以看到在大多数情况下(尽管不一定全部)它正在返回 PNG 或 JPEG 文件。我认为问题在于我实际上没有从i 获得任何文件名,我假设这是因为它是一个临时文件。

任何帮助将不胜感激,我是 Python 的新手。

【问题讨论】:

标签: python flask python-imaging-library google-places-api


【解决方案1】:

这是一个猜测,因为我没有 Google Places 帐户,但是:通常,HTTP 响应将声明它们包含在内容类型标头中的数据类型。

标头的值可能如下所示

"image/jpeg"

或者这个

"image/jpeg; charset=UTF-8"

标准库中的mimetypes 模块包含从该标头值派生扩展的工具。所以你可以这样做:

import mimetypes
import requests

def save_picture(google_url):

    response = requests.get(google_url, stream=True)
    content_type = response.headers['content-type']    # 'image/jpeg; charset=UTF-8'
    mimetype, _, _ = content_type.partition(';')       # 'image/jpeg'
    f_ext = mimetypes.guess_extension(mimetype)        # '.jpg'

    random_hex = secrets.token_hex(8)
    i = Image.open(response.raw)
    picture_fn = random_hex + f_ext
    picture_path = os.path.join(current_app.root_path, 'static/experience_images', picture_fn)

    output_size = (600, 600)
    i.thumbnail(output_size)
    i.show()
    i.save(picture_path)

    return picture_fn

【讨论】:

    【解决方案2】:

    根据 PIL documentation,格式字符串在某些情况下可能为 None。 (如果您发布一个完整的示例,我可以在笔记本中运行并使用它会很有帮助,如果我使用随机图像 URL,它基本上可以工作。)

    提供默认格式(.jpg?)可能就足够了 f_ext = (i.format).lower() if i.format 不是 None else '.jpg' 对于那些情况,但在这里猜测一下......

    【讨论】:

      【解决方案3】:

      好的,所以我想出了一个解决方案。如果其他人有更好的解决方案,我会全力以赴。

      基本上,问题似乎是当我使用i.format 获取文件扩展名类型时,它不包含“。”在“.PNG”中。所以文件名类似于“filenamepng”而不是“filename.png”。

      所以现在在获得文件扩展名之后

      f_ext = i.format
      

      我用

      创建文件名
      picture_fn = random_hex + '.' + f_ext
      

      现在似乎一切正常 :-) 感谢 DrD,我在整理示例代码 sn-p 供您试用时发现了这一点。

      现在完成的代码如下:

      import os, requests
      import secrets
      from PIL import Image
      from flask import url_for, current_app
      
      def save_picture(google_url):
          random_hex = secrets.token_hex(8)
          i = Image.open(requests.get(google_url, stream=True).raw)
          f_ext = (i.format).lower()
          picture_fn = random_hex + '.' + f_ext
          picture_path = os.path.join(current_app.root_path, 'static/experience_images', picture_fn)
      
          output_size = (600, 600)
          i.thumbnail(output_size)
          i.save(picture_path)
      
          return picture_fn
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-06-02
        • 1970-01-01
        相关资源
        最近更新 更多