intégration d'une image dans un e-mail html

113

J'essaie d'envoyer un e-mail html en plusieurs parties / associé avec des images gif intégrées. Cet e-mail est généré à l'aide d'Oracle PL / SQL. Mes tentatives ont échoué, l'image s'affichant sous la forme d'un X rouge (dans Outlook 2007 et Yahoo Mail)

J'envoie des e-mails html depuis un certain temps, mais mes exigences sont maintenant d'utiliser plusieurs images gif dans l'e-mail. Je peux les stocker sur l'un de nos serveurs Web et simplement les relier, mais de nombreux utilisateurs de clients de messagerie ne les afficheront pas automatiquement et devront soit modifier les paramètres, soit les télécharger manuellement pour chaque e-mail.

Donc, mes pensées sont d'intégrer l'image. Mes questions sont:

  1. Qu'est-ce que je fais de mal ici?
  2. L'approche d'intégration est-elle la bonne?
  3. Y a-t-il d'autres options si j'ai besoin d'utiliser de plus en plus d'images? Les pièces jointes ne fonctionneront pas, car les images sont généralement des logos et des icônes qui n'auront aucun sens hors du contexte du message. De plus, certains éléments de l'e-mail sont des liens vers un système en ligne, donc générer un PDF statique et l'attacher ne fonctionnera pas (à ma connaissance de toute façon).

fragment:

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

Merci beaucoup.

BTW: Oui, j'ai vérifié que les données base64 sont correctes, car je peux intégrer l'image dans le html lui-même (en utilisant la même utilisation d'algo pour créer des données d'en-tête) et voir l'image dans Firefox / IE.

Je dois également noter que ce n'est PAS pour le spam, les e-mails sont envoyés à des clients spécifiques qui l'attendent quotidiennement. Le contenu est basé sur les données et non sur les publicités.

tbone
la source
Question rapide: hébergez-vous ces images hors site ou les intégrez-vous directement dans l'e-mail?
JonLim
Une partie de ma question vraiment, je peux faire l'un ou l'autre. J'essaye ici de les intégrer, mais sans succès. Si je me connecte simplement à eux, de nombreux utilisateurs ne verront pas les images sans les télécharger au préalable, ce que j'aimerais éviter.
tbone
1
Un habitué a <img src="URL" />fonctionné pour moi, mais c'était une image que j'ai hébergée hors site. Cela ne fonctionne pas pour vous?
JonLim
"fonctionne" est subjectif ... oui, cela fonctionne si l'utilisateur est prêt à télécharger les images à chaque fois, mais j'aimerais éviter cela et intégrer l'image.
tbone le
1
@JonLim: merci d'avoir regardé dedans, voir mes commentaires dans la réponse pour ce qui me manquait.
tbone le

Réponses:

139

Essayez de l'insérer directement, de cette façon, vous pouvez insérer plusieurs images à différents endroits dans l'e-mail.

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

Et pour rendre cet article utile aux autres: Si vous n'avez pas de chaîne de données base64, créez-en une facilement à l'adresse: adresse http://www.motobit.com/util/base64-decoder-encoder.asp à partir d'un fichier image .

Le code source de l'e-mail ressemble à ceci, mais je ne peux vraiment pas vous dire à quoi sert cette limite:

 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, je me rends compte que si vous insérez le premier extrait de code de mon message pour écrire un e-mail avec thunderbird, thunderbird change automatiquement le code html pour qu'il ressemble à peu près au deuxième code de mon message.

