Einbetten des Bildes in eine HTML-E-Mail

113

Ich versuche, eine mehrteilige / verwandte HTML-E-Mail mit eingebetteten GIF-Bildern zu senden. Diese E-Mail wird mit Oracle PL / SQL generiert. Meine Versuche sind fehlgeschlagen. Das Bild wird als rotes X angezeigt (in Outlook 2007 und Yahoo Mail).

Ich habe seit einiger Zeit HTML-E-Mails gesendet, aber meine Anforderungen sind jetzt, mehrere GIF-Bilder in der E-Mail zu verwenden. Ich kann diese auf einem unserer Webserver speichern und nur mit ihnen verknüpfen, aber viele Benutzer-E-Mail-Clients zeigen sie nicht automatisch an und müssen entweder die Einstellungen ändern oder sie für jede E-Mail manuell herunterladen.

Meine Gedanken sind also, das Bild einzubetten. Meine Fragen sind:

  1. Was mache ich hier falsch?
  2. Ist der Einbettungsansatz der richtige?
  3. Gibt es noch andere Optionen, wenn ich immer mehr Bilder verwenden muss? Anhänge funktionieren nicht, da es sich bei den Bildern normalerweise um Logos und Symbole handelt, die aus dem Kontext der Nachricht keinen Sinn ergeben. Außerdem sind einige Elemente der E-Mail Links zu einem Online-System, sodass das Generieren einer statischen PDF-Datei und das Anhängen nicht funktionieren (meines Wissens nach).

Ausschnitt:

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

Danke vielmals.

Übrigens: Ja, ich habe überprüft, ob die base64-Daten korrekt sind, da ich das Bild in das HTML selbst einbetten kann (unter Verwendung derselben Algo-Verwendung zum Erstellen von Header-Daten) und das Bild in Firefox / IE anzeigen kann.

Ich sollte auch beachten, dass dies NICHT für Spam ist, die E-Mails werden an bestimmte Kunden gesendet, die es täglich erwarten. Der Inhalt ist datengesteuert und keine Werbung.

Knochen
quelle
Kurze Frage: Hosten Sie diese Bilder außerhalb des Standorts oder binden Sie sie direkt in die E-Mail ein?
JonLim
Ein Teil meiner Frage kann ich auch. Ich versuche hier, sie einzubetten, aber nicht erfolgreich. Wenn ich nur auf sie verlinke, sehen viele Benutzer die Bilder nicht, ohne sie zuerst herunterzuladen, was ich vermeiden möchte.
Knochen
1
Ein Stammgast <img src="URL" />arbeitete für mich, aber es war ein Bild, das ich außerhalb des Unternehmens gehostet habe. Das funktioniert bei dir nicht
JonLim
"funktioniert" ist subjektiv ... ja, es funktioniert, wenn der Benutzer bereit ist, die Bilder jedes Mal herunterzuladen, aber ich möchte das vermeiden und das Bild einbetten.
Knochen
1
@ JonLim: Danke, dass du dich damit befasst hast. Siehe meine Kommentare in der Antwort für das, was mir gefehlt hat.
Knochen

Antworten:

139

Versuchen Sie, es direkt einzufügen. Auf diese Weise können Sie mehrere Bilder an verschiedenen Stellen in die E-Mail einfügen.

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

Und um diesen Beitrag für andere nützlich zu machen: Wenn Sie keine Base64-Datenzeichenfolge haben, erstellen Sie einfach eine unter: http://www.motobit.com/util/base64-decoder-encoder.asp aus einer Bilddatei .

E-Mail-Quellcode sieht ungefähr so ​​aus, aber ich kann Ihnen wirklich nicht sagen, wofür diese Grenzsache ist:

 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: Oh, ich merke nur, wenn du das erste Code-Snippet aus meinem Beitrag einfügst, um eine E-Mail mit Thunderbird zu schreiben, ändert Thunderbird den HTML-Code automatisch so, dass er fast genauso aussieht wie der zweite Code in meinem Beitrag.

