[html] embedding image in html email

I'm trying to send a multipart/related html email with embedded gif images. This email is generated using Oracle PL/SQL. My attempts have failed, with the image showing up as a red X (in Outlook 2007 and yahoo mail)

I've been sending html emails for some time, but my requirements are now to use several gif images in the email. I can store these on one of our web servers and just link to them, but many users email clients will not show them automatically and will need to either change settings or manually download them for each email.

So, my thoughts are to embed the image. My questions are:

  1. What am I doing wrong here?
  2. Is the embedding approach the correct one?
  3. Any other options if I need to use more and more images? Attachments won't work, as the images are typically logos and icons that won't make sense out of the context of the message. Also, some elements of the email are links into an online system, so generating a static PDF and attaching won't work (to my knowledge anyway).

snippet:

MIME-Version: 1.0
To: [email protected]
BCC: [email protected]
From: [email protected]
Subject: Test
Reply-To: [email protected]
Content-Type: multipart/related; boundary="a1b2c3d4e3f2g1"

--a1b2c3d4e3f2g1

content-type: text/html;

    <html>
    <head><title>My title</title></head>
    <body>
    <div style="font-size:11pt;font-family:Calibri;">
    <p><IMG SRC="cid:my_logo" alt="Logo"></p>

... more html here ...

</div></body></html> 

--a1b2c3d4e3f2g1

Content-Type: image/gif;
Content-ID:<my_logo>
Content-Transfer-Encoding: base64
Content-Disposition: inline

[base64 image data here]

--a1b2c3d4e3f2g1--

Many thanks.

BTW: Yes, I have verified that the base64 data is correct, as I can embed the image in the html itself (using same algo use for creating header data) and see image in Firefox/IE.

I should also note that this is NOT for spam, the emails are sent to specific clients who are expecting it daily. The content is data-driven, and not adverts.

This question is related to html image oracle email mime

The answer is


Using Base64 to embed images in html is awesome. Nonetheless, please notice that base64 strings can make your email size big.

Therefore,

1) If you have many images, uploading your images to a server and loading those images from the server can make your email size smaller. (You can get a lot of free services via Google)

2) If there are just a few images in your mail, using base64 strings is definitely an awesome option.

Besides the choices provided by existing answers, you can also use a command to generate a base64 string on linux:

base64 test.jpg

The following is working code with two ways of achieving this:

using System;
using Outlook = Microsoft.Office.Interop.Outlook;

namespace ConsoleApp2
{
    class Program
    {
        static void Main(string[] args)
        {

            Method1();
            Method2();
        }

        public static void Method1()
        {
            Outlook.Application outlookApp = new Outlook.Application();
            Outlook.MailItem mailItem = outlookApp.CreateItem(Outlook.OlItemType.olMailItem);
            mailItem.Subject = "This is the subject";
            mailItem.To = "[email protected]";
            string imageSrc = "D:\\Temp\\test.jpg"; // Change path as needed

            var attachments = mailItem.Attachments;
            var attachment = attachments.Add(imageSrc);
            attachment.PropertyAccessor.SetProperty("http://schemas.microsoft.com/mapi/proptag/0x370E001F", "image/jpeg");
            attachment.PropertyAccessor.SetProperty("http://schemas.microsoft.com/mapi/proptag/0x3712001F", "myident"); // Image identifier found in the HTML code right after cid. Can be anything.
            mailItem.PropertyAccessor.SetProperty("http://schemas.microsoft.com/mapi/id/{00062008-0000-0000-C000-000000000046}/8514000B", true);

            // Set body format to HTML

            mailItem.BodyFormat = Outlook.OlBodyFormat.olFormatHTML;
            string msgHTMLBody = "<html><head></head><body>Hello,<br><br>This is a working example of embedding an image unsing C#:<br><br><img align=\"baseline\" border=\"1\" hspace=\"0\" src=\"cid:myident\" width=\"\" 600=\"\" hold=\" /> \"></img><br><br>Regards,<br>Tarik Hoshan</body></html>";
            mailItem.HTMLBody = msgHTMLBody;
            mailItem.Send();
        }

