如何在使用 PIL 修改文件上传表单后将文件上传到 s3?
How to upload a file to s3 from a file upload form after modifying it with PIL?
代码如下:
app.config['DEBUG']= True
if request.method == 'POST' and request.form['file_submit']:
print request.form
print request.files['image']
if request.files['image']:
print 'foshhh'
image_file = request.files['image']
img = PIL.Image.open(image_file.stream)
print img
if request.form['make_transparent']:
threshold=100
print 'changin sizesd'
dist=5
# np.asarray(img) is read only. Wrap it in np.array to make it modifiable.
arr=np.array(np.asarray(img))
r,g,b,a=np.rollaxis(arr,axis=-1)
mask=((r>threshold)
& (g>threshold)
& (b>threshold)
& (np.abs(r-g)<dist)
& (np.abs(r-b)<dist)
& (np.abs(g-b)<dist)
)
arr[mask,3]=0
img=Image.fromarray(arr,mode='RGBA')
if request.form['change_size']:
img = Image.open('out.png')
img.thumbnail(size,Image.ANTIALIAS)
img.save('out.png',"PNG")
img.save('out.png',"PNG")
print os.path.getsize("out.png") #from answer
assert os.path.isfile("out.png") #from answer
conn = S3Connection(AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY)
b = conn.get_bucket('snappie.watermarks')
k = Key(b)
k.key = "test.png"
k.set_metadata('Content-Type', 'image/png')
k.set_contents_from_filename("out.png")
print "got file"
return redirect("https://s3.amazonaws.com/snappie.watermarks/"+filename)
else:
print 'please upload a file to submit the form!'
这里是 html 表格:
<form method="POST" enctype="multipart/form-data" name="file_submit">
<label>Choose png here.<input type="file" name="image"></label>
<input type="hidden" name="file_submit" value="yes">
Change size?<input type="checkbox" name="change_size" value="yes"/>
Make Background Transparent?<input type="checkbox" name="make_transparent" value="yes"\><br><br>
<input type="submit" value="submit">
</form>
部分问题是它并没有真正给我错误日志。你可以看到这个想法是有 2 个复选框可以修改图像文件。如果选中第一个,它的 "made transparent" 如果选中第二个,它会更改大小。
我想我在转换和修改图像对象时遇到了问题,尤其是当它被传递到这个对象时:k.set_contents_from_filename("out.png")
这里有什么帮助吗?这是服务器日志给我的唯一输出:
GET
127.0.0.1 - - [18/Jan/2015 15:42:26] "GET / HTTP/1.1" 200 -
POST
ImmutableMultiDict([('file_submit', u'yes')])
<FileStorage: u'birnam_wood.jpg' ('image/jpeg')>
foshhh
<PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=100x100 at 0x7FDDF4CA6C68>
127.0.0.1 - - [18/Jan/2015 15:42:32] "POST / HTTP/1.1" 400 -
请使用以下技巧查看 boto 发送到 S3 的所有原始 http 请求:
import httplib
httplib.HTTPConnection.debuglevel = 1
您也可以使用此提示:
import logging
logging.basicConfig(filename="boto.log", level=logging.DEBUG)
在使用 Web 服务器测试功能之前,请尝试从默认 python 控制台执行一些测试代码:
import httplib
httplib.HTTPConnection.debuglevel = 1
conn = boto.connect_s3(aws_access_key_id='some', aws_secret_access_key='some')
b = conn.get_bucket('snappie.watermarks')
k = Key(b)
k.key = "test.txt"
k.set_contents_from_string('12345')
之后请检查文件是否存在。在任何情况下,在所有操作之后你应该执行:
key.make_public()
因为默认情况下所有新的存储桶对象都不是 public。
为了正确的调试目的,您确实需要查看回溯。它会告诉你哪里出了问题:-)!!
否则:我想你的一般做法(先在文件系统中创建一个图像文件,然后使用boto上传)是可以的。但是,出于调试目的,您可以检查 img.save('out.png',"PNG")
留下的内容。出于调查目的,您可以测试文件是否存在,否则会引发异常:assert os.path.isfile("out.png")
。此外,您可能希望使用 os.path.getsize("out.png")
打印文件大小。据我记得使用 boto 时,k.set_contents_from_filename("out.png")
是正确的做法。
也就是说,你的做事顺序是对的。正如 Dmitry 已经指出的那样,S3 很可能存在 authentication/connection 问题。您将通过查看 Traceback 找到此问题的详细信息。 boto 回溯将包含错误 AWS 错误响应。
基本上,我认为服务器错误是在 request.files 字典中没有 "image" 对象但请求已发送时形成的。因此服务器不知道该怎么做。我通过使用 request.files.get('image') 而不是 request.files['image'] 来修复它。因此,如果没有图像,它 returns None 而不是给出一个关键错误。
仍然没有 trackback,虽然我知道每个人都想要一个,因为 flask 中的这种服务器错误似乎 return 不是 traceback。只是浏览器中的 "Bad request" 错误消息。
代码如下:
app.config['DEBUG']= True
if request.method == 'POST' and request.form['file_submit']:
print request.form
print request.files['image']
if request.files['image']:
print 'foshhh'
image_file = request.files['image']
img = PIL.Image.open(image_file.stream)
print img
if request.form['make_transparent']:
threshold=100
print 'changin sizesd'
dist=5
# np.asarray(img) is read only. Wrap it in np.array to make it modifiable.
arr=np.array(np.asarray(img))
r,g,b,a=np.rollaxis(arr,axis=-1)
mask=((r>threshold)
& (g>threshold)
& (b>threshold)
& (np.abs(r-g)<dist)
& (np.abs(r-b)<dist)
& (np.abs(g-b)<dist)
)
arr[mask,3]=0
img=Image.fromarray(arr,mode='RGBA')
if request.form['change_size']:
img = Image.open('out.png')
img.thumbnail(size,Image.ANTIALIAS)
img.save('out.png',"PNG")
img.save('out.png',"PNG")
print os.path.getsize("out.png") #from answer
assert os.path.isfile("out.png") #from answer
conn = S3Connection(AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY)
b = conn.get_bucket('snappie.watermarks')
k = Key(b)
k.key = "test.png"
k.set_metadata('Content-Type', 'image/png')
k.set_contents_from_filename("out.png")
print "got file"
return redirect("https://s3.amazonaws.com/snappie.watermarks/"+filename)
else:
print 'please upload a file to submit the form!'
这里是 html 表格:
<form method="POST" enctype="multipart/form-data" name="file_submit">
<label>Choose png here.<input type="file" name="image"></label>
<input type="hidden" name="file_submit" value="yes">
Change size?<input type="checkbox" name="change_size" value="yes"/>
Make Background Transparent?<input type="checkbox" name="make_transparent" value="yes"\><br><br>
<input type="submit" value="submit">
</form>
部分问题是它并没有真正给我错误日志。你可以看到这个想法是有 2 个复选框可以修改图像文件。如果选中第一个,它的 "made transparent" 如果选中第二个,它会更改大小。
我想我在转换和修改图像对象时遇到了问题,尤其是当它被传递到这个对象时:k.set_contents_from_filename("out.png")
这里有什么帮助吗?这是服务器日志给我的唯一输出:
GET
127.0.0.1 - - [18/Jan/2015 15:42:26] "GET / HTTP/1.1" 200 -
POST
ImmutableMultiDict([('file_submit', u'yes')])
<FileStorage: u'birnam_wood.jpg' ('image/jpeg')>
foshhh
<PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=100x100 at 0x7FDDF4CA6C68>
127.0.0.1 - - [18/Jan/2015 15:42:32] "POST / HTTP/1.1" 400 -
请使用以下技巧查看 boto 发送到 S3 的所有原始 http 请求:
import httplib
httplib.HTTPConnection.debuglevel = 1
您也可以使用此提示:
import logging
logging.basicConfig(filename="boto.log", level=logging.DEBUG)
在使用 Web 服务器测试功能之前,请尝试从默认 python 控制台执行一些测试代码:
import httplib
httplib.HTTPConnection.debuglevel = 1
conn = boto.connect_s3(aws_access_key_id='some', aws_secret_access_key='some')
b = conn.get_bucket('snappie.watermarks')
k = Key(b)
k.key = "test.txt"
k.set_contents_from_string('12345')
之后请检查文件是否存在。在任何情况下,在所有操作之后你应该执行:
key.make_public()
因为默认情况下所有新的存储桶对象都不是 public。
为了正确的调试目的,您确实需要查看回溯。它会告诉你哪里出了问题:-)!!
否则:我想你的一般做法(先在文件系统中创建一个图像文件,然后使用boto上传)是可以的。但是,出于调试目的,您可以检查 img.save('out.png',"PNG")
留下的内容。出于调查目的,您可以测试文件是否存在,否则会引发异常:assert os.path.isfile("out.png")
。此外,您可能希望使用 os.path.getsize("out.png")
打印文件大小。据我记得使用 boto 时,k.set_contents_from_filename("out.png")
是正确的做法。
也就是说,你的做事顺序是对的。正如 Dmitry 已经指出的那样,S3 很可能存在 authentication/connection 问题。您将通过查看 Traceback 找到此问题的详细信息。 boto 回溯将包含错误 AWS 错误响应。
基本上,我认为服务器错误是在 request.files 字典中没有 "image" 对象但请求已发送时形成的。因此服务器不知道该怎么做。我通过使用 request.files.get('image') 而不是 request.files['image'] 来修复它。因此,如果没有图像,它 returns None 而不是给出一个关键错误。
仍然没有 trackback,虽然我知道每个人都想要一个,因为 flask 中的这种服务器错误似乎 return 不是 traceback。只是浏览器中的 "Bad request" 错误消息。