вбудовування зображення в HTML-пошту


113

Я намагаюся надіслати багатоповерховий / пов’язаний HTML-лист із вбудованими зображеннями GIF. Цей електронний лист створюється за допомогою Oracle PL / SQL. Мої спроби не вдалися, оскільки зображення відображалося як червоний X (у Outlook 2007 та Yahoo Mail)

Я вже деякий час надсилаю 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--

Велике дякую.

BTW: Так, я перевірив правильність даних base64, оскільки я можу вставити зображення у сам html (використовуючи таке ж використання algo для створення даних заголовка) і побачити зображення у Firefox / IE.

Я також повинен зазначити, що це НЕ для спаму, електронні листи надсилаються конкретним клієнтам, які очікують цього щодня. Вміст керується даними, а не рекламою.


Швидке запитання: чи розміщуєте ви ці зображення поза сайтом чи вставляєте їх безпосередньо в електронний лист?
JonLim

Частина мого запитання дійсно, я можу зробити будь-яке. Я намагаюся тут вставити їх, але не вдало. Якщо я просто посилаюся на них, багато користувачів не побачать зображення, не завантажуючи їх спочатку, чого я хотів би уникнути.
tbone

1
Черговий <img src="URL" />працював для мене, але це був образ, який я розміщував поза сайтом. Це не працює для вас?
JonLim

"працює" суб'єктивно ... так, це працює, якщо користувач готовий завантажувати зображення щоразу, але я хотів би цього уникнути і вставити зображення.
tbone

1
@JonLim: дякую, що заглянув у цю відповідь, дивіться мої коментарі у відповіді на те, що я пропускав.
tbone

Відповіді:


139

Спробуйте вставити його безпосередньо, таким чином ви можете вставити кілька зображень у різних місцях електронної пошти.

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

// EDIT: О, я просто усвідомлюю, що якщо ви вставите перший фрагмент коду з моєї публікації, щоб написати електронний лист із thunderbird, thunderbird автоматично змінює html-код, щоб виглядати приблизно так само, як і другий код у моєму дописі.


5
спробував це спочатку, це не працює для мене електронною поштою. добре працює для перегляду в IE / Firefox, але не надсилається як електронний лист.
tbone

Можливо, ви знаєте спосіб (яким буде тип вмісту? Текст / html? Заголовки електронної пошти, які мені потрібно знати, щоб надіслати змішаний файл html / image таким чином)
tbone

1
@Zesty використовуйте @ [ім'я користувача], щоб попередити когось, щойно побачило ваше запитання. Я використовую utl_smtp. Для мене мені довелося створити збірку clob з html тілом, межами тощо, а потім надіслати через utl_smtp. Дивіться тут простий приклад: oracle-base.com/articles/misc/EmailFromOraclePLSQL.php Зверніть увагу, що це посилання не відображає підхід до вбудованих зображень, але має детальну інформацію, щоб вас продовжити.
tbone

41
URI-
адреси

2
Здається, це не працює в hotmail / icloud = (я щось пропустив
hsb1007

22

Іншим рішенням є приєднання зображення як вкладення, а потім посилання на нього html-код за допомогою cid.

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

11

Я не вважаю жодної відповіді тут корисною, тому я пропоную своє рішення.

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

Тоді це спрацює


Бореться за це. Я кодував саме так, як вище, але зображення не з’являється (просто кадр з текстом alt; текст працює чудово). Мій Content-ID - це <filename.jpg>, тому мій href = "cid: filename.jpg" - чи є якийсь спеціальний трюк зі значенням або синтаксисом Content-ID та cid:?
Пітер Флінн

Я перевірив RFC2392, і вираз CID видається дійсним. Але він все ще не відображається.
Пітер Флін

Я написав відповідь на подібне питання і створив мистецтво ASCii пояснити структуру: stackoverflow.com/a/40420648/633961
guettli

10

Якщо це не працює, ви можете спробувати один із цих інструментів, який перетворить зображення в таблицю HTML (однак остерігайтеся розміру зображення):


10
img2hmtl - це найсмішніше рішення / ідея, яку я бачив за деякий час. +1
Kristjan Liiva

4

Використання Base64 для вбудовування зображень у HTML є приголомшливим. Тим не менш, зауважте, що рядки base64 можуть збільшувати розмір вашої електронної пошти.

Тому

1) Якщо у вас багато зображень, завантаження зображень на сервер та завантаження цих зображень із сервера можуть зменшити розмір вашої електронної пошти. (Ви можете отримати багато безкоштовних послуг через Google)

2) Якщо у вашій пошті є лише кілька зображень, використання рядків base64 - це, безумовно, приголомшливий варіант.

