如何在使用PIL修改文件后从文件上传表单上传文件到s3?

时间:2022-06-29 21:19:12

Here is the code stuff:

这是代码的东西:

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!'

and here is the html 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>

part of the problem is that It doesn't really give me an error log. You can see that the idea is that there are 2 checkboxes which can modify the image file. If the first one is checked, its "made transparent" and if the second one is checked, it changes the size.

部分问题是它并没有真正给我一个错误日志。您可以看到,有两个复选框可以修改图像文件。如果选中第一个,则“使其透明”,如果选中第二个,则会更改大小。

I think I am having issue with the type of the image object when it gets converted and modified, especially when it gets passed into this object: k.set_contents_from_filename("out.png")

我认为在转换和修改图像对象的类型时遇到问题,特别是当它被传递到这个对象时:k.set_contents_from_filename(“out.png”)

Any help here? This is the only output the server logs give me:

有什么帮助吗?这是服务器日志给我的唯一输出:

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 -

3 个解决方案

#1


2  

For proper debugging purposes you really need to look at a traceback. It will tell you what is wrong :-)!!

出于正确的调试目的,您确实需要查看回溯。它会告诉你出了什么问题:-) !!

Otherwise: I guess your general approach (first create an image file in the file system and then use boto for uploading it) is fine. However, for debugging purposes you could check what img.save('out.png',"PNG") leaves behind. You can, for investigation purposes, test if the file exists and otherwise raise an exception: assert os.path.isfile("out.png"). Also, you may want to print the file size using os.path.getsize("out.png"). As far as I remember working with boto, k.set_contents_from_filename("out.png") is the right thing to do then.

否则:我猜你的一般方法(首先在文件系统中创建一个图像文件,然后使用boto上传它)就可以了。但是,出于调试目的,您可以检查img.save('out.png',“PNG”)留下的内容。出于调查目的,您可以测试文件是否存在,否则引发异常:断言os.path.isfile(“out.png”)。此外,您可能希望使用os.path.getsize(“out.png”)打印文件大小。据我记得使用boto,k.set_contents_from_filename(“out.png”)是正确的做法。

That is, your order of doing things is right. Most probably there is an authentication/connection problem with S3, as Dmitry already pointed out. The details of this problem you will find by looking at a Traceback. A boto traceback will contain the error AWS error response.

也就是说,你的做事顺序是正确的。很可能是S3存在身份验证/连接问题,正如Dmitry已经指出的那样。通过查看Traceback可以找到此问题的详细信息。 boto回溯将包含错误AWS错误响应。

#2


1  

Please, use the trick below to see all raw http requests that boto sends to S3:

请使用以下技巧查看boto发送给S3的所有原始http请求:

import httplib
httplib.HTTPConnection.debuglevel = 1

also you could use this hint for the same:

您也可以使用此提示:

import logging
logging.basicConfig(filename="boto.log", level=logging.DEBUG)

Before testing functionality using web server please try to execute some test code from default python console:

在使用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')

After this please check file existence. In any case after all manipulations you should execute:

在此之后请检查文件是否存在。在任何情况下,你应该执行所有操作:

key.make_public()

Because by default all new bucket objects aren't public.

因为默认情况下所有新的桶对象都不是公共的。

#3


0  

Basically, I think the server error was formed when there was no "image" object in the request.files dictionary yet the request was sent. Therefore the server had no idea what to do. I fixed it by using request.files.get('image') instead of request.files['image']. Thus if there is no image, it returns None instead of giving a key error.

基本上,我认为服务器错误是在request.files字典中没有“image”对象但请求被发送时形成的。因此服务器不知道该怎么做。我使用request.files.get('image')而不是request.files ['image']来修复它。因此,如果没有图像,则返回None而不是给出键错误。

There was still no trackback, though I know everyone wanted one, because this kind of server error in flask DOES NOT seem to return a traceback. Simply a "Bad request" error message in the browser.

仍然没有引用,虽然我知道每个人都想要一个,因为烧瓶中的这种服务器错误似乎不会返回追溯。只是浏览器中的“错误请求”错误消息。

#1


2  

For proper debugging purposes you really need to look at a traceback. It will tell you what is wrong :-)!!

出于正确的调试目的,您确实需要查看回溯。它会告诉你出了什么问题:-) !!

Otherwise: I guess your general approach (first create an image file in the file system and then use boto for uploading it) is fine. However, for debugging purposes you could check what img.save('out.png',"PNG") leaves behind. You can, for investigation purposes, test if the file exists and otherwise raise an exception: assert os.path.isfile("out.png"). Also, you may want to print the file size using os.path.getsize("out.png"). As far as I remember working with boto, k.set_contents_from_filename("out.png") is the right thing to do then.

否则:我猜你的一般方法(首先在文件系统中创建一个图像文件,然后使用boto上传它)就可以了。但是,出于调试目的,您可以检查img.save('out.png',“PNG”)留下的内容。出于调查目的,您可以测试文件是否存在,否则引发异常:断言os.path.isfile(“out.png”)。此外,您可能希望使用os.path.getsize(“out.png”)打印文件大小。据我记得使用boto,k.set_contents_from_filename(“out.png”)是正确的做法。

That is, your order of doing things is right. Most probably there is an authentication/connection problem with S3, as Dmitry already pointed out. The details of this problem you will find by looking at a Traceback. A boto traceback will contain the error AWS error response.

也就是说,你的做事顺序是正确的。很可能是S3存在身份验证/连接问题,正如Dmitry已经指出的那样。通过查看Traceback可以找到此问题的详细信息。 boto回溯将包含错误AWS错误响应。

#2


1  

Please, use the trick below to see all raw http requests that boto sends to S3:

请使用以下技巧查看boto发送给S3的所有原始http请求:

import httplib
httplib.HTTPConnection.debuglevel = 1

also you could use this hint for the same:

您也可以使用此提示:

import logging
logging.basicConfig(filename="boto.log", level=logging.DEBUG)

Before testing functionality using web server please try to execute some test code from default python console:

在使用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')

After this please check file existence. In any case after all manipulations you should execute:

在此之后请检查文件是否存在。在任何情况下,你应该执行所有操作:

key.make_public()

Because by default all new bucket objects aren't public.

因为默认情况下所有新的桶对象都不是公共的。

#3


0  

Basically, I think the server error was formed when there was no "image" object in the request.files dictionary yet the request was sent. Therefore the server had no idea what to do. I fixed it by using request.files.get('image') instead of request.files['image']. Thus if there is no image, it returns None instead of giving a key error.

基本上,我认为服务器错误是在request.files字典中没有“image”对象但请求被发送时形成的。因此服务器不知道该怎么做。我使用request.files.get('image')而不是request.files ['image']来修复它。因此,如果没有图像,则返回None而不是给出键错误。

There was still no trackback, though I know everyone wanted one, because this kind of server error in flask DOES NOT seem to return a traceback. Simply a "Bad request" error message in the browser.

仍然没有引用,虽然我知道每个人都想要一个,因为烧瓶中的这种服务器错误似乎不会返回追溯。只是浏览器中的“错误请求”错误消息。