Bernd
quelle
5
Ich habe es zuerst versucht, es funktioniert bei mir nicht für E-Mails. funktioniert gut für die Anzeige in IE / Firefox, wird aber nicht als E-Mail gesendet.
Knochen
Vielleicht kennen Sie einen Weg (was wäre der Inhaltstyp? Text / HTML? Die E-Mail-Header, die ich wissen müsste, um eine gemischte HTML / Bild-Datei auf diese Weise zu senden)
tbone
1
@Zesty benutze @ [Benutzername], um jemanden zu benachrichtigen, habe gerade deine Frage gesehen. Ich benutze utl_smtp. Für mich musste ich einen Clob mit dem HTML-Body, den Grenzen usw. erstellen und dann über utl_smtp senden. Ein einfaches Beispiel finden Sie hier: oracle-base.com/articles/misc/EmailFromOraclePLSQL.php Beachten Sie, dass dieser Link keinen Ansatz für eingebettete Bilder zeigt, sondern Details enthält, die Sie zum Laufen bringen.
Knochen
40
Daten - URIs in E - Mails werden nicht in vielen Mainstream - Clients unterstützt und sollte nicht verwendet werden, finden Sie unter : campaignmonitor.com/blog/post/3927/...
Michael Böckling
2
Es scheint nicht in hotmail / icloud zu funktionieren = (habe ich etwas verpasst
hsb1007
21

Die andere Lösung besteht darin, das Bild als Anhang anzuhängen und dann mit cid auf den HTML-Code zu verweisen.

HTML Quelltext:

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

C # -Code:

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();
Khyati Elhance
quelle
11

Ich finde keine der Antworten hier nützlich, daher biete ich meine Lösung an.

  1. Das Problem ist, dass Sie multipart/relatedals Inhaltstyp verwenden, was in diesem Fall nicht gut ist. Ich benutze multipart/mixedund drin multipart/alternative(es funktioniert auf den meisten Clients).

  2. Die Nachrichtenstruktur sollte wie folgt aussehen:

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

Dann wird es funktionieren

Pavel Perna
quelle
Kämpfe mit diesem. Ich habe genau wie oben codiert, aber das Bild wird nicht angezeigt (nur ein Rahmen mit dem Alternativtext; der Text funktioniert einwandfrei). Meine Inhalts-ID ist <filename.jpg>, also meine href = "cid: filename.jpg" - gibt es einen besonderen Trick für den Wert oder die Syntax von Content-ID und cid :?
Peter Flynn
Ich habe mit RFC2392 nachgefragt und der CID-Ausdruck scheint gültig zu sein. Aber es wird immer noch nicht angezeigt.
Peter Flynn
Ich schrieb eine Antwort auf eine ähnliche Frage und erstellte eine ASCII-Kunst, um die Struktur zu erklären: stackoverflow.com/a/40420648/633961
guettli
4

Die Verwendung von Base64 zum Einbetten von Bildern in HTML ist fantastisch. Beachten Sie jedoch, dass Base64-Zeichenfolgen Ihre E-Mail-Größe vergrößern können.

Deshalb,

1) Wenn Sie viele Bilder haben, kann das Hochladen Ihrer Bilder auf einen Server und das Laden dieser Bilder vom Server Ihre E-Mail-Größe verringern. (Sie können viele kostenlose Dienste über Google erhalten)

2) Wenn Ihre E-Mail nur wenige Bilder enthält, ist die Verwendung von base64-Zeichenfolgen definitiv eine großartige Option.

Neben den Auswahlmöglichkeiten, die durch vorhandene Antworten bereitgestellt werden, können Sie auch einen Befehl verwenden, um eine Base64-Zeichenfolge unter Linux zu generieren:

base64 test.jpg
Brian
quelle
Michael Böckling wies darauf hin: Daten-URIs in E-Mails werden von vielen Mainstream-Clients wie Google Mail nicht unterstützt
Mendy
3

Ich weiß, dass dies ein alter Beitrag ist, aber die aktuellen Antworten berücksichtigen nicht die Tatsache, dass Outlook und viele andere E-Mail-Anbieter keine Inline-Bilder oder CID-Bilder unterstützen. Der effektivste Weg, Bilder in E-Mails zu platzieren, besteht darin, sie online zu hosten und einen Link dazu in die E-Mail zu setzen. Bei kleinen E-Mail-Listen funktioniert eine öffentliche Dropbox einwandfrei. Dies hält auch die E-Mail-Größe niedrig.

