Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/amazon-s3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Flask web服务器在处理和上载到S3时会损坏图像_Python_Amazon S3_Flask_Io_Python Imaging Library - Fatal编程技术网

Python Flask web服务器在处理和上载到S3时会损坏图像

Python Flask web服务器在处理和上载到S3时会损坏图像,python,amazon-s3,flask,io,python-imaging-library,Python,Amazon S3,Flask,Io,Python Imaging Library,我正在尝试将来自Flask Web服务器的图像存储在S3上。服务器接收图像并对其进行处理以创建两个副本(压缩+缩略图),然后上载所有三个副本 成像的两个进程接收良好,但原始进程已损坏。代码不会抛出任何错误。 所有这些都使用Python 3.6、Flask 1.0.2和Boto3 1.9.88 以下是上传页面代码的摘录: form = UploadForm() if form.validate_on_submit(): photo = form.photo.data name,

我正在尝试将来自Flask Web服务器的图像存储在S3上。服务器接收图像并对其进行处理以创建两个副本(压缩+缩略图),然后上载所有三个副本

成像的两个进程接收良好,但原始进程已损坏。代码不会抛出任何错误。

所有这些都使用Python 3.6、Flask 1.0.2和Boto3 1.9.88

以下是上传页面代码的摘录:

form = UploadForm()
if form.validate_on_submit():
    photo = form.photo.data

    name, ext = os.path.splitext(form.photo.data.filename)

    photo_comp, photo_thum = get_compressions(photo, 'JPEG')

    pic_set = {}

    pic_set['original'] = photo
    pic_set['compressed'] = photo_comp
    pic_set['thumbs'] = photo_thum

    for pic in pic_set:
        output = upload_to_s3(file=pic_set[pic], username=current_user.username, \
                         filetype = pic, \
                         bucket_name = current_app.config['S3_BUCKET'])
函数“get_compressions()”将生成文件的缩小大小.jpeg和缩略图(抱歉缩进格式出现错误):

最后,“upload_to_s3()”函数在AWS s3上是一个相当简单的保存:

def upload_to_s3(file, username, filetype, bucket_name, acl= os.environ.get('AWS_DEFAULT_ACL')):
s3.upload_fileobj(
    Fileobj=file
    , Bucket=bucket_name
    , Key = "{x}/{y}/{z}".format(x=username,y=filetype,z=file.filename)
    , ExtraArgs = {'ContentType': file.content_type}
)
print('Upload successful: ', file.filename)
return file.filename
我相信压缩会影响原始文件对象的上传-当PIL image.save()返回一个新对象时,压缩行为似乎会以某种方式影响原始对象

在尝试研究这一点时,我注意到Flask作为标准是多线程的,Python GIL不适用于I/O操作或图像处理——不确定这是否相关

我试图解决的两个选项是:

  • 更改代码顺序执行,使其变为原始上载-压缩-压缩上载,但这会导致错误
    'ValueError:I/O操作关闭的文件'

  • 在使用get_compressions()之前,使用copy.deepcopy()创建一个新对象,但这会导致
    “类型错误:无法序列化”\u io.BufferedRandom“对象”


  • 我真的不知道如何继续!可能会上载原始文件,然后在后台使用服务器进程压缩(基于上载的文件),但这会给希望立即检索压缩版本以加载页面的客户端带来问题。

    获取压缩功能中,您正在读取原始的
    文件
    ,它是一个文件存储对象,因此您的文件指针结束于文件的末尾,并将一个零字节文件写入S3。因此,您需要
    seek
    返回到文件的开头,就像您对压缩版本所做的那样:

    file.seek(0)                                                                
    temp_thumb.seek(0)                                                          
    temp_compress.seek(0)
    

    已经修好了,谢谢。这么简单的修复!
    file.seek(0)                                                                
    temp_thumb.seek(0)                                                          
    temp_compress.seek(0)