有没有办法用python从拉链内部提供用户上传的图像?

时间:2014-03-29 19:23:16

标签: python zip compression

因此,我建立了一个网站,用户可以上传图片库(每个图库通常有数十个图片),在上传之前应该将它们压缩成一个zip文件(由用户提供)。我注意到(至少在Linux上)我可以点击压缩文件夹并查看其中的图像而不提取它。是否可以像这样使用python从zip文件内部提供图像,因为解压缩是CPU密集型的?

1 个答案:

答案 0 :(得分:3)

您可以使用zipfile模块使用Python阅读zip文件的内容,这样您就可以动态解压缩和提供文件。这是否真的是你想要做的另一个问题,因为正如你所提到的,解压缩文件将比仅直接从文件系统提供文件更加CPU密集。

我猜测用户正在以zip格式上传文件,以便他们可以一次上传多张图片。在这种情况下,在上传zip文件后解压缩可能会更好。然后,您可以将文件解压缩到一个位置,您可以使用Web服务器将文件作为静态文件提供。

示例应用程序

以下代码显示了一个示例Flask应用程序,该应用程序演示了如何直接从zip文件提供图像。它削减了很多角落,所以不要在生产应用程序中直接使用它!

要测试应用程序,请安装flask(可能是virtualenv)并运行代码:

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

确保您有一个名为galleries的目录与flask应用程序处于同一级别,并且您在.zip目录中有一些包含jpeg的galleries个文件。

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)

可能的改进

  • 设置过期和其他可能有助于缓存image功能
  • 中的图像文件的内容
  • 使用解压缩图像的缓存
    • 提供图像时,首先检查图像是否在缓存位置
    • 如果没有,请将其解压缩到缓存位置
    • 然后使用send_file将文件提供给客户
  • 缓存每个zipfile中包含的文件列表
  • 如果图像实际上不在zip文件中,则生成404!

结论

以上代码可以使用,特别是如果您在流量较低的网站上。如果有几个人每天看一些图像,那么你会没事的。如果您稍微优化上述代码(过期,缓存),那么您仍然可以处理更多流量。但是,如果您想获得最佳性能,那么您正在查看在上传时解压缩zip文件的内容,并直接使用网络服务器(nginxapache或您正在使用的任何内容)提供这些文件。当您收到来自世界各地的数千名访客时,您也可以开始查看content delivery networks