        public static void Method2()
        {

            // Create the Outlook application.
            Outlook.Application outlookApp = new Outlook.Application();

            Outlook.MailItem mailItem = (Outlook.MailItem)outlookApp.CreateItem(Outlook.OlItemType.olMailItem);

            //Add an attachment.
            String attachmentDisplayName = "MyAttachment";

            // Attach the file to be embedded
            string imageSrc = "D:\\Temp\\test.jpg"; // Change path as needed

            Outlook.Attachment oAttach = mailItem.Attachments.Add(imageSrc, Outlook.OlAttachmentType.olByValue, null, attachmentDisplayName);

            mailItem.Subject = "Sending an embedded image";

            string imageContentid = "someimage.jpg"; // Content ID can be anything. It is referenced in the HTML body

            oAttach.PropertyAccessor.SetProperty("http://schemas.microsoft.com/mapi/proptag/0x3712001E", imageContentid);

            mailItem.HTMLBody = String.Format(
                "<body>Hello,<br><br>This is an example of an embedded image:<br><br><img src=\"cid:{0}\"><br><br>Regards,<br>Tarik</body>",
                imageContentid);

            // Add recipient
            Outlook.Recipient recipient = mailItem.Recipients.Add("[email protected]");
            recipient.Resolve();

            // Send.
            mailItem.Send();
        }
    }
}

I know this is an old post, but the current answers dont address the fact that outlook and many other email providers dont support inline images or CID images. The most effective way to place images in emails is to host it online and place a link to it in the email. For small email lists a public dropbox works fine. This also keeps the email size down.


For those who couldnt get one of these solutions working: Send inline image in email Following the steps laid out in the solution offered by @T30 i was able to get my inline image to display without being blocked by outlook (previous methods it was blocked). If you are using exchange like we are then also when doing:

service = new ExchangeService(ExchangeVersion);
service.AutodiscoverUrl("[email protected]");
SmtpClient smtp = new SmtpClient(service.Url.Host);

you will need to pass it your exchange service url host. Other than that following this solution should allow you to easily send embedded imgages.


Try to resolve that with Context.Request:

<img width="150" height="60" src="@($"{Context.Request.Scheme}://{Context.Request.Host}{Context.Request.PathBase}/images/logo.png")" />

In my situation, when I used Content-ID I had that image as an attachment as well, and that was not the best solution.


It may be of interest that both Outlook and Outlook Express can generate these multipart image email formats, if you insert the image files using the Insert / Picture menu function.

Obviously the email type must be set to HTML (not plain text).

Any other method (e.g. drag/drop, or any command-line invocation) results in the image(s) being sent as an attachment.

If you then send such an email to yourself, you can see how it is formatted! :)

FWIW, I am looking for a standalone windows executable which does inline images from the command line mode, but there seem to be none. It's a path which many have gone up... One can do it with say Outlook Express, by passing it an appropriately formatted .eml file.


  1. You need 3 boundaries for inline images to be fully compliant.

  2. Everything goes inside the multipart/mixed.

  3. Then use the multipart/related to contain your multipart/alternative and your image attachment headers.

  4. Lastly, include your downloadable attachments inside the last boundary of multipart/mixed.


One additional hint to Pavel Perna's post which helped me very much (cannot comment with my reputation, that's why I post this as answer): In some versions of Microsoft Exchange, the inline contents disposition is removed (see this post by Microsoft). The image is simply not part in the mail the user sees in Outlook. As a workaround, use "Content-Disposition: attachement" instead. Outlook 2016 won't show images as attachement that are used in the mail message, although they use the "Content-Disposition: attachement".


There's actually a very good blog post that lists pro's and cons of three different approaches to this problem by Martyn Davies. You can read it at https://sendgrid.com/blog/embedding-images-emails-facts/.

I'd like to add a fourth approach using CSS background images.

Add

<div id="myImage"></div>

to your e-mail body and a css class like:

#myImage {
    background-image:  url('data:image/png;base64,iVBOR...[some more encoding]...rkggg==');
    width: [the-actual-image-width];
    height: [the-actual-image-height];
}

The other solution is attaching the image as attachment and then referencing it html code using cid.

HTML Code:

