I'd like to create an image using PIL and be able to email it without having to save it to disk.
This is what works, but involves saving to disk:
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
msg = MIMEMultipart()
im = Image.new("RGB", (200, 200))
with open("tempimg.jpg", "w") as f:
im.save(f, "JPEG")
with open("tempimg.jpg", 'rb') as f:
img = MIMEImage(f.read())
msg.attach(img)
Now I'd like to be able to do something like:
import StringIO
tempimg = StringIO.StringIO()
tempimg.write(im.tostring())
img = MIMEImage(tempimage.getvalue(), "JPG")
msg.attach(img)
, which doesn't work. I've found some discussion in Spanish that looks like it addresses the same question, with no solution except a pointer at StringIO.
im.tostring
returns raw image data but you need to pass whole image file data to MIMEImage
, so use StringIO module to save the image to memory and use that data:
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
from PIL import Image
import cStringIO
msg = MIMEMultipart()
im = Image.new("RGB", (200, 200))
memf = cStringIO.StringIO()
im.save(memf, "JPEG")
img = MIMEImage(memf.getvalue())
msg.attach(img)
Since the cStringIO module used in the Anurag Uniyal's answer has been removed in Python 3.0, here is a solution for Python 3.x:
To convert a given PIL image (here pil_image
) to a MIMEImage
, use the BytesIO module to save the PIL image to a byte buffer and use that to get a MIMEImage
.
from email.mime.image import MIMEImage
from io import BytesIO
from PIL import Image
byte_buffer = BytesIO()
pil_image.save(byte_buffer, "PNG")
mime_image = MIMEImage(byte_buffer.getvalue())
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With