Крім вибору, що надається наявними відповідями, ви також можете використовувати команду для генерації рядка base64 на Linux:

base64 test.jpg

Наголосив Майкл Бёклінг: URI-адреси даних в електронних листах не підтримуються у багатьох клієнтах, таких як gmail
Mendy

3

Я знаю, що це старе повідомлення, але поточні відповіді не стосуються того факту, що перспективи та багато інших постачальників електронної пошти не підтримують вбудовані зображення чи зображення CID. Найбільш ефективним способом розміщення зображень в електронних листах є розміщення його в Інтернеті та розміщення посилання на нього в електронній пошті. Для невеликих списків електронної пошти загальнодоступна скринька справді працює добре. Це також зменшує розмір електронної пошти.


2
  1. Вам потрібно 3 межі, щоб вбудовані зображення повністю відповідали.

  2. Все йде всередині multipart/mixed.

  3. Потім використовуйте, multipart/relatedщоб містити multipart/alternativeзаголовки вкладень та зображень.

  4. Нарешті, додайте вкладені файли для завантаження всередині останньої межі multipart/mixed.


11
Було б корисно, якщо ви включите приклад.
Makyen

7
Ще кориснішою буде посилання на специфікацію.
jbruni

2

Насправді є дуже хороша публікація в блозі, в якій перераховані професіонали та мінуси трьох різних підходів до цієї проблеми Мартіна Девіс. Ви можете прочитати його на 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];
}

2

Для тих, хто не зміг отримати одне з таких рішень: Надіслати вбудоване зображення електронною поштою Дотримуючись кроків, викладених у рішенні, запропонованому @ T30, я зміг отримати моє вбудоване зображення для відображення, не перекривши його перспективою (попередні методи було заблоковано) . Якщо ви використовуєте обмін, як і ми, тоді також робимо:

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

вам потрібно буде передати його хосту URL-адреси сервісу обміну. Крім цього, наступне рішення повинно дозволяти вам легко надсилати вбудовані зображення.


1

Можливо, буде цікаво, що і Outlook, і Outlook Express можуть створювати ці формати електронної пошти з декількома зображеннями, якщо ви вставляєте файли зображень за допомогою функції меню Вставити / Зображення.

Очевидно, що тип електронної пошти повинен бути встановлений у HTML (не звичайний текст).

Будь-який інший метод (наприклад, перетягування / падіння або виклик командного рядка) призводить до того, що зображення (и) надсилаються як вкладення.

Якщо ви надішліть собі такий електронний лист, ви зможете побачити, як він відформатований! :)

FWIW, я шукаю автономне виконуване вікно, яке робить вбудовані зображення з режиму командного рядка, але їх, здається, немає. Це шлях, який пройшов багато хто ... Можна зробити це за допомогою програми Outlook Express, передавши їй відповідний формат .eml-файлу.


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

0

Ще один натяк на пост Павла Перни, який дуже мені допоміг (не можу коментувати свою репутацію, тому я публікую це як відповідь): У деяких версіях Microsoft Exchange видалення вкладеного вмісту видаляється ( див. Цей пост від Microsoft ). Зображення просто не є частиною пошти, яку бачить користувач у Outlook. В якості вирішення замість цього використовуйте "Вміст-диспозиція: вкладення". Outlook 2016 не відображатиме зображення як вкладення, які використовуються у поштовому повідомленні, хоча вони використовують "Вміст-розпорядження: вкладення".


-30

Якщо ви використовуєте Outlook для надсилання статичного зображення з гіперпосиланням, простим способом було б використання Word.

  1. Відкрийте MS Word
  2. Скопіюйте зображення на порожню сторінку
  3. Додати гіперпосилання на зображення (Ctrl + K)
  4. Скопіюйте зображення на електронну пошту
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.