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