Roller Crawford
quelle
2
  1. Sie benötigen 3 Grenzen, damit Inline-Bilder vollständig kompatibel sind.

  2. Alles geht in die multipart/mixed.

  3. Verwenden Sie dann die multipart/related, um Ihre multipart/alternativeund Ihre Bildanhang-Header zu enthalten .

  4. Zuletzt fügen Sie Ihre herunterladbaren Anhänge innerhalb der letzten Grenze von multipart/mixed.

Steven Newman
quelle
11
Es wäre hilfreich, wenn Sie ein Beispiel hinzufügen.
Makyen
7
Noch nützlicher wäre ein Verweis auf die Spezifikation.
Jbruni
2

Es gibt tatsächlich einen sehr guten Blog-Beitrag, der die Vor- und Nachteile von drei verschiedenen Ansätzen für dieses Problem von Martyn Davies auflistet. Sie können es unter https://sendgrid.com/blog/embedding-images-emails-facts/ lesen .

Ich möchte einen vierten Ansatz mit CSS-Hintergrundbildern hinzufügen.

Hinzufügen

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

an Ihren E-Mail-Text und eine CSS-Klasse wie:

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

Für diejenigen, die eine dieser Lösungen nicht zum Laufen bringen konnten: Inline-Bild per E-Mail senden Nach den in der von @ T30 angebotenen Lösung beschriebenen Schritten konnte ich mein Inline-Bild anzeigen lassen, ohne von Outlook blockiert zu werden (frühere Methoden wurden blockiert). . Wenn Sie Exchange wie wir verwenden, dann auch, wenn Sie Folgendes tun:

service = new ExchangeService(ExchangeVersion);
service.AutodiscoverUrl("[email protected]");
SmtpClient smtp = new SmtpClient(service.Url.Host);

Sie müssen es Ihrem Exchange-Service-URL-Host übergeben. Abgesehen davon sollten Sie nach dieser Lösung problemlos eingebettete Bilder senden können.

tstrand66
quelle
1

Es kann von Interesse sein, dass sowohl Outlook als auch Outlook Express diese mehrteiligen Bild-E-Mail-Formate generieren können, wenn Sie die Bilddateien über die Menüfunktion Einfügen / Bild einfügen.

Offensichtlich muss der E-Mail-Typ auf HTML (kein einfacher Text) eingestellt sein.

Jede andere Methode (z. B. Drag & Drop oder Befehlszeilenaufruf) führt dazu, dass die Bilder als Anhang gesendet werden.

Wenn Sie sich dann eine solche E-Mail senden, können Sie sehen, wie sie formatiert ist! :) :)

FWIW, ich suche nach einer eigenständigen ausführbaren Windows-Datei, die Inline-Bilder aus dem Befehlszeilenmodus ausführt, aber es scheint keine zu geben. Es ist ein Pfad, den viele gegangen sind ... Man kann es mit Outlook Express tun, indem man ihm eine entsprechend formatierte EML-Datei übergibt.

Peter
quelle
0

Das Folgende ist Arbeitscode mit zwei Möglichkeiten, um dies zu erreichen:

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

Ein zusätzlicher Hinweis zu Pavel Pernas Beitrag, der mir sehr geholfen hat (kann nicht mit meinem Ruf kommentieren, deshalb poste ich dies als Antwort): In einigen Versionen von Microsoft Exchange wird die Inline-Inhaltsdisposition entfernt ( siehe diesen Beitrag von Microsoft ). Das Bild ist einfach nicht Teil der E-Mail, die der Benutzer in Outlook sieht. Verwenden Sie zur Problemumgehung stattdessen "Content-Disposition: Anhang". Outlook 2016 zeigt keine Bilder als Anhang an, die in der E-Mail-Nachricht verwendet werden, obwohl sie die "Inhaltsdisposition: Anhang" verwenden.

Klendatho
quelle
-30

Wenn Sie mit Outlook ein statisches Bild mit Hyperlink senden, können Sie auf einfache Weise Word verwenden.

  1. Öffnen Sie MS Word
  2. Kopieren Sie das Bild auf eine leere Seite
  3. Hyperlink zum Bild hinzufügen (Strg + K)
  4. Kopieren Sie das Bild in Ihre E-Mail
Claudio Viz
quelle