nhúng hình ảnh vào email html


113

Tôi đang cố gửi một email html nhiều phần / có liên quan với hình ảnh gif được nhúng. Email này được tạo bằng Oracle PL / SQL. Nỗ lực của tôi không thành công, với hình ảnh hiển thị dưới dạng dấu X màu đỏ (trong Outlook 2007 và yahoo mail)

Tôi đã gửi email html một thời gian, nhưng yêu cầu của tôi bây giờ là sử dụng một số hình ảnh gif trong email. Tôi có thể lưu trữ chúng trên một trong các máy chủ web của chúng tôi và chỉ liên kết đến chúng, nhưng nhiều người dùng ứng dụng email khách sẽ không tự động hiển thị chúng và sẽ cần phải thay đổi cài đặt hoặc tải xuống thủ công cho từng email.

Vì vậy, suy nghĩ của tôi là nhúng hình ảnh. Câu hỏi của tôi là:

  1. Tôi làm gì sai ở đây?
  2. Cách tiếp cận nhúng có đúng không?
  3. Bất kỳ tùy chọn nào khác nếu tôi cần sử dụng ngày càng nhiều hình ảnh? Tệp đính kèm sẽ không hoạt động, vì hình ảnh thường là biểu trưng và biểu tượng sẽ không có ý nghĩa ngoài ngữ cảnh của thông báo. Ngoài ra, một số yếu tố của email là các liên kết đến một hệ thống trực tuyến, vì vậy việc tạo một tệp PDF tĩnh và đính kèm sẽ không hoạt động (theo hiểu biết của tôi).

đoạn mã:

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

Cảm ơn nhiều.

BTW: Có, tôi đã xác minh rằng dữ liệu base64 là chính xác, vì tôi có thể nhúng hình ảnh vào chính html (sử dụng thuật ngữ tương tự để tạo dữ liệu tiêu đề) và xem hình ảnh trong Firefox / IE.

Tôi cũng cần lưu ý rằng điều này KHÔNG dành cho thư rác, các email được gửi đến những khách hàng cụ thể đang mong đợi nó hàng ngày. Nội dung theo hướng dữ liệu và không phải quảng cáo.


Câu hỏi nhanh: bạn đang lưu trữ những hình ảnh này ngoài trang web hay nhúng chúng trực tiếp vào email?
JonLim

Một phần của câu hỏi của tôi thực sự, tôi có thể làm một trong hai. Tôi cố gắng nhúng chúng ở đây, nhưng không thành công. Nếu tôi chỉ liên kết đến chúng, nhiều người dùng sẽ không nhìn thấy hình ảnh nếu không tải chúng xuống trước, điều mà tôi muốn tránh.
tbone

1
Một thông thường <img src="URL" />làm việc cho tôi, nhưng đó là một hình ảnh mà tôi lưu trữ bên ngoài trang web. Điều đó không hiệu quả với bạn?
JonLim

"hoạt động" là chủ quan ... vâng, nó hoạt động nếu người dùng sẵn sàng tải xuống hình ảnh mỗi lần, nhưng tôi muốn tránh điều đó và nhúng hình ảnh.
tbone

1
@JonLim: cảm ơn vì đã xem xét nó, hãy xem nhận xét của tôi trong câu trả lời cho những gì tôi còn thiếu.
tbone

Câu trả lời:


139

Cố gắng chèn trực tiếp, bằng cách này bạn có thể chèn nhiều hình ảnh ở nhiều vị trí khác nhau trong email.

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

Và để làm cho bài đăng này hữu ích cho những người khác: Nếu bạn không có chuỗi dữ liệu base64, hãy tạo một chuỗi dễ dàng tại: http://www.motobit.com/util/base64-decoder-encoder.asp từ tệp hình ảnh .

Mã nguồn email trông giống như thế này, nhưng tôi thực sự không thể cho bạn biết ranh giới đó dùng để làm gì:

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

// CHỈNH SỬA: Ồ, tôi chỉ nhận ra nếu bạn chèn đoạn mã đầu tiên từ bài đăng của tôi để viết email bằng Thunderbird, thì Thunderbird sẽ tự động thay đổi mã html để trông khá giống với mã thứ hai trong bài đăng của tôi.


