提问人:tbone 提问时间:7/15/2011 最后编辑:tbone 更新时间:5/27/2023 访问量:561594
在 HTML 电子邮件中嵌入图像
embedding image in html email
问:
我正在尝试发送一封包含嵌入式 gif 图像的多部分/相关 html 电子邮件。此电子邮件是使用 Oracle PL/SQL 生成的。我的尝试失败了,图像显示为红色 X(在 Outlook 2007 和 yahoo 邮件中)
我已经发送 html 电子邮件一段时间了,但我现在的要求是在电子邮件中使用多个 gif 图像。我可以将它们存储在我们的一个 Web 服务器上并链接到它们,但许多用户的电子邮件客户端不会自动显示它们,并且需要更改设置或手动下载每封电子邮件。
所以,我的想法是嵌入图像。我的问题是:
- 我在这里做错了什么?
- 嵌入方法是否正确?
- 如果我需要使用越来越多的图像,还有其他选择吗?附件不起作用,因为图像通常是徽标和图标,在消息的上下文中没有意义。此外,电子邮件的某些元素是指向在线系统的链接,因此生成静态 PDF 并附加不起作用(据我所知)。
片段:
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--
非常感谢。
顺便说一句:是的,我已经验证了 base64 数据是正确的,因为我可以将图像嵌入到 html 本身中(使用与创建标头数据相同的算法)并在 Firefox/IE 中查看图像。
我还应该注意,这不是垃圾邮件,电子邮件会发送给每天期待它的特定客户。内容是数据驱动的,而不是广告。
答:
尝试直接插入它,这样您就可以在电子邮件的不同位置插入多张图像。
<img src="data:image/jpg;base64,{{base64-data-string here}}" />
并使这篇文章对其他人有用: 如果您没有 base64 数据字符串,请在以下位置轻松创建一个:从图像文件 http://www.motobit.com/util/base64-decoder-encoder.asp。
电子邮件源代码看起来像这样,但我真的不能告诉你这个边界的东西是做什么用的:
To: [email protected]
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--
编辑:哦,我刚刚意识到,如果你插入我帖子中的第一个代码片段来用 thunderbird 写一封电子邮件,thunderbird 会自动更改 html 代码,使其看起来与我帖子中的第二个代码几乎相同。
评论
如果它不起作用,您可以尝试以下工具之一,将图像转换为 HTML 表格(但要注意图像的大小):
- http://stylecampaign.com/blog/2009/12/bypass-image-blocking-by-converting-images-to-html/
- http://neil.fraser.name/software/img2html/
评论
我发现这里的任何答案都没有用,所以我提供了我的解决方案。
问题是您使用的是内容类型,在这种情况下不好。我正在使用它并在其中(它适用于大多数客户端)。
multipart/related
multipart/mixed
multipart/alternative
消息结构应如下所示:
[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--
然后它会起作用
评论
如果您使用“插入/图片”菜单功能插入图像文件,则 Outlook 和 Outlook Express 都可以生成这些多部分图像电子邮件格式,这可能会令人感兴趣。
显然,电子邮件类型必须设置为HTML(而不是纯文本)。
任何其他方法(例如拖放或任何命令行调用)都会导致图像作为附件发送。
如果您随后将这样的电子邮件发送给自己,您可以看到它的格式!:)
FWIW,我正在寻找一个独立的 Windows 可执行文件,它可以从命令行模式执行内联图像,但似乎没有。这是一条许多人都走过的道路......例如,可以通过向 Outlook Express 传递一个格式适当的 .eml 文件来做到这一点。
使用 Base64 在 html 中嵌入图像真是太棒了。尽管如此,请注意,base64 字符串会使您的电子邮件大小变大。
因此
1)如果您有很多图像,将图像上传到服务器并从服务器加载这些图像可以使您的电子邮件大小更小。(您可以通过Google获得很多免费服务)
2) 如果您的邮件中只有几张图片,使用 base64 字符串绝对是一个很棒的选择。
除了现有答案提供的选项外,您还可以使用命令在 linux 上生成 base64 字符串:
base64 test.jpg
评论
您需要 3 个边界才能使内联图像完全兼容。
一切都在里面。
multipart/mixed
然后使用 to 包含您和您的图像附件标题。
multipart/related
multipart/alternative
最后,将可下载的附件包含在 的最后一个边界内。
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("[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();
评论
实际上,有一篇非常好的博客文章列出了马丁·戴维斯(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 protected]");
SmtpClient smtp = new SmtpClient(service.Url.Host);
您需要将它传递给您的 Exchange 服务 URL 主机。除此之外,遵循此解决方案应该允许您轻松发送嵌入式 imgage。
我知道这是一篇旧文章,但目前的答案并没有解决 Outlook 和许多其他电子邮件提供商不支持内联图像或 CID 图像的事实。在电子邮件中放置图像的最有效方法是在线托管图像并在电子邮件中放置指向它的链接。对于小型电子邮件列表,公共 Dropbox 工作正常。这也降低了电子邮件的大小。
以下是使用两种实现此目的的方法的工作代码:
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();
}
}
}
Pavel Perna的帖子对我帮助很大(不能用我的声誉发表评论,这就是我发布这个作为答案的原因):在某些版本的Microsoft Exchange中,删除了内联内容处置(请参阅Microsoft的这篇文章)。该图像根本不是用户在 Outlook 中看到的邮件的一部分。解决方法是,请改用“Content-Disposition: attachement”。Outlook 2016 不会将邮件中使用的图像显示为附件,尽管它们使用“内容处置:附件”。
尝试使用 Context.Request 解决此问题:
<img width="150" height="60" src="@($"{Context.Request.Scheme}://{Context.Request.Host}{Context.Request.PathBase}/images/logo.png")" />
在我的情况下,当我使用 Content-ID 时,我也将该图像作为附件,这不是最好的解决方案。
评论
如果要使用 Microsoft EWS 服务在电子邮件中发送内联图像,可以将图像作为附件发送,并将其设置为内联。
以下是将 MIMEMessage 转换为 EmailMessage 的 java 代码片段:
ExchangeEwsConnection ewsConnection =
ExchangeEwsSupport.getConnection(configuration, connectionDetails, false, true);
try {
ExchangeService exchangeService =
ExchangeEwsSupport.getExchangeService(configuration, ewsConnection, null);
EmailMessage emailMessage = new EmailMessage(exchangeService);
emailMessage.setSubject(message.getSubject());
emailMessage.getToRecipients().add(new EmailAddress("[email protected]"));
if (message instanceof MimeMessage) {
MimeMessage mimeMessage = (MimeMessage) message;
Multipart multipart = (Multipart) mimeMessage.getContent();
for (int i = 0; i < multipart.getCount(); i++) {
BodyPart bodyPart = multipart.getBodyPart(i);
if (StringUtils.equalsIgnoreCase("text/html",
bodyPart.getDataHandler().getContentType())) {
emailMessage
.setBody(new MessageBody(bodyPart.getDataHandler().getContent().toString()));
}
if (StringUtils.equalsIgnoreCase(bodyPart.getDisposition(), Part.INLINE)) {
FileDataSource fileDataSource =
((FileDataSource) bodyPart.getDataHandler().getDataSource());
File imageFile = fileDataSource.getFile();
FileAttachment imageInlineAttachment = emailMessage.getAttachments().addFileAttachment(
imageFile.getName(), new FileInputStream(imageFile.getAbsolutePath()));
imageInlineAttachment.setContentType("image/png");
imageInlineAttachment.setIsInline(true);
String contentId =
bodyPart.getHeader("Content-ID")[0];
imageInlineAttachment.setContentId(contentId);
} else if (StringUtils.equalsIgnoreCase(bodyPart.getDisposition(), Part.ATTACHMENT)) {
FileDataSource fileDataSource =
((FileDataSource) bodyPart.getDataHandler().getDataSource());
File file = fileDataSource.getFile();
emailMessage.getAttachments().addFileAttachment(file.getName(), file.getAbsolutePath());
}
}
}
emailMessage.send();
} catch (Exception e) {
logger.log(“Exception occurred, cause:”, e.getCause());
}
以下是将MIMEMessage转换为EmailMessage格式的分步指南 - https://azaylamba.medium.com/converting-mimemessage-to-emailmessage-while-sending-email-using-microsoft-ews-service-a-57137e281f53
它详细说明了如何在电子邮件中发送内联图像。
评论
<img src="URL" />