menyematkan gambar di email html

113

Saya mencoba mengirim email html multi bagian / terkait dengan gambar gif yang disematkan. Email ini dibuat menggunakan Oracle PL / SQL. Upaya saya gagal, dengan gambar muncul sebagai X merah (di Outlook 2007 dan yahoo mail)

Saya telah mengirim email html untuk beberapa waktu, tetapi persyaratan saya sekarang adalah menggunakan beberapa gambar gif di email. Saya dapat menyimpan ini di salah satu server web kami dan hanya menautkannya, tetapi banyak klien email pengguna tidak akan menampilkannya secara otomatis dan perlu mengubah pengaturan atau mengunduhnya secara manual untuk setiap email.

Jadi, pikiranku adalah menanamkan gambar itu. Pertanyaan saya adalah:

  1. Apa yang saya lakukan salah di sini?
  2. Apakah pendekatan embedding sudah benar?
  3. Adakah opsi lain jika saya perlu menggunakan lebih banyak gambar? Lampiran tidak akan berfungsi, karena gambar biasanya berupa logo dan ikon yang tidak masuk akal dari konteks pesan. Selain itu, beberapa elemen email adalah tautan ke sistem online, jadi membuat PDF statis dan melampirkan tidak akan berfungsi (menurut pengetahuan saya).

potongan:

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

Terimakasih banyak.

BTW: Ya, saya telah memverifikasi bahwa data base64 benar, karena saya dapat menyematkan gambar di html itu sendiri (menggunakan penggunaan algo yang sama untuk membuat data header) dan melihat gambar di Firefox / IE.

Saya juga harus mencatat bahwa ini BUKAN untuk spam, email dikirim ke klien tertentu yang mengharapkannya setiap hari. Kontennya berdasarkan data, dan bukan iklan.

tulang T
sumber
Pertanyaan singkat: apakah Anda menghosting gambar ini di luar situs atau menyematkannya langsung ke email?
JonLim
Bagian dari pertanyaan saya sungguh, saya bisa melakukan keduanya. Saya mencoba di sini untuk menyematkannya, tetapi tidak berhasil. Jika saya hanya menautkannya, banyak pengguna tidak akan melihat gambar tanpa mendownloadnya terlebih dahulu, yang ingin saya hindari.
Tbone
1
A biasa <img src="URL" />berfungsi untuk saya, tetapi itu adalah gambar yang saya hosting di luar situs. Itu tidak berhasil untukmu?
JonLim
"berfungsi" bersifat subjektif ... ya, berfungsi jika pengguna ingin mendownload gambar setiap kali, tapi saya ingin menghindari itu dan menyematkan gambar.
Tbone
1
@ JonLim: terima kasih telah memeriksanya, lihat komentar saya di jawaban untuk apa yang saya lewatkan.
Tbone

Jawaban:

139

Cobalah untuk memasukkannya secara langsung, dengan cara ini Anda dapat memasukkan banyak gambar di berbagai lokasi dalam email.

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

Dan untuk membuat posting ini berguna bagi orang lain untuk: Jika Anda tidak memiliki string data base64, buatlah dengan mudah di: http://www.motobit.com/util/base64-decoder-encoder.asp dari file gambar .

Kode sumber email terlihat seperti ini, tetapi saya benar-benar tidak dapat memberi tahu Anda untuk apa batas itu:

 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, saya baru sadar jika Anda memasukkan potongan kode pertama dari posting saya untuk menulis email dengan thunderbird, thunderbird secara otomatis mengubah kode html agar terlihat hampir sama dengan kode kedua di posting saya.

Bernd
sumber
5
mencoba ini terlebih dahulu, tidak berhasil untuk saya untuk email. berfungsi dengan baik untuk dilihat di IE / Firefox, tetapi tidak dikirim sebagai email.
Tbone
Mungkin Anda tahu caranya (apa jenis kontennya? Teks / html? Header email yang perlu saya ketahui untuk mengirim file html / gambar campuran dengan cara ini)
tbone
1
@Zesty gunakan @ [nama pengguna] untuk memperingatkan seseorang, baru saja melihat pertanyaan Anda. Saya menggunakan utl_smtp. Bagi saya, saya harus membuat clob dengan html body, batas, dll dan kemudian mengirim melalui utl_smtp. Lihat di sini untuk contoh sederhananya: oracle-base.com/articles/misc/EmailFromOraclePLSQL.php Perhatikan bahwa tautan ini tidak menunjukkan pendekatan gambar yang disematkan, tetapi memiliki detail untuk membantu Anda melanjutkan.
Tbone
41
URI data dalam email tidak didukung di banyak klien utama dan tidak boleh digunakan, lihat: campaignmonitor.com/blog/post/3927/…
Michael Böckling
2
Tampaknya tidak berfungsi di hotmail / icloud = (apakah saya melewatkan sesuatu
hsb1007
22

Solusi lain adalah melampirkan gambar sebagai lampiran dan kemudian mereferensikan kode html menggunakan cid.

Kode HTML:

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

C # Kode:

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

Saya tidak menemukan jawaban apa pun di sini yang berguna, jadi saya memberikan solusi saya.

  1. Masalahnya adalah Anda menggunakan multipart/relatedjenis konten yang tidak baik dalam kasus ini. Saya menggunakan multipart/mixeddan di dalamnya multipart/alternative(berfungsi pada sebagian besar klien).

  2. Struktur pesan harus sebagai berikut:

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

Maka itu akan berhasil

Pavel Perna
sumber
Berjuang yang satu ini. Saya telah membuat kode persis seperti di atas, tetapi gambar tidak muncul (hanya bingkai dengan teks alt; teks berfungsi dengan baik). Content-ID saya adalah <filename.jpg> jadi my href = "cid: filename.jpg" - adakah trik khusus untuk nilai atau sintaks Content-ID dan cid:?
Peter Flynn
Saya memeriksa dengan RFC2392 dan ekspresi CID tampaknya valid. Tapi masih belum muncul.
Peter Flynn
Saya menulis jawaban untuk pertanyaan serupa dan membuat seni ascii untuk menjelaskan strukturnya: stackoverflow.com/a/40420648/633961
guettli
4

Menggunakan Base64 untuk menyematkan gambar di html sangat mengagumkan. Meskipun demikian, harap perhatikan bahwa string base64 dapat membuat ukuran email Anda menjadi besar.

Karena itu,

1) Jika Anda memiliki banyak gambar, mengunggah gambar Anda ke server dan memuat gambar-gambar itu dari server dapat membuat ukuran email Anda lebih kecil. (Anda bisa mendapatkan banyak layanan gratis melalui Google)

2) Jika hanya ada beberapa gambar di email Anda, menggunakan string base64 jelas merupakan pilihan yang bagus.

Selain pilihan yang diberikan oleh jawaban yang ada, Anda juga dapat menggunakan perintah untuk menghasilkan string base64 di linux:

base64 test.jpg
Brian
sumber
Ditunjukkan oleh Michael Böckling: URI data dalam email tidak didukung di banyak klien utama seperti gmail
Mendy
3

Saya tahu ini adalah posting lama, tetapi jawaban saat ini tidak membahas fakta bahwa pandangan dan banyak penyedia email lainnya tidak mendukung gambar inline atau gambar CID. Cara paling efektif untuk menempatkan gambar di email adalah dengan menghostingnya secara online dan menempatkan link ke gambar tersebut di email. Untuk daftar email kecil, dropbox publik berfungsi dengan baik. Ini juga mengurangi ukuran email.

Skuter Crawford
sumber
2
  1. Anda memerlukan 3 batas agar gambar sebaris sepenuhnya sesuai.

  2. Semuanya masuk ke dalam multipart/mixed.

  3. Kemudian gunakan multipart/relateduntuk memuat multipart/alternativeheader lampiran Anda dan gambar Anda.

  4. Terakhir, sertakan lampiran Anda yang dapat diunduh di dalam batas terakhir multipart/mixed.

Steven Newman
sumber
11
Akan sangat membantu jika Anda menyertakan sebuah contoh.
Makyen
7
Bahkan lebih berguna akan menjadi referensi ke spesifikasi.
jbruni
2

Sebenarnya ada posting blog yang sangat bagus yang mencantumkan pro dan kontra dari tiga pendekatan berbeda untuk masalah ini oleh Martyn Davies. Anda dapat membacanya di https://sendgrid.com/blog/embedding-images-emails-facts/ .

Saya ingin menambahkan pendekatan keempat menggunakan gambar latar belakang CSS.

Menambahkan

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

ke badan email Anda dan kelas css seperti:

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

Bagi mereka yang tidak bisa mendapatkan salah satu dari solusi ini yang berfungsi: Kirim gambar sebaris dalam email Mengikuti langkah-langkah yang ditetapkan dalam solusi yang ditawarkan oleh @ T30 saya bisa menampilkan gambar sebaris saya tanpa diblokir oleh pandangan (metode sebelumnya diblokir) . Jika Anda menggunakan pertukaran seperti kami maka juga saat melakukan:

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

Anda harus meneruskannya ke host url layanan pertukaran Anda. Selain itu, mengikuti solusi ini akan memungkinkan Anda dengan mudah mengirim gambar yang disematkan.

tstrand66
sumber
1

Mungkin menarik bahwa Outlook dan Outlook Express dapat menghasilkan format email gambar multi bagian ini, jika Anda memasukkan file gambar menggunakan fungsi menu Sisipkan / Gambar.

Jelas jenis email harus diatur ke HTML (bukan teks biasa).

Metode lain (misalnya seret / lepas, atau pemanggilan baris perintah apa pun) menghasilkan gambar yang dikirim sebagai lampiran.

Jika Anda kemudian mengirim email seperti itu kepada diri Anda sendiri, Anda dapat melihat bagaimana formatnya! :)

FWIW, saya mencari windows mandiri yang dapat dieksekusi yang melakukan gambar inline dari mode baris perintah, tetapi tampaknya tidak ada. Ini adalah jalur yang telah ditempuh banyak orang ... Seseorang dapat melakukannya dengan mengatakan Outlook Express, dengan meneruskannya ke file .eml yang diformat dengan tepat.

Peter
sumber
0

Berikut ini adalah kode kerja dengan dua cara untuk mencapai ini:

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

Satu petunjuk tambahan untuk posting Pavel Perna yang sangat membantu saya (tidak dapat berkomentar dengan reputasi saya, itulah mengapa saya memposting ini sebagai jawaban): Di beberapa versi Microsoft Exchange, disposisi konten inline dihapus ( lihat posting ini oleh Microsoft ). Gambar tersebut bukan bagian dari email yang dilihat pengguna di Outlook. Sebagai solusinya, gunakan "Content-Disposition: attachment" sebagai gantinya. Outlook 2016 tidak akan menampilkan gambar sebagai lampiran yang digunakan dalam pesan email, meskipun gambar tersebut menggunakan "Content-Disposition: attachment".

Klendatho
sumber
-30

Jika Anda menggunakan Outlook untuk mengirim gambar statis dengan hyperlink, cara mudah adalah menggunakan Word.

  1. Buka MS Word
  2. Salin gambar ke halaman kosong
  3. Tambahkan hyperlink ke gambar (Ctrl + K)
  4. Salin gambar ke email Anda
Claudio Viz
sumber