ผมได้สร้างภาพโดยใช้PIL ฉันจะบันทึกลงในสตริงในหน่วยความจำได้อย่างไร Image.save()
วิธีการต้องใช้ไฟล์
ฉันต้องการเก็บภาพหลาย ๆ ภาพไว้ในพจนานุกรม
คำตอบ:
คุณสามารถใช้BytesIO
คลาสเพื่อรับ wrapper รอบ ๆ สตริงที่ทำงานเหมือนไฟล์ BytesIO
วัตถุให้อินเตอร์เฟซเดียวกันเป็นไฟล์ แต่จะช่วยประหยัดเนื้อหาเพียงในหน่วยความจำ:
import io
with io.BytesIO() as output:
image.save(output, format="GIF")
contents = output.getvalue()
คุณต้องระบุรูปแบบเอาต์พุตด้วยformat
พารามิเตอร์อย่างชัดเจนมิฉะนั้น PIL จะเพิ่มข้อผิดพลาดเมื่อพยายามตรวจจับโดยอัตโนมัติ
หากคุณโหลดรูปภาพจากไฟล์มันมีformat
พารามิเตอร์ที่มีรูปแบบไฟล์ต้นฉบับดังนั้นในกรณีนี้คุณสามารถformat=image.format
ใช้ได้
ใน Python 2 เวอร์ชันเก่าก่อนที่จะเปิดตัวio
โมดูลคุณจะต้องใช้StringIO
โมดูลแทน
You can use a file object instead of a filename. In this case, you must always specify the format.
ดังนั้นหากอาร์กิวเมนต์แรกเป็นอ็อบเจ็กต์ไฟล์คุณต้องส่งผ่านอาร์กิวเมนต์ที่สองซึ่งเป็นรูปแบบ (เช่น'PNG'
)
from io import StringIO
image.save(output, format=image.format)
สำหรับ Python3 จำเป็นต้องใช้ BytesIO:
from io import BytesIO
from PIL import Image, ImageDraw
image = Image.new("RGB", (300, 50))
draw = ImageDraw.Draw(image)
draw.text((0, 0), "This text is drawn on image")
byte_io = BytesIO()
image.save(byte_io, 'PNG')
อ่านเพิ่มเติม: http://fadeit.dk/blog/post/python3-flask-pil-in-memory-image
วิธีแก้ปัญหาของ sth ไม่ได้ผลสำหรับฉัน
เพราะใน ...
Imaging / PIL / Image.pyc บรรทัด 1423 -> เพิ่ม KeyError (ext) # ส่วนขยายที่ไม่รู้จัก
กำลังพยายามตรวจหารูปแบบจากนามสกุลในชื่อไฟล์ซึ่งไม่มีอยู่ในกรณี StringIO
คุณสามารถข้ามการตรวจจับรูปแบบได้โดยตั้งค่ารูปแบบด้วยตัวคุณเองในพารามิเตอร์
import StringIO
output = StringIO.StringIO()
format = 'PNG' # or 'JPEG' or whatever you want
image.save(output, format)
contents = output.getvalue()
output.close()
save()
สามารถใช้วัตถุคล้ายไฟล์เช่นเดียวกับเส้นทางดังนั้นคุณสามารถใช้บัฟเฟอร์ในหน่วยความจำเช่นStringIO
:
buf = StringIO.StringIO()
im.save(buf, format='JPEG')
jpeg = buf.getvalue()
ด้วยความทันสมัย (ณ กลางปี 2017 Python 3.5 และ Pillow 4.0):
ดูเหมือนว่า StringIO จะไม่ทำงานเหมือนเดิมอีกต่อไป คลาส BytesIO เป็นวิธีที่เหมาะสมในการจัดการสิ่งนี้ ฟังก์ชันบันทึกของ Pillow คาดว่าสตริงเป็นอาร์กิวเมนต์แรกและไม่น่าแปลกใจที่จะไม่เห็น StringIO เช่นนี้ สิ่งต่อไปนี้คล้ายกับโซลูชัน StringIO รุ่นเก่า แต่มี BytesIO แทน
from io import BytesIO
from PIL import Image
image = Image.open("a_file.png")
faux_file = BytesIO()
image.save(faux_file, 'png')
เมื่อคุณพูดว่า "ฉันต้องการเก็บภาพจำนวนมากในพจนานุกรม" จะไม่ชัดเจนว่านี่เป็นโครงสร้างในหน่วยความจำหรือไม่
คุณไม่จำเป็นต้องทำสิ่งนี้เพื่อทำให้ภาพในความทรงจำเสื่อมลง เพียงแค่เก็บไฟล์image
วัตถุไว้ในพจนานุกรมของคุณ
หากคุณจะเขียนพจนานุกรมของคุณลงในไฟล์คุณอาจต้องการดู im.tostring()
วิธีการและไฟล์Image.fromstring()
ฟังก์ชัน
http://effbot.org/imagingbook/image.htm
im.tostring () => สตริง
ส่งคืนสตริงที่มีข้อมูลพิกเซลโดยใช้ตัวเข้ารหัส "raw" มาตรฐาน
Image.fromstring (โหมดขนาดข้อมูล) => รูปภาพ
สร้างหน่วยความจำภาพจากข้อมูลพิกเซลในสตริงโดยใช้ตัวถอดรหัส "raw" มาตรฐาน
"รูปแบบ" (.jpeg, .png ฯลฯ ) จะมีความสำคัญเฉพาะบนดิสก์เมื่อคุณแลกเปลี่ยนไฟล์ หากคุณไม่ได้แลกเปลี่ยนไฟล์รูปแบบก็ไม่สำคัญ