incorporare l'immagine nell'email html


113

Sto cercando di inviare un'e-mail HTML multiparte / correlata con immagini gif incorporate. Questa e-mail viene generata utilizzando Oracle PL / SQL. I miei tentativi sono falliti, con l'immagine che appare come una X rossa (in Outlook 2007 e yahoo mail)

Ho inviato e-mail html per un po 'di tempo, ma ora i miei requisiti sono di utilizzare diverse immagini gif nell'e-mail. Posso memorizzarli su uno dei nostri server web e collegarli semplicemente ad essi, ma molti client di posta elettronica degli utenti non li mostreranno automaticamente e dovranno modificare le impostazioni o scaricarli manualmente per ogni email.

Quindi, i miei pensieri sono di incorporare l'immagine. Le mie domande sono:

  1. Cosa sto facendo di sbagliato qui?
  2. L'approccio di incorporamento è quello corretto?
  3. Eventuali altre opzioni se devo utilizzare sempre più immagini? Gli allegati non funzioneranno, poiché le immagini sono in genere loghi e icone che non hanno senso dal contesto del messaggio. Inoltre, alcuni elementi dell'email sono collegamenti a un sistema online, quindi la generazione di un PDF statico e l'allegato non funzioneranno (per quanto ne so comunque).

frammento:

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

Grazie molto.

BTW: Sì, ho verificato che i dati di base64 siano corretti, poiché posso incorporare l'immagine nello stesso html (utilizzando lo stesso algoritmo per la creazione dei dati di intestazione) e vedere l'immagine in Firefox / IE.

Dovrei anche notare che questo NON è per lo spam, le e-mail vengono inviate a client specifici che se lo aspettano ogni giorno. Il contenuto è basato sui dati e non sulla pubblicità.


Domanda veloce: stai ospitando queste immagini fuori dal sito o le stai incorporando direttamente nell'email?
JonLim

Parte della mia domanda davvero, posso fare entrambe le cose. Sto provando qui a incorporarli, ma non con successo. Se mi collego solo a loro, molti utenti non vedranno le immagini senza prima averle scaricate, cosa che vorrei evitare.
tbone

1
Un normale <img src="URL" />funzionava per me, ma era un'immagine che ho ospitato fuori sede. Non funziona per te?
JonLim

"funziona" è soggettivo ... sì, funziona se l'utente desidera scaricare le immagini ogni volta, ma vorrei evitarlo e incorporare l'immagine.
tbone

1
@ JonLim: grazie per aver esaminato, vedere i miei commenti nella risposta per quello che mi mancava.
tbone

Risposte:


139

Prova a inserirlo direttamente, in questo modo puoi inserire più immagini in vari punti dell'email.

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

E per rendere questo post utile agli altri: Se non hai una stringa di dati base64, creane una facilmente su: http://www.motobit.com/util/base64-decoder-encoder.asp da un file immagine .

Il codice sorgente dell'email assomiglia a questo, ma non posso davvero dirti a cosa serve quel 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, mi rendo conto che se inserisci il primo frammento di codice dal mio post per scrivere un'e-mail con thunderbird, thunderbird cambia automaticamente il codice html in modo che sia più o meno lo stesso del secondo codice nel mio post.


5
ho provato prima questo, non funziona per me per la posta elettronica. funziona bene per la visualizzazione in IE / Firefox, ma non viene inviato come e-mail.
tbone

Forse conosci un modo (quale sarebbe il tipo di contenuto? Testo / html? Le intestazioni delle e-mail che avrei bisogno di sapere per inviare un file html / immagine misto in questo modo)
tbone

1
@Zesty usa @ [nome utente] per avvisare qualcuno, ha appena visto la tua domanda. Uso utl_smtp. Per me, ho dovuto creare build un clob con il corpo html, i confini, ecc. E quindi inviare tramite utl_smtp. Vedi qui per un semplice esempio: oracle-base.com/articles/misc/EmailFromOraclePLSQL.php Nota che questo collegamento non mostra l'approccio alle immagini incorporate, ma ha dettagli per farti andare.
tbone

41
Gli URI dei dati nelle e-mail non sono supportati in molti client tradizionali e non dovrebbero essere utilizzati, vedere: campaignmonitor.com/blog/post/3927/…
Michael Böckling

