简体   繁体   中英

How to include inline images in e-mail signature when sent out with python?

How can I send a python e-mail with inline images for the signature? Currently, I use a link to display the images like this:

<img border="0" src="https://website.com/logo.png" role="presentation" alt="logo mail icon" style="max-width: 300px; width: 300px; display: block;">

But in Outlook the images are not loaded and the user needs to click on "display images" which ruins the e-mail, since I use it for business purposes (it is a confirmation link for a registration). Is there a way how to display the images inline and send them with the e-mail instead of a link?

My code so far:

from email.message import EmailMessage
import smtplib, ssl
import email.utils
import html2text

with open(html_template, 'r') as f:
        html_string = f.read()

plain_text = html2text.html2text(html_string)

msg               = EmailMessage()
msg['Subject']    = subject
msg['From']       = mail_address
msg['To']         = email_receiver
msg['Date']       = email.utils.formatdate()
msg.add_header('Content-Type','text/html')
msg.add_header('Content-Disposition', 'attachment', filename=file_attachment)
msg.set_content(plain_text)
msg.add_alternative(html_string.format(name=surname), subtype='html')

files = [file_attachment]
for file in files:
    with open(file, 'rb') as f:
        file_data = f.read()
        file_name = f.name
    msg.add_attachment(file_data, maintype='application', subtype='octet-stream', filename=file_name)

with smtplib.SMTP(smtp, port) as smtp:
    smtp.ehlo()
    smtp.starttls(context=ssl.create_default_context())
    smtp.ehlo()
    smtp.login(mail_address, mail_password)

try:
    smtp.send_message(msg)
    smtp.quit()

except Exception as e:
    print('ERROR')

I couldn't find much approaches or solutions. I've read about encoding the images into base64 but I am a bit confused.

Thanks in advance!

To display images inline, you have to provide the image data in the email itself. You can do so by using a base64 encoded string of your image data. Here an example:

 <img alt="Website" width="16" height="16" style="border:none;" src="data:image/png;filename=web.png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAABsAAAAbAFcG/0uAAABPElEQVQ4jaVT3U3DMBD+mgUSJqAbNEyQbkDYgL43Ejz7pUjkPZIHoBvUjNAJcDcoG7QTBH3mMzoikEC1dPL5/r+782wcR9jTdv09AFKD72cPYBu821rpV4C26+cAAoCF0Z91l0Z2oHnw7shHYZwjAN6PcnySLIo/S5ds5fMZQJlL0YNuOlaiONGV8sHsdv1MvC8AbhR9AHCNn8+7grD8NwCrQg17Dd7F4F1QRpZ8JbwH8ZRVtKEtfehbqNvB5EvlB+9OABKJP06aSZ+GEEZlOUnRmHctWe7HQuNEfhe/YP3zyQGG4N2SpPdGfBScpZoLYzfkMbKkdrI8ddv1eYSV+LlZLMhnPx0jMW/+M8a0ym3Xs9S8wjRigDsFS5AA7IwurXTwrs49YDksj0RsCUYeo3irIyXYF3+my74zgA9tApBUsNxB3wAAAABJRU5ErkJggg==" />

You can use online converters to get your base64 string or build it directly in your python script:

import base64
encoded_string = base64.b64encode(open("image.png", "rb").read())

Keep in mind, that inline images can also be blocked by the receivers mail client, so always provide proper alt descriptions.

The image has to be base64 encode and while implementing it to the html tag the b' prefix needs to be removed by using .decode()

import base64
encoded_string = base64.b64encode(open("image.png", "rb").read()).decode()

HTML code:

html = '''<img alt="Website" width="16" height="16" style="border:none;" src="data:image/png;filename=web.png;base64," />'''.format(logo=encoded_string)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM