问题描述
我正在尝试在内存中创建一个PIL图像对象列表的zip文件。
import io
from PIL import Image
def get_images(path):
'''This returns a list of PIL images'''
pass
def file_process_im_memory():
images = get_images('mypath')
file_object = io.BytesIO()
file_object2 = io.BytesIO()
images[0].save(file_object,'PNG')
images[1].save(file_object2,'PNG')
file_object.seek(0)
file_object2.seek(0)
图像写在内存中,现在我想从内存中的图像文件创建一个zip文件,我在下面尝试过,但是没有用。
zip_file = ZipFile(zip_file_bytes_io,'w')
for image in images:
file_object = io.BytesIO()
image.save(file_object,'PNG')
file_object.seek(0)
zip_file.writestr(file_object.getvlaue())
zip_file_bytes_io.seek(0)
解决方法
我相信这会做您想要的。正如我在已删除的评论中所说的那样,一个问题是zip_file.writestr()
的第一个参数应该是文件名/成员名,它将在存档中给出,第二个是要写入的数据。 >
为了能够做到这一点,必须保留图像文件名。现在,在get_images()
下面的代码中,返回[<image file name>,<PIL image object>]
的一对对值列表,以便在编写内存zip文件时可以使用该名称。
#!/usr/bin/env python3
# https://stackoverflow.com/questions/63439403/how-to-create-a-zip-file-in-memory-with-a-list-of-pil-image-objects
import io
import os
from PIL import Image
from pprint import pprint
from zipfile import ZipFile
def get_images(path):
""" Returns a list of image file base name & PIL image object pairs. """
# Harcoded with two images for testing purposes.
IMAGES = (r"C:\vols\Files\PythonLib\Stack Overflow\cookie_cutter_background.png",r"C:\vols\Files\PythonLib\Stack Overflow\Flying-Eagle.png")
images = []
for image_path in IMAGES:
# Get image file name without extension.
image_name = os.path.splitext(os.path.os.path.basename(image_path))[0]
pil_image = Image.open(image_path)
images.append([image_name,pil_image])
return images
def file_process_in_memory():
""" Converts PIL image objects into BytesIO in-memory bytes buffers. """
images = get_images('mypath')
for i,(image_name,pil_image) in enumerate(images):
file_object = io.BytesIO()
pil_image.save(file_object,"PNG")
pil_image.close()
images[i][1] = file_object # Replace PIL image object with BytesIO memory buffer.
return images # Return modified list.
images = file_process_in_memory()
# Create an in-memory zip file from the in-memory image file data.
zip_file_bytes_io = io.BytesIO()
with ZipFile(zip_file_bytes_io,'w') as zip_file:
for image_name,bytes_stream in images:
zip_file.writestr(image_name+".png",bytes_stream.getvalue())
pprint(zip_file.infolist()) # Print final contents of in memory zip file.
print('done')
样本输出:
[<ZipInfo filename='cookie_cutter_background.png' filemode='?rw-------' file_size=727857>,<ZipInfo filename='Flying-Eagle.png' filemode='?rw-------' file_size=462286>]
done