Bernd
la source
5
essayé cela en premier, cela ne fonctionne pas pour moi pour le courrier électronique. fonctionne bien pour l'affichage dans IE / Firefox, mais pas envoyé par e-mail.
tbone le
Peut-être connaissez-vous un moyen (quel serait le type de contenu? Text / html? Les en-têtes de courrier électronique que j'aurais besoin de savoir pour envoyer un fichier mixte html / image de cette façon)
tbone
1
@Zesty utilise @ [nom d'utilisateur] pour alerter quelqu'un, vient de voir votre question. J'utilise utl_smtp. Pour moi, je devais créer un clob avec le corps html, les limites, etc., puis l'envoyer via utl_smtp. Voir ici pour un exemple simple: oracle-base.com/articles/misc/EmailFromOraclePLSQL.php Notez que ce lien ne montre pas l'approche des images intégrées, mais contient des détails pour vous aider.
tbone
41
Les URI de données dans les e-mails ne sont pas pris en charge dans de nombreux clients grand public et ne doivent pas être utilisés, voir: campaignmonitor.com/blog/post/3927/…
Michael Böckling
2
Cela ne semble pas fonctionner dans hotmail / icloud = (ai-je raté quelque chose
hsb1007
22

L'autre solution consiste à attacher l'image en tant que pièce jointe, puis à la référencer du code html à l'aide de cid.

Code HTML:

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

Code 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();
Khyati Elhance
la source
11

Je ne trouve aucune des réponses utiles ici, donc je propose ma solution.

  1. Le problème est que vous utilisez multipart/relatedcomme type de contenu ce qui n'est pas bon dans ce cas. J'utilise multipart/mixedet à l'intérieurmultipart/alternative (cela fonctionne sur la plupart des clients).

  2. La structure du message doit être la suivante:

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

Alors ça fonctionnera

Pavel Perna
la source
Lutte sur celui-ci. J'ai codé exactement comme ci-dessus, mais l'image n'apparaît pas (juste un cadre avec le texte alternatif; le texte fonctionne bien). Mon Content-ID est <filename.jpg> donc mon href = "cid: filename.jpg" - y a-t-il une astuce spéciale pour la valeur ou la syntaxe de Content-ID et cid:?
Peter Flynn
J'ai vérifié avec RFC2392 et l'expression CID semble être valide. Mais cela ne s'affiche toujours pas.
Peter Flynn
J'ai écrit une réponse à une question similaire et créé un art ascii pour expliquer la structure: stackoverflow.com/a/40420648/633961
guettli
4

Utiliser Base64 pour incorporer des images en HTML est génial. Néanmoins, veuillez noter que les chaînes base64 peuvent augmenter la taille de votre e-mail.

Par conséquent,

1) Si vous avez beaucoup d'images, le téléchargement de vos images sur un serveur et le chargement de ces images à partir du serveur peut réduire la taille de votre e-mail. (Vous pouvez obtenir de nombreux services gratuits via Google)

2) S'il n'y a que quelques images dans votre courrier, l'utilisation de chaînes base64 est certainement une option géniale.

Outre les choix fournis par les réponses existantes, vous pouvez également utiliser une commande pour générer une chaîne base64 sous Linux:

base64 test.jpg
Brian
la source
Souligné par Michael Böckling: les URI de données dans les e-mails ne sont pas pris en charge dans de nombreux clients grand public comme gmail
Mendy
3

Je sais que c'est un ancien message, mais les réponses actuelles ne traitent pas du fait que Outlook et de nombreux autres fournisseurs de messagerie ne prennent pas en charge les images en ligne ou les images CID. Le moyen le plus efficace de placer des images dans des e-mails est de les héberger en ligne et de placer un lien vers ces images dans l'e-mail. Pour les petites listes de diffusion, une boîte de dépôt publique fonctionne très bien. Cela réduit également la taille de l'e-mail.

Scooter Crawford
la source
2
  1. Vous avez besoin de 3 limites pour que les images en ligne soient entièrement conformes.

  2. Tout va à l'intérieur du multipart/mixed.

  3. Utilisez ensuite le multipart/relatedpour contenir vos en multipart/alternative-têtes et vos en-têtes de pièce jointe d'image.

  4. Enfin, incluez vos pièces jointes téléchargeables dans la dernière limite de multipart/mixed.

Steven Newman
la source
11
Il serait utile que vous incluiez un exemple.
Makyen
7
Une référence à la spécification serait encore plus utile.
jbruni
2

Il existe en fait un très bon article de blog qui répertorie les avantages et les inconvénients de trois approches différentes de ce problème par Martyn Davies. Vous pouvez le lire sur https://sendgrid.com/blog/embedding-images-emails-facts/ .

J'aimerais ajouter une quatrième approche utilisant des images de fond CSS.

Ajouter

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

au corps de votre e-mail et à une classe css comme:

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

Pour ceux qui n'ont pas pu faire fonctionner l'une de ces solutions: Envoyer une image en ligne par e-mail En suivant les étapes décrites dans la solution proposée par @ T30, j'ai pu afficher mon image en ligne sans être bloquée par Outlook (méthodes précédentes, elle était bloquée) . Si vous utilisez l'échange comme nous le faisons, alors aussi lorsque vous faites:

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

vous devrez lui transmettre l'hôte de l'URL de votre service d'échange. Autre que cela, cette solution devrait vous permettre d'envoyer facilement des images intégrées.

tstrand66
la source
1

Il peut être intéressant qu'Outlook et Outlook Express puissent générer ces formats de courrier électronique d'images en plusieurs parties, si vous insérez les fichiers image à l'aide de la fonction de menu Insérer / Image.

De toute évidence, le type d'e-mail doit être défini sur HTML (et non sur du texte brut).

Toute autre méthode (par exemple, glisser / déposer ou tout appel de ligne de commande) entraîne l'envoi de l'image ou des images en pièce jointe.

Si vous vous envoyez ensuite un tel e-mail, vous pouvez voir comment il est formaté! :)

FWIW, je recherche un exécutable Windows autonome qui fait des images en ligne à partir du mode ligne de commande, mais il semble n'y en avoir aucun. C'est un chemin que beaucoup ont emprunté ... On peut le faire avec par exemple Outlook Express, en lui passant un fichier .eml correctement formaté.

Peter
la source
0

Ce qui suit est un code de travail avec deux façons d'y parvenir:

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
la source
0

Un indice supplémentaire à l'article de Pavel Perna qui m'a beaucoup aidé (je ne peux pas commenter ma réputation, c'est pourquoi je poste ceci comme réponse): dans certaines versions de Microsoft Exchange, la disposition du contenu en ligne est supprimée ( voir cet article de Microsoft ). L'image ne fait tout simplement pas partie du courrier que l'utilisateur voit dans Outlook. Pour contourner ce problème, utilisez plutôt "Content-Disposition: attachement". Outlook 2016 n'affichera pas les images en tant que pièce jointe qui sont utilisées dans le message électronique, bien qu'elles utilisent le «Content-Disposition: attachement».

Klendatho
la source
-30

Si vous utilisez Outlook pour envoyer une image statique avec un lien hypertexte, un moyen simple serait d'utiliser Word.

  1. Ouvrez MS Word
  2. Copiez l'image sur une page vierge
  3. Ajouter un lien hypertexte à l'image (Ctrl + K)
  4. Copiez l'image dans votre e-mail
Claudio Viz
la source