在 html 电子邮件中嵌入图像

我试图发送一个多部分/相关的 HTML 电子邮件与嵌入的 gif 图像。此电子邮件是使用 Oracle PL/SQL 生成的。我的尝试失败了,图像显示为红色 X (在 Outlook2007和雅虎邮件中)

我已经发送了一段时间的 html 电子邮件,但我现在的要求是在电子邮件中使用几个 gif 图像。我可以存储在我们的网络服务器之一,只是链接到他们,但许多用户的电子邮件客户端将不会显示他们自动,将需要更改设置或手动下载他们为每个电子邮件。

因此,我的想法是嵌入图像。我的问题是:

  1. 我做错了什么?
  2. 嵌入式方法正确吗?
  3. 如果我需要使用越来越多的图像,还有其他选项吗?附件不会起作用,因为图片通常是标志和图标,在信息的上下文中是没有意义的。此外,电子邮件的一些元素是链接到一个在线系统,所以生成一个静态 PDF 和附加不会工作(至少我的知识)。

片段:

MIME-Version: 1.0
To: me@gmail.com
BCC: me@yahoo.com
From: email@yahoo.com
Subject: Test
Reply-To: email@yahoo.com
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--

非常感谢。

顺便说一句: 是的,我已经验证了 base64数据是正确的,因为我可以将图像嵌入 html 本身(使用相同的算法来创建头数据) ,并在 Firefox/IE 中查看图像。

我还应该指出,这不是垃圾邮件,电子邮件发送给特定的客户谁是期待它每天。内容是数据驱动的,而不是广告。

524003 次浏览

尝试直接插入,这样你就可以在电子邮件的不同位置插入多个图像。

<img src="data:image/jpg;base64,\{\{base64-data-string here}}" />

为了使这篇文章对其他人有用: 如果您没有 base64数据字符串,可以在以下位置轻松创建一个: 从一个图像文件 http://www.motobit.com/util/base64-decoder-encoder.asp

电子邮件源代码看起来像这样,但是我真的不能告诉你这个边界是什么:

 To: email@email.de
Subject: ...
Content-Type: multipart/related;
boundary="------------090303020209010600070908"


This is a multi-part message in MIME format.
--------------090303020209010600070908
Content-Type: text/html; charset=ISO-8859-15
Content-Transfer-Encoding: 7bit


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>


<meta http-equiv="content-type" content="text/html; charset=ISO-8859-15">
</head>
<body bgcolor="#ffffff" text="#000000">
<img src="cid:part1.06090408.01060107" alt="">
</body>
</html>


--------------090303020209010600070908
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]


--------------090303020209010600070908--

编辑: 哦,我刚刚意识到,如果你插入我文章中的第一个代码片段,用雷鸟写一封电子邮件,雷鸟会自动改变 html 代码,使其看起来和我文章中的第二个代码几乎一样。

如果它不工作,你可以尝试这些工具之一,将图像转换成一个 HTML 表(但要注意图像的大小) :

我在这里找不到任何有用的答案,所以我提供了我的解决方案。

  1. 问题是您使用 multipart/related作为内容类型,这在本例中是不好的。我使用的是 multipart/mixed和内部 multipart/alternative(它在大多数客户端上工作)。

  2. 信息结构应如下:

    [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

如果您使用“插入/图片”菜单功能插入图片文件,Outlook 和 Outlook Express 都可以生成这些多部分图片电子邮件格式,这可能会很有意思。

显然,电子邮件类型必须设置为 HTML (而不是纯文本)。

任何其他方法(例如拖放或任何命令行调用)都会导致将映像作为附件发送。

如果你发送这样的电子邮件给你自己,你可以看到它是如何格式化的! :)

FWIW,我正在寻找一个独立的窗口可执行程序,它从命令行模式的内联图像,但似乎没有。这是一个路径,许多已经上升... 一个可以做到这一点,说 Outlook 快递,通过传递它一个适当的格式。Eml 文件。

使用 Base64在 html 中嵌入图像非常棒。尽管如此,请注意 base64字符串可以使您的电子邮件大小变大。

所以,

1)如果你有很多图片,将你的图片上传到服务器并从服务器上载这些图片可以使你的电子邮件更小。(你可以通过谷歌获得很多免费服务)

2)如果你的邮件中只有几张图片,使用 base64字符串绝对是一个很棒的选择。

除了现有答案提供的选择之外,您还可以使用命令在 linux 上生成 base64字符串:

base64 test.jpg
  1. 您需要3个内联图像边界才能完全兼容。

  2. 所有东西都放在 multipart/mixed里面。

  3. 然后使用 multipart/related包含您的 multipart/alternative和您的图像附件标题。

  4. 最后,在 multipart/mixed的最后边界内包含您可下载的附件。

另一种解决方案是将图像附加为附件,然后使用 cid 引用它的 html 代码。

HTML 代码:

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

C # 代码:

EmailMessage email = new EmailMessage(service);
email.Subject = "Email with Image";
email.Body = new MessageBody(BodyType.HTML, html);
email.ToRecipients.Add("abc@xyz.com");
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();

实际上有一篇非常好的博客文章列出了 Martyn Davies 用三种不同方法解决这个问题的优缺点。你可以在 https://sendgrid.com/blog/embedding-images-emails-facts/上阅读。

我想添加使用 CSS 背景图像的第四种方法。

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

你的电子邮件主体和 css 类,如:

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

对于那些无法得到这些解决方案的人: 用电子邮件发送内联图像 按照@T30提供的解决方案中列出的步骤,我可以让内联图像显示,而不会被 Outlook 阻塞(之前的方法被阻塞)。如果你像我们一样使用交换,那么在做:

service = new ExchangeService(ExchangeVersion);
service.AutodiscoverUrl("email@domain.com");
SmtpClient smtp = new SmtpClient(service.Url.Host);

您将需要通过它您的交换服务网址主机。除了遵循这个解决方案之外,应该允许您轻松地发送嵌入式图像。

我知道这是一个老职位,但目前的答案不解决的事实,展望和许多其他电子邮件提供商不支持内联图像或 CID 图像。在电子邮件中放置图像最有效的方法是在线托管它,并在电子邮件中放置一个链接到它。对于小的电子邮件列表一个公共的下拉框工程罚款。这也使电子邮件的大小保持下来。

以下是实现这一目标的两种方式的工作守则:

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 = "john@example.com";
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("john@example.com");
recipient.Resolve();


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

Pavel Perna 的帖子对我有很大帮助(不能评论我的声誉,这就是为什么我把这个作为答案) : 在某些版本的 Microsoft Exchange 中,内联内容处理被删除(请看微软的这篇文章)。该图像不是用户在 Outlook 中看到的邮件的一部分。作为一种解决方案,使用“内容处置: 附件”代替。Outlook2016不会将图像显示为邮件消息中使用的附件,尽管它们使用“ Content-Disposition: attachement”。

尝试用上下文解决这个问题。请求:

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

在我的情况下,当我使用 Content-ID 时,我也将该图像作为附件,这不是最好的解决方案。