简体   繁体   English

有什么办法可以使用python从zip内部提供用户上传的图片?

[英]Any way to serve user uploaded images from inside zips with python?

So I am making a site where users can upload galleries of images(usually dozens of images per gallery), and they should be compressed into a zip file(by the user) before upload. 因此,我正在建立一个站点,用户可以在其中上传图像库(每个画廊通常有几十个图像),并且在上传之前应将其压缩为zip文件(由用户)。 I notice how (at least on Linux) I can click on a compressed folder and view the images inside it without extracting it. 我注意到(至少在Linux上)如何单击压缩的文件夹并查看其中的图像而不解压缩它。 Is it possible to serve images from inside zipfiles with python like this, as decompressing is CPU intensive? 像这样,解压缩会占用大量CPU资源,是否可以使用python这样从zipfile中提供图像?

You can read the contents of zip files using Python using the zipfile module which would allow you to decompress and serve files on the fly. 您可以使用zipfile模块使用Python读取zip文件的内容,该模块可让您即时解压缩并提供文件。 Whether this is actually what you want to do is another question, since, as you mention, decompressing the file will be more CPU intensive than just serving the file directly from the file system. 这是否实际上是您要执行的另一个问题,因为正如您提到的,解压缩文件比直接从文件系统提供文件要占用更多的CPU资源。

I am guessing that users are uploading files in a zip so that they can upload multiple images at once. 我猜想用户正在以zip格式上传文件,以便他们可以一次上传多个图像。 In this case it might be better to just decompress the zip file after it has been uploaded. 在这种情况下,最好将zip文件上传后再解压缩。 You can then decompress the file into a location from which you can serve the files as static files using a webserver. 然后,您可以将文件解压缩到一个位置,您可以使用Web服务器从该位置将文件作为静态文件提供。

Sample application 样品申请

The following code shows a sample Flask application that demonstrates how to serve up images directly from zip files. 以下代码显示了Flask示例应用程序,该应用程序演示了如何直接从zip文件提供图像。 It cuts a lot of corners so don't use this directly in a production app! 它开了很多角,所以不要在生产应用程序中直接使用它!

To test the app, install flask (probably into a virtualenv) and run the code: 要测试该应用程序,请安装flask(可能安装到virtualenv中)并运行代码:

virtualenv env
env/bin/pip install flask
env/bin/python sample_flask_application.py

Make sure that you have a directory called galleries at the same level as the flask application and that you have a few .zip files containing jpegs in the galleries directory. 确保在与flask应用程序相同的目录下具有一个名为galleries的目录,并且在galleries目录中具有几个包含jpegs的.zip文件。

import os
import zipfile

from flask import Flask
from flask import Response

app = Flask(__name__)

gallery_path = 'galleries'

@app.route('/')
def index():
    html = '<a href="{0}">{0}</a>'
    gallery_zips = os.listdir(gallery_path)
    gallery_names = [os.path.splitext(zfile)[0] for zfile in gallery_zips]
    galleries = [html.format(gallery) for gallery in gallery_names]
    return '<br>'.join(galleries)


@app.route('/<gallery>')
def gallery(gallery):
    zip_path = os.path.join(gallery_path, gallery + '.zip')
    html = '<a href="{0}/{1}">{1}</a>'
    with zipfile.ZipFile(zip_path, 'r') as zfp:
        images = zfp.namelist()
        image_list = [html.format(gallery, image) for image in images]
        return '<br>'.join(image_list)


@app.route('/<gallery>/<path:image>')
def image(gallery, image):
    zip_path = os.path.join(gallery_path, gallery + '.zip')
    with zipfile.ZipFile(zip_path) as zfp:
        image_fp = zfp.open(image, 'r')
        return Response(image_fp, mimetype='image/jpeg')

if __name__ == '__main__':
    app.run(debug=True)

Possible improvements 可能的改进

  • Set expires and other things that might help cache the image files in the image function 设置过期和其他的东西,可能有助于在缓存中的图像文件image功能
  • Use a cache of decompressed images 使用解压缩图像的缓存
    • When serving an image, first check if the image is in the cache location 提供图片时,请先检查图片是否在缓存位置
    • If not, decompress it to the cache location 如果不是,则将其解压缩到缓存位置
    • Then use send_file to serve the file to client 然后使用send_file将文件提供给客户端
  • Cache the list of files contained in each zipfile 缓存每个zip文件中包含的文件列表
  • Generate a 404 if the image is not actually in the zip file! 如果图像实际上不在zip文件中,则生成404!

Conclusions 结论

The above code will work, especially if you are on a low traffic site. 上面的代码将起作用,尤其是在人流少的站点上时。 If a few people look at a few images a day, then you'll be fine. 如果有人每天看几张图像,那您会没事的。 If you optimise the above code a bit (expires, caching) then you can deal with more traffic still. 如果您稍微优化上述代码(过期,缓存),则仍可以处理更多流量。 However if you want the best performance then you are looking at something that decompresses the zip files when they are uploaded and serves them up using a webserver directly ( nginx , apache , or whatever you are using). 但是,如果要获得最佳性能,则需要寻找一种能够在zip文件上传后对其进行解压缩并直接使用网络服务器( nginxapache或使用的任何文件)对其进行压缩的工具。 When you get thousands of visitors from all over the world then you can start looking at content delivery networks as well. 当您获得来自世界各地的成千上万的访客时,您也可以开始查看内容交付网络

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM