How to Add Multiple Embed Images in an Email Using Python

How to add multiple embed images in an email using python

The solution turns out to be:

def AddImage(self, fileName, title):
internalFileName = '%s-%s-%s' %(fileName, datetime.now().strftime('%Y%m%d%H%M%S'), uuid.uuid4())
self.imgHtml +='<p style="font-size:15px;font-weight:bold;font-family:Comic Sans MS">%s</p><br><img src="cid:%s"><br>' %(title, internalFileName)
fp = open(fileName, 'rb')
msgImage = MIMEImage(fp.read())
fp.close()
msgImage.add_header('Content-ID', '<%s>' %(internalFileName))
self.msgRoot.attach(msgImage)
def Send(self, toList):
msgText = MIMEText(self.imgHtml, 'html')
self.msgAlternative.attach(msgText)
self.msgRoot['Subject'] = 'Audience Ingestion Integrated Test Report @%s [%s]' %(datetime.now().strftime('%Y-%m-%d'), socket.gethostname())
strFrom = 'notifier@freewheel.tv'
self.msgRoot['From'] = strFrom
strTo = email.Utils.COMMASPACE.join(toList)
self.msgRoot['To'] = strTo
smtp = smtplib.SMTP('smtp1.dev.fwmrm.net', 25)
smtp.sendmail(strFrom, strTo, self.msgRoot.as_string())
smtp.quit()

which means that when AddImage(), just attach the MIMEImage to the MIMEMultipart and add the string to the html string, and when Send() after several invocations of AddImage(), attach the MIMEText generated from the html string to MIMEMultipart.

Python - Send email with multiple image attachments

I think the code should be:

fp = open('image1.png', 'rb')
msgImage1 = MIMEImage(fp.read())
fp.close()
msgImage.add_header('Content-ID', '<image1>')
msgRoot.attach(msgImage1)

fp = open('image2.png', 'rb')
msgImage2 = MIMEImage(fp.read())
fp.close()
msgImage.add_header('Content-ID', '<image2>')
msgRoot.attach(msgImage2)

You need to specify it's image1 instead of just image

Python - send mail to GMAIL with embedded images

You need to attach it and reference it in the HTML. I.e. attach a message with a HTML img that sources the image you've attached.

I see you are well underway, working with the same modules and have a working code, so you should be able get it done with this snippet of code below:

.....
import os
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email.mime.image import MIMEImage
.....
# Get the files/images you want to add.
img_dir = "/images"
images = [os.path.join(img_dir, i) for i in os.listdir(img_dir)]

# Added a enumerate loop around the whole procedure.
# Reference to cid:image_id_"j", which you will attach to the email later.
for j, val in enumerate(images):
msgText = MIMEText('<br> <img src="cid:image_id_{}"> </br>'.format(j), 'html')
msgAlternative.attach(msgText)

with open('{}'.format(val), "rb") as attachment:
msgImage = MIMEImage(attachment.read())

# Define the image's ID with counter as you will reference it.
msgImage.add_header('Content-ID', '<image_id_{}>'.format(j))
msgRoot.attach(msgImage)

Attach multiple images into html email in Python

Simply keep filenames as list and use for-loop to repeate the same code for different items from list.

To have different Content-ID you can simply use f-string like f"<image{number}> with enumerate().

filenames = [
'newsletter/bar_chart.png',
'newsletter/scatter_plot.png',
'newsletter/image3.png',
'newsletter/image4.png',
]

for number, name in enumerate(filenames, 1):
fp = open(name, 'rb')
msg_image = MIMEImage(fp.read()) # PEP8: `lower_case_names` for variables
fp.close()
msg_image.add_header('Content-ID', f'<image{number}>')
msg_root.attach(msg_image)

This way you can get filenames from:

  • file
  • database
  • os.listdir('newsletter')
  • glob.glob('newsletter/*.png')
  • command line - python.exe script.py name1 name2 and filenames = sys.argv[1:]

Eventually you can create list with tuples (filename, content_id)

In list you can use string "<image4>" or you can use string "image4" and later use f-string to add < > - f"<{content_id}>".

filenames = [
('newsletter/bar_chart.png', 'bar_chart'),
('newsletter/scatter_plot.png', 'scatter_plot'),
('newsletter/image3.png', 'image3'),
('newsletter/image4.png', 'image4'),
]

for name, content_id in filenames:
fp = open(name, 'rb')
msg_image = MIMEImage(fp.read()) # PEP8: `lower_case_names` for variables
fp.close()
msg_image.add_header('Content-ID', f'<{content_id}>')
msg_root.attach(msg_image)

Eventually you could use name like newsletter/bar_chart.png to create content_id.

content_id = name.split('/')[-1].split('.')[0]  

It gives bar_chart


PEP 8 -- Style Guide for Python Code

Embed both images and text inside email body

i have managed to embed both text and image in one now i want to embed multiple images but only getting one r the last image

msg['Subject'] = "My text dated"
msg['From'] = MY_ADDRESS
msg['To'] = MY_ADDRESS


# set the plain text body
msg.set_content('This is a plain text body.')

# now create a Content-ID for the image
image_cid = make_msgid()
# if `domain` argument isn't provided, it will
# use your computer's name
email = "someome@gmail.com"
name = "someome"
# set an alternative html body
msg.add_alternative("""\
<html>
<body>
<p>This is an HTML body.<br>
It also has an image.
<p><h4 style="font-size:15px;">email{email}</h4></p>
<p><h4 style="font-size:15px;">Name{name}</h4></p>
</p>
<img src="cid:{image_cid}">
</body>
</html>
""".format(email="someome@gmail.com",name=name,image_cid=image_cid[1:-1]), subtype='html')
# image_cid looks like <long.random.number@xyz.com>
# to use it as the img src, we don't need `<` or `>`
# so we use [1:-1] to strip them off



from glob import glob
list_of_images = glob('*.jpg')

for filename in list_of_images:
# now open the image and attach it to the email
with open(filename, 'rb') as img:
# know the Content-Type of the image
maintype, subtype = mimetypes.guess_type(img.name)[0].split('/')
# attach it
msg.get_payload()[1].add_related(img.read(),
maintype=maintype,
subtype=subtype,
cid=image_cid)


Related Topics



Leave a reply



Submit