从在线打开图像,保存到服务器刻录机

时间:2014-07-27 01:26:09

标签: python file url flask stringio

我正在使用Flask从网址打开图片。

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)

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

1 个答案:

答案 0 :(得分:3)

从没有文件名的对象保存图像时,如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)