Embedding Image to Email
From Logic Wiki
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
- Save your image(s) to D:\Web\EmbeddedImages" (folder setting is in app.config of VDSCore.Mailer application)
- Let’s say you have a TrainingLogo.jpg save it as D:\Web\EmbeddedImages\TrainingLogo.jpg
- 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);