Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting PIL image to MIMEImage

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.

like image 818
user1103852 Avatar asked Jan 18 '23 00:01

user1103852


2 Answers

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)
like image 137
Anurag Uniyal Avatar answered Jan 28 '23 15:01

Anurag Uniyal


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())
like image 29
Korne127 Avatar answered Jan 28 '23 15:01

Korne127