Embedding Image to Email

From Logic Wiki
Jump to: navigation, search


The problem

After I'd sent an email containing image with public url as src it failed to display images in outlook and gmail

<img src="http://www.imagesource.com/image1.jpg">

So I converted Image src to base64 in https://www.base64-image.de/ It worked in outlook but not worked in Gmail.

 <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhE....

Finally I came to a point where embedding images to emails is the last solution. But it must be applied to templates and I had to complete this with minimum effort and minimum changes (without breaking working code)

The solution

  • I created a folder where Mailer app sits
D:\Web\EmbeddedImages
  • Added this folder to App.config
<add key="ImagesFolder" value="D:\Web\EmbeddedImages" />
  • in the method where I send emails I added these lines
MailMessage mm = new MailMessage();
var imagesFolder = ConfigurationManager.AppSettings["ImagesFolder"];
string pattern = @"##IMG(.+?)##";
MatchCollection matches = Regex.Matches(email.Body, pattern);
var imgId = 0;
var images = new List<LinkedResource>();
foreach (var item in matches)
{
  imgId += 1;
  var imgName = item.ToString().Replace("##", "").Replace("IMG|", "");

  byte[] reader = File.ReadAllBytes(imagesFolder + "\\" + imgName);
  MemoryStream image1 = new MemoryStream(reader);
  LinkedResource linkedImg = new LinkedResource(image1, System.Net.Mime.MediaTypeNames.Image.Jpeg);

  linkedImg.ContentId = "image" + imgId.ToString();
  linkedImg.ContentType = new System.Net.Mime.ContentType("image/jpg");
  email.Body = email.Body.Replace(item.ToString(), "cid:" + "image" + imgId.ToString());
  images.Add(linkedImg);
}

if (matches.Count > 0)
{
  AlternateView av1 = AlternateView.CreateAlternateViewFromString(email.Body, null, MediaTypeNames.Text.Html);
  foreach (var linkedResource in images)
  {
     av1.LinkedResources.Add(linkedResource);
  }
mm.AlternateViews.Add(av1);
}
mm.Body = email.Body;

Usage

  1. Save your image(s) to D:\Web\EmbeddedImages" (folder setting is in app.config of VDSCore.Mailer application)
  2. Let’s say you have a TrainingLogo.jpg save it as D:\Web\EmbeddedImages\TrainingLogo.jpg
  3. In the template change img src like <img src=”##IMG|TrainingLogo.jpg##”>


I was inspired from the code I found below

string body = "blah blah blah... body goes here with the image tag: <img src=\"cid:companyLogo\" width="104" height="27" />";

byte[] reader = File.ReadAllBytes("E:\\TestImage.jpg");
MemoryStream image1 = new MemoryStream(reader);
AlternateView av = AlternateView.CreateAlternateViewFromString(body, null, System.Net.Mime.MediaTypeNames.Text.Html);

LinkedResource headerImage = new LinkedResource(image1, System.Net.Mime.MediaTypeNames.Image.Jpeg);
headerImage.ContentId = "companyLogo";
headerImage.ContentType = new ContentType("image/jpg");
av.LinkedResources.Add(headerImage);


System.Net.Mail.MailMessage message = new System.Net.Mail.MailMessage();
message.AlternateViews.Add(av);
message.To.Add(emailTo);
message.Subject = " Your order is being processed...";
message.From = new System.Net.Mail.MailAddress("xxx@example.com");


ContentType mimeType = new System.Net.Mime.ContentType("text/html");
AlternateView alternate = AlternateView.CreateAlternateViewFromString(body, mimeType);
message.AlternateViews.Add(alternate);