【问题标题】:Open Image From Online, Save To Server Flask从在线打开图像,保存到服务器烧瓶
【发布时间】:2014-09-18 13:37:50
【问题描述】:

我正在使用 Flask 从 URL 打开图像。

file = cStringIO.StringIO(urllib.urlopen(URL).read())
img = Image.open(file)

然后我想拍摄图像并将其保存到我的网站。当我这样做时,我得到

Traceback (most recent call last):
  File "/Library/Python/2.7/site-packages/flask/app.py", line 1836, in __call__
    return self.wsgi_app(environ, start_response)
  File "/Library/Python/2.7/site-packages/flask/app.py", line 1820, in wsgi_app
    response = self.make_response(self.handle_exception(e))
  File "/Library/Python/2.7/site-packages/flask/app.py", line 1403, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/Library/Python/2.7/site-packages/flask/app.py", line 1817, in wsgi_app
    response = self.full_dispatch_request()
  File "/Library/Python/2.7/site-packages/flask/app.py", line 1477, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/Library/Python/2.7/site-packages/flask/app.py", line 1381, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/Library/Python/2.7/site-packages/flask/app.py", line 1475, in full_dispatch_request
    rv = self.dispatch_request()
  File "/Library/Python/2.7/site-packages/flask/app.py", line 1461, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/Users/User/Desktop/Flask/fl.py", line 37, in index
    img.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
  File "/Library/Python/2.7/site-packages/PIL/Image.py", line 1648, in save
    raise KeyError(ext)  # unknown extension
KeyError: ''

这是要保存的代码:

filename = secure_filename(img.filename)
img.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
print url_for('uploaded_file', filename=filename)

@app.route('/uploads/<filename>')
def uploaded_file(filename):
    return send_from_directory(app.config['UPLOAD_FOLDER'], filename)

为什么会这样?我该如何解决这个问题?

【问题讨论】:

  • edit您的问题并包含回溯的全文
  • @MattDMo 好的,刚刚更新。

标签: python file url flask stringio


【解决方案1】:

当从一个对象没有文件名保存图像时,比如StringIO对象,你需要告诉PIL它是什么类型的图像:

img.save(os.path.join(app.config['UPLOAD_FOLDER'], filename), format='PNG')

这里我声明格式是 PNG,但您需要从响应中反省 Content-Type 标头并查看其中的类型。根据标头将内容类型映射到适当的 PIL 格式。

您还需要想出一个更好的文件名; img.filename 是一个空字符串,因为您从未给 img.open() 一个文件名。例如,使用URL 的最后一个组件;大概会有一个文件名:

formats = {
    'image/jpeg': 'JPEG',
    'image/png': 'PNG',
    'image/gif': 'GIF'
}

response = urllib.urlopen(URL)
image_type = response.info().get('Content-Type')
try:
    format = formats[image_type]
except KeyError:
    raise ValueError('Not a supported image format')

file = cStringIO.StringIO(response.read())
img = Image.open(file)

# ...

filename = secure_filename(URL.rpartition('/')[-1])
img.save(os.path.join(app.config['UPLOAD_FOLDER'], filename), format=format)

【讨论】:

  • 太棒了。但现在我收到一个错误OError: [Errno 21] Is a directory: "uploads/"。这是什么意思?
  • @user3822146: img.filenameempty,因为您从未提供过文件名。所以os.path.join(app.config['UPLOAD_FOLDER'], filename) 结果最终成为目录名称。我会更新的。
  • 有道理。非常感谢。
猜你喜欢
  • 2018-06-05
  • 2023-03-14
  • 2014-06-04
  • 2013-07-08
  • 2014-07-02
  • 1970-01-01
  • 1970-01-01
  • 2020-09-20
  • 1970-01-01
相关资源
最近更新 更多