5
đã thử cái này trước, nó không hoạt động với tôi cho email. hoạt động tốt để xem trong IE / Firefox, nhưng không được gửi dưới dạng email.
tbone

Có lẽ u biết một chiều (điều gì sẽ loại nội dung là văn bản / html các tiêu đề email tôi cần phải biết để gửi một html / hình ảnh tập tin hỗn hợp theo cách này?)
tbone

1
@Zesty sử dụng @ [tên người dùng] để cảnh báo ai đó, vừa xem câu hỏi của bạn. Tôi sử dụng utl_smtp. Đối với tôi, tôi phải tạo một bản dựng với nội dung html, ranh giới, v.v. và sau đó gửi qua utl_smtp. Xem ví dụ đơn giản ở đây: oracle-base.com/articles/misc/EmailFromOraclePLSQL.php Lưu ý rằng liên kết này không hiển thị cách tiếp cận hình ảnh nhúng, nhưng có chi tiết để giúp bạn thực hiện.
tbone

41
Dữ liệu URI trong email không được hỗ trợ trong nhiều khách hàng chủ đạo và không nên được sử dụng, xem: campaignmonitor.com/blog/post/3927/...
Michael Böckling

2
Nó dường như không làm việc trong hotmail / icloud = (Tôi đã bỏ lỡ bất cứ điều gì
hsb1007

21

Giải pháp khác là đính kèm hình ảnh dưới dạng tệp đính kèm và sau đó tham chiếu nó bằng mã html bằng cid.

Mã HTML:

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

Mã 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();

11

Tôi không tìm thấy bất kỳ câu trả lời nào ở đây hữu ích, vì vậy tôi đang cung cấp giải pháp của mình.

  1. Vấn đề là bạn đang sử dụng multipart/relatedlàm loại nội dung không tốt trong trường hợp này. Tôi đang sử dụng multipart/mixedvà bên trong nó multipart/alternative(nó hoạt động trên hầu hết các khách hàng).

  2. Cấu trúc thông báo phải như sau:

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

Sau đó nó sẽ hoạt động


Đấu tranh với cái này. Tôi đã viết mã chính xác như trên, nhưng hình ảnh không xuất hiện (chỉ là một khung với văn bản thay thế; văn bản hoạt động tốt). Content-ID của tôi là <filename.jpg> nên href = "cid: filename.jpg" của tôi - có một số thủ thuật đặc biệt đối với giá trị hoặc cú pháp của Content-ID và cid:?
Peter Flynn

Tôi đã kiểm tra với RFC2392 và biểu thức CID có vẻ hợp lệ. Nhưng nó vẫn không hiển thị.
Peter Flynn

Tôi đã viết một câu trả lời cho một câu hỏi tương tự và tạo ra một nghệ thuật ascii để giải thích cấu trúc: stackoverflow.com/a/40420648/633961
guettli


4

Sử dụng Base64 để nhúng hình ảnh vào html thật tuyệt vời. Tuy nhiên, hãy lưu ý rằng chuỗi base64 có thể làm cho kích thước email của bạn lớn.

Vì thế,

1) Nếu bạn có nhiều hình ảnh, tải hình ảnh của bạn lên máy chủ và tải những hình ảnh đó từ máy chủ có thể làm cho kích thước email của bạn nhỏ hơn. (Bạn có thể nhận được rất nhiều dịch vụ miễn phí qua Google)

2) Nếu chỉ có một vài hình ảnh trong thư của bạn, sử dụng chuỗi base64 chắc chắn là một lựa chọn tuyệt vời.

Bên cạnh các lựa chọn được cung cấp bởi các câu trả lời hiện có, bạn cũng có thể sử dụng lệnh để tạo chuỗi base64 trên linux:

base64 test.jpg

Chỉ ra bởi Michael Böckling: URI dữ liệu trong email không được hỗ trợ trong nhiều ứng dụng khách chính như gmail
Mendy

3

Tôi biết đây là một bài đăng cũ, nhưng các câu trả lời hiện tại không giải quyết được thực tế là outlook và nhiều nhà cung cấp email khác không hỗ trợ hình ảnh nội tuyến hoặc hình ảnh CID. Cách hiệu quả nhất để đặt hình ảnh trong email là lưu trữ nó trực tuyến và đặt một liên kết đến nó trong email. Đối với danh sách email nhỏ, hộp kéo công khai hoạt động tốt. Điều này cũng giúp giảm kích thước email.