2
Non sembra funzionare in hotmail / icloud = (mi sono perso qualcosa
hsb1007

22

L'altra soluzione è allegare l'immagine come allegato e quindi fare riferimento al codice html utilizzando cid.

Codice HTML:

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

Codice 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

Non trovo utile nessuna delle risposte qui, quindi sto fornendo la mia soluzione.

  1. Il problema è che stai usando multipart/relatedcome tipo di contenuto che non è buono in questo caso. Lo sto usando multipart/mixede al suo interno multipart/alternative(funziona sulla maggior parte dei client).

  2. La struttura del messaggio dovrebbe essere la seguente:

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

Allora funzionerà


Lottando su questo. Ho codificato esattamente come sopra, ma l'immagine non appare (solo una cornice con il testo alternativo; il testo funziona bene). Il mio Content-ID è <filename.jpg> quindi my href = "cid: filename.jpg" - c'è qualche trucco speciale per il valore o la sintassi di Content-ID e cid:?
Peter Flynn,

Ho controllato con RFC2392 e l'espressione CID sembra essere valida. Ma ancora non viene visualizzato.
Peter Flynn,

Ho scritto una risposta ad una domanda simile e ha creato un'arte ASCII per spiegare la struttura: stackoverflow.com/a/40420648/633961
guettli


4

Usare Base64 per incorporare immagini in html è fantastico. Tuttavia, tieni presente che le stringhe base64 possono aumentare le dimensioni della tua email.

Perciò,

1) Se hai molte immagini, caricare le tue immagini su un server e caricare quelle immagini dal server può ridurre le dimensioni della tua email. (Puoi ottenere molti servizi gratuiti tramite Google)

2) Se ci sono solo poche immagini nella tua posta, usare le stringhe base64 è sicuramente un'opzione fantastica.

Oltre alle scelte fornite dalle risposte esistenti, puoi anche usare un comando per generare una stringa base64 su linux:

base64 test.jpg

Sottolineato da Michael Böckling: gli URI dei dati nelle e-mail non sono supportati in molti client tradizionali come gmail
Mendy

3

So che questo è un vecchio post, ma le risposte attuali non riguardano il fatto che Outlook e molti altri provider di posta elettronica non supportano le immagini in linea o le immagini CID. Il modo più efficace per inserire immagini nelle e-mail è ospitarle online e inserire un collegamento ad esse nell'e-mail. Per piccoli elenchi di posta elettronica, una casella personale pubblica funziona bene. Ciò mantiene anche la dimensione dell'email ridotta.


2
  1. Sono necessari 3 limiti affinché le immagini in linea siano completamente conformi.

  2. Tutto va dentro il multipart/mixed.

  3. Quindi usa il multipart/relatedper contenere le multipart/alternativetue intestazioni di allegato dell'immagine.

  4. Infine, includi i tuoi allegati scaricabili all'interno dell'ultimo confine di multipart/mixed.


11
Sarebbe utile se includessi un esempio.
Makyen

7
Ancora più utile sarebbe un riferimento alle specifiche.
jbruni

2

In realtà c'è un ottimo post sul blog che elenca i pro ei contro di tre diversi approcci a questo problema di Martyn Davies. Puoi leggerlo su https://sendgrid.com/blog/embedding-images-emails-facts/ .

Vorrei aggiungere un quarto approccio utilizzando immagini di sfondo CSS.

Inserisci

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

al corpo della tua e-mail e una classe CSS come:

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

2

Per coloro che non sono riusciti a far funzionare una di queste soluzioni: Invia immagine in linea tramite e-mail Seguendo i passaggi descritti nella soluzione offerta da @ T30 sono stato in grado di visualizzare la mia immagine in linea senza essere bloccato da Outlook (i metodi precedenti erano bloccati) . Se stai usando l'exchange come noi, allora anche quando fai:

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

dovrai passarlo all'host dell'URL del servizio di scambio. Oltre a quello che segue, questa soluzione dovrebbe consentire di inviare facilmente immagini incorporate.


1

Potrebbe essere interessante che sia Outlook che Outlook Express possano generare questi formati di e-mail immagine multiparte, se si inseriscono i file immagine utilizzando la funzione di menu Inserisci / Immagine.

Ovviamente il tipo di email deve essere impostato su HTML (non testo semplice).

Qualsiasi altro metodo (ad es. Trascinamento della selezione o qualsiasi invocazione dalla riga di comando) comporta l'invio delle immagini come allegato.

Se poi invii un'email di questo tipo a te stesso, puoi vedere come è formattata! :)

FWIW, sto cercando un eseguibile autonomo per Windows che faccia immagini in linea dalla modalità riga di comando, ma sembra che non ce ne siano. È un percorso che molti hanno seguito ... Si può farlo con, ad esempio, Outlook Express, passandogli un file .eml opportunamente formattato.


0

Quanto segue sta lavorando al codice con due modi per ottenere ciò:

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

Un suggerimento in più al post di Pavel Perna che mi ha aiutato molto (non posso commentare con la mia reputazione, ecco perché lo posto come risposta): In alcune versioni di Microsoft Exchange, la disposizione dei contenuti in linea è rimossa ( vedi questo post di Microsoft ). L'immagine semplicemente non fa parte della posta che l'utente vede in Outlook. Come soluzione alternativa, utilizza invece "Content-Disposition: attachement". Outlook 2016 non mostrerà le immagini come allegati utilizzati nel messaggio di posta, sebbene utilizzino "Content-Disposition: attachement".


-30

Se stai usando Outlook per inviare un'immagine statica con collegamento ipertestuale, un modo semplice sarebbe usare Word.

  1. Apri MS Word
  2. Copia l'immagine su una pagina vuota
  3. Aggiungi collegamento ipertestuale all'immagine (Ctrl + K)
  4. Copia l'immagine nella tua email
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.