在html电子邮件中嵌入图像

时间:2011-07-15 12:23:13

标签: html image oracle email mime

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

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

所以,我的想法是嵌入图像。我的问题是:

  1. 我在这里做错了什么?
  2. 嵌入方法是否正确?
  3. 如果我需要使用越来越多的图像,还有其他选择吗?附件不起作用,因为图像通常是徽标和图标,这些图标和图标在消息的上下文中无法理解。此外,电子邮件的某些元素是指向在线系统的链接,因此生成静态PDF和附加将无效(据我所知)。
  4. 片段:

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

    非常感谢。

    BTW:是的,我已经验证了base64数据是正确的,因为我可以将图像嵌入到html本身(使用相同的algo用于创建标题数据)并在Firefox / IE中查看图像。

    我还应该注意,这不是针对垃圾邮件,而是将电子邮件发送给每天都在期待的特定客户。内容是数据驱动的,而不是广告。

14 个答案:

答案 0 :(得分:121)

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

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

//编辑:哦,我只是意识到如果你从我的帖子中插入第一个代码片段来写一封带有thunderbird的电子邮件,thunderbird会自动更改html代码,看起来和我帖子中的第二个代码差不多。 / p>

答案 1 :(得分:15)

另一个解决方案是将图像作为附件附加,然后使用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();

答案 2 :(得分:9)

我发现这里没有任何答案有用,所以我提供了解决方案。

  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--
    
  3. 然后它会起作用

答案 3 :(得分:6)

如果它不起作用,您可以尝试使用这些工具之一将图像转换为HTML表格(请注意图像的大小):

答案 4 :(得分:4)

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

因此,

1)如果您有许多图像,将图像上传到服务器并从服务器加载这些图像可以使您的电子邮件大小更小。 (您可以通过Google获得大量免费服务)

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

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

base64 test.jpg

答案 5 :(得分:2)

  1. 内联图片需要3个边界才能完全合规。

  2. 所有内容都在multipart/mixed

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

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

答案 6 :(得分:2)

对于无法获得以下解决方案之一的用户: Send inline image in email 按照@ T30提供的解决方案中列出的步骤,我能够显示我的嵌入式图像,而不会被外观所阻挡(以前的方法已被阻挡)。如果您像我们一样在使用交换,那么在进行操作时:

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

您将需要将其交换服务URL主机传递给它。除了遵循该解决方案之外,还可以使您轻松发送嵌入式图像。

答案 7 :(得分:2)

我知道这是一篇过时的文章,但是当前的答案并未解决Outlook和许多其他电子邮件提供商不支持嵌入式图像或CID图像的事实。将图像放置在电子邮件中最有效的方法是在线托管图像并将其链接放置在电子邮件中。对于较小的电子邮件列表,可以使用公共投递箱。这也可以减小电子邮件的大小。

答案 8 :(得分:1)

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

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

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

如果您随后向自己发送此类电子邮件,则可以查看其格式! :)

FWIW,我正在寻找一个独立的Windows可执行文件,它可以从命令行模式执行内嵌图像,但似乎没有。它是许多已经上升的路径......可以通过传递适当格式化的.eml文件来说明Outlook Express。

答案 9 :(得分:1)

实际上,这是一篇非常好的博客文章,列出了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];
}

答案 10 :(得分:0)

以下是具有两种实现方式的工作代码:

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();
        }
    }
}

答案 11 :(得分:0)

Pavel Perna帖子的另一个提示对我很有帮助(无法评论我的声誉,这就是为什么我将其发布为答案):在某些版本的Microsoft Exchange中,删除了内联内容处理(see this post by Microsoft )。该图像根本不属于用户在Outlook中看到的邮件中。解决方法是改用“ Content-Disposition:附件”。尽管Outlook 2016使用“内容处置:附件”,但它们不会将邮件中显示的图像显示为附件。

答案 12 :(得分:0)

尝试使用Context.Request解决该问题:

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

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

答案 13 :(得分:-20)

如果您使用Outlook发送带超链接的静态图像,一种简单的方法是使用Word。

  1. 打开MS Word
  2. 将图像复制到空白页
  3. 向图像添加超链接(Ctrl + K)
  4. 将图片复制到您的电子邮件