2
  1. Bạn cần có 3 ranh giới để hình ảnh nội tuyến hoàn toàn tuân thủ.

  2. Mọi thứ đi vào bên trong multipart/mixed.

  3. Sau đó, sử dụng multipart/relatedđể chứa multipart/alternativetiêu đề tệp đính kèm hình ảnh của bạn và của bạn.

  4. Cuối cùng, bao gồm các tệp đính kèm có thể tải xuống của bạn bên trong ranh giới cuối cùng của multipart/mixed.


11
Sẽ rất hữu ích nếu bạn bao gồm một ví dụ.
Makyen

7
Thậm chí hữu ích hơn sẽ là một tham chiếu đến thông số kỹ thuật.
jbruni

2

Thực sự có một bài đăng trên blog rất hay liệt kê những ưu và khuyết điểm của ba cách tiếp cận khác nhau đối với vấn đề này của Martyn Davies. Bạn có thể đọc nó tại https://sendgrid.com/blog/embedding-images-emails-facts/ .

Tôi muốn thêm cách tiếp cận thứ tư bằng cách sử dụng hình nền CSS.

Thêm vào

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

vào nội dung e-mail của bạn và một lớp css như:

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

2

Đối với những người không thể nhận được một trong những giải pháp này hoạt động: Gửi hình ảnh nội tuyến trong email Làm theo các bước được trình bày trong giải pháp được cung cấp bởi @ T30, tôi đã có thể hiển thị hình ảnh nội tuyến của mình mà không bị chặn bởi outlook (các phương pháp trước đó nó đã bị chặn) . Nếu bạn đang sử dụng trao đổi như chúng tôi thì khi thực hiện:

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

bạn sẽ cần phải chuyển nó cho máy chủ url dịch vụ trao đổi của bạn. Ngoài ra, giải pháp này sẽ cho phép bạn dễ dàng gửi các hình ảnh nhúng.


1

Có thể quan tâm rằng cả Outlook và Outlook Express đều có thể tạo các định dạng email hình ảnh nhiều phần này, nếu bạn chèn tệp hình ảnh bằng chức năng menu Chèn / Ảnh.

Rõ ràng là loại email phải được đặt thành HTML (không phải văn bản thuần túy).

Bất kỳ phương pháp nào khác (ví dụ: kéo / thả hoặc bất kỳ lệnh gọi dòng lệnh nào) dẫn đến (các) hình ảnh được gửi dưới dạng tệp đính kèm.

Nếu sau đó bạn gửi một email như vậy cho mình, bạn có thể thấy nó được định dạng như thế nào! :)

FWIW, tôi đang tìm kiếm một cửa sổ độc lập có thể thực thi được hình ảnh nội tuyến từ chế độ dòng lệnh, nhưng dường như không có. Đó là một con đường mà nhiều người đã đi lên ... Người ta có thể làm điều đó với Outlook Express, bằng cách chuyển cho nó một tệp .eml được định dạng thích hợp.


0

Sau đây là mã làm việc với hai cách để đạt được điều này:

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

0

Một gợi ý bổ sung cho bài đăng của Pavel Perna đã giúp tôi rất nhiều (không thể bình luận bằng danh tiếng của tôi, đó là lý do tại sao tôi đăng bài này như câu trả lời): Trong một số phiên bản của Microsoft Exchange, việc bố trí nội dung nội tuyến bị loại bỏ ( xem bài đăng này của Microsoft ). Hình ảnh đơn giản không phải là một phần trong thư mà người dùng nhìn thấy trong Outlook. Thay vào đó, hãy sử dụng "Nội dung-Bố trí: tệp đính kèm". Outlook 2016 sẽ không hiển thị hình ảnh dưới dạng tệp đính kèm được sử dụng trong thư, mặc dù chúng sử dụng "Nội dung-Bố trí: tệp đính kèm".


-30

Nếu bạn đang sử dụng Outlook để gửi một hình ảnh tĩnh với siêu liên kết, một cách dễ dàng sẽ là sử dụng Word.

  1. Mở MS Word
  2. Sao chép hình ảnh vào một trang trống
  3. Thêm siêu liên kết vào hình ảnh (Ctrl + K)
  4. Sao chép hình ảnh vào email của bạn
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.