<html>
    <head>
    </head>
    <body>
        <img width=100 height=100 id="1" src="cid:Logo.jpg">
    </body>
</html>

C# Code:

EmailMessage email = new EmailMessage(service);
email.Subject = "Email with Image";
email.Body = new MessageBody(BodyType.HTML, html);
email.ToRecipients.Add("[email protected]");
string file = @"C:\Users\acv\Pictures\Logo.jpg";
email.Attachments.AddFileAttachment("Logo.jpg", file);
email.Attachments[0].IsInline = true;
email.Attachments[0].ContentId = "Logo.jpg";
email.SendAndSaveCopy();

I don't find any of the answers here useful, so I am providing my solution.

  1. The problem is that you are using multipart/related as the content type which is not good in this case. I am using multipart/mixed and inside it multipart/alternative (it works on most clients).

  2. The message structure should be as follows:

    [Headers]
    Content-type:multipart/mixed; boundary="boundary1"
    --boundary1
    Content-type:multipart/alternative; boundary="boundary2"
    --boundary2
    Content-Type: text/html; charset=ISO-8859-15
    Content-Transfer-Encoding: 7bit
    [HTML code with a href="cid:..."]
    
    --boundary2
    Content-Type: image/png;
    name="moz-screenshot.png"
    Content-Transfer-Encoding: base64
    Content-ID: <part1.06090408.01060107>
    Content-Disposition: inline; filename="moz-screenshot.png"
    [base64 image data here]
    
    --boundary2--
    --boundary1--
    

Then it will work


If you are using Outlook to send a static image with hyperlink, an easy way would be to use Word.

  1. Open MS Word
  2. Copy the image onto a blank page
  3. Add hyperlink to the image (Ctrl + K)
  4. Copy the image to your email

If it does not work, you may try one of these tools that convert the image to an HTML table (beware the size of your image though):


Examples related to html

Embed ruby within URL : Middleman Blog Please help me convert this script to a simple image slider Generating a list of pages (not posts) without the index file Why there is this "clear" class before footer? Is it possible to change the content HTML5 alert messages? Getting all files in directory with ajax DevTools failed to load SourceMap: Could not load content for chrome-extension How to set width of mat-table column in angular? How to open a link in new tab using angular? ERROR Error: Uncaught (in promise), Cannot match any routes. URL Segment

Examples related to image

Reading images in python Numpy Resize/Rescale Image Convert np.array of type float64 to type uint8 scaling values Extract a page from a pdf as a jpeg How do I stretch an image to fit the whole background (100% height x 100% width) in Flutter? Angular 4 img src is not found How to make a movie out of images in python Load local images in React.js How to install "ifconfig" command in my ubuntu docker image? How do I display local image in markdown?

Examples related to oracle

concat yesterdays date with a specific time ORA-28001: The password has expired how to modify the size of a column How to create a blank/empty column with SELECT query in oracle? Find the number of employees in each department - SQL Oracle Query to display all tablespaces in a database and datafiles When or Why to use a "SET DEFINE OFF" in Oracle Database How to insert date values into table error: ORA-65096: invalid common user or role name in oracle In Oracle SQL: How do you insert the current date + time into a table?

Examples related to email

Monitoring the Full Disclosure mailinglist require(vendor/autoload.php): failed to open stream Failed to authenticate on SMTP server error using gmail Expected response code 220 but got code "", with message "" in Laravel How to to send mail using gmail in Laravel? Laravel Mail::send() sending to multiple to or bcc addresses Getting "The remote certificate is invalid according to the validation procedure" when SMTP server has a valid certificate How to validate an e-mail address in swift? PHP mail function doesn't complete sending of e-mail How to validate email id in angularJs using ng-pattern

Examples related to mime

Resource blocked due to MIME type mismatch (X-Content-Type-Options: nosniff) Nginx fails to load css files Which MIME type to use for a binary file that's specific to my program? embedding image in html email How to set MimeBodyPart ContentType to "text/html"? Mail multipart/alternative vs multipart/mixed Proper MIME type for OTF fonts How can I find out a file's MIME type (Content-Type)? Detect when browser receives file download Get MIME type from filename extension