HTMLメールに画像を埋め込む


113

埋め込まれたgif画像を含むmultipart / related htmlメールを送信しようとしています。この電子メールは、Oracle PL / SQLを使用して生成されます。画像が赤いXとして表示されて、私の試みは失敗しました(Outlook 2007およびyahooメールの場合)

私はしばらくの間HTMLメールを送信してきましたが、私の要件は今、メールでいくつかのgif画像を使用することです。これらをWebサーバーの1つに保存してリンクすることはできますが、多くのユーザーの電子メールクライアントでは自動的に表示されず、設定を変更するか、電子メールごとに手動でダウンロードする必要があります。

だから、私の考えは、画像を埋め込むことです。私の質問は:

  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自体に画像を埋め込み、Firefox / IEで画像を表示できるためです。

これはスパムではないことにも注意してください。電子メールは毎日それを期待している特定のクライアントに送信されます。コンテンツはデータ主導であり、広告ではありません。


簡単な質問:これらの画像をオフサイトでホストしていますか、それとも電子メールに直接埋め込みますか?
JonLim

私の質問の一部は本当に、どちらかを行うことができます。私はそれらを埋め込むためにここで試しますが、うまくいきません。それらにリンクするだけでは、多くのユーザーは最初に画像をダウンロードしないと画像を表示できません。これは避けたいと思います。
tbone

1
常連<img src="URL" />は私のために働いたが、それは私がオフサイトでホストしたイメージでした。それはあなたのために機能しませんか?
JonLim

「作品」は主観的です...はい、ユーザーが毎回画像をダウンロードすることをいとわない場合は機能しますが、それを避けて画像を埋め込みたいです。
tbone

1
@JonLim:それを調べてくれてありがとう、私が欠けていたものの答えに私のコメントを見てください。
tbone 2011

回答:


139

電子メールのさまざまな場所に複数の画像を挿入できるので、直接挿入してみてください。

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

そして、この投稿を他の人に役立つようにするには:base64-data文字列がない場合は、次の場所で簡単に作成します: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--

//編集:ああ、私が投稿の最初のコードスニペットを挿入してthunderbirdでメールを作成すると、thunderbirdは自動的にHTMLコードを変更して私の投稿の2番目のコードとほとんど同じに見えるようにします。


5
最初にこれを試しました、それは私にとってメールでは機能しません。IE / Firefoxでの表示には問題ありませんが、電子メールとして送信されません。
tbone 2011

多分あなたは方法を知っています(コンテンツタイプは何ですか?text / html?この方法で混合html /画像ファイルを送信するために私が知る必要がある電子メールヘッダー)
tbone

1
@Zestyは@ [username]を使用して誰かに警告します。質問を見ただけです。utl_smtpを使用しています。私にとっては、html本体、境界などでclobを作成し、utl_smtp経由で送信する必要がありました。簡単な例については、こちらを参照してください:oracle-base.com/articles/misc/EmailFromOraclePLSQL.phpこのリンクは埋め込み画像のアプローチを示していませんが、詳細を説明しています。
tbone

41
電子メールのデータURIは多くのメインストリームクライアントでサポートされていないため、使用しないでください。キャンペーン
モニター.com / blog / post / 3927 /…

2
hotmail / icloud =(何も見落としませんでした
hsb1007

21

他の解決策は、画像を添付ファイルとして添付してから、cidを使用してhtmlコードを参照することです。

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

その後、動作します


これに苦労しています。上記とまったく同じようにコーディングしましたが、画像が表示されません(代替テキストを含むフレームのみ。テキストは正常に機能します)。私のContent-IDは<filename.jpg>なのでmy href = "cid:filename.jpg"-Content-IDとcidの値または構文に特別なトリックはありますか?
Peter Flynn

RFC2392で確認したところ、CID表現は有効であるようです。ただし、それでも表示されません。
Peter Flynn

私は同様の質問への回答を書き、構造を説明するASCIIアートを作成しました:stackoverflow.com/a/40420648/633961
guettli

10

それが機能しない場合は、画像をHTMLテーブルに変換する次のツールのいずれかを試すことができます(ただし、画像のサイズに注意してください)。


10
img2hmtlは、私がしばらく見てきた中で最も奇抜なソリューション/アイデアです。+1
クリスチャンリーヴァ2017

4

Base64を使用して画像をHTMLに埋め込むのは素晴らしいことです。それでも、base64文字列はメールのサイズを大きくする可能性があることに注意してください。

したがって、

1)画像の数が多い場合、サーバーに画像をアップロードしてサーバーからそれらの画像をロードすると、メールのサイズが小さくなる場合があります。(Google経由で多くの無料サービスを利用できます)

2)メールに画像が少ししかない場合は、base64文字列を使用することは間違いなく素晴らしいオプションです。

既存の回答で提供される選択肢の他に、コマンドを使用してLinuxでbase64文字列を生成することもできます。

base64 test.jpg

MichaelBöcklingが指摘:メールのデータURIは、Gmailなどの多くのメインストリームクライアントではサポートされていません
Mendy

3

私はこれが古い投稿であることを知っていますが、現在の回答では、Outlookや他の多くのメールプロバイダーがインライン画像やCID画像をサポートしていないという事実に対処していません。メールに画像を配置する最も効果的な方法は、画像をオンラインでホストし、メールへのリンクを配置することです。小さなメールリストの場合は、パブリックドロップボックスが適切に機能します。これにより、メールのサイズも小さくなります。


2
  1. インライン画像が完全に準拠するには、3つの境界が必要です。

  2. すべてがの内部に入りmultipart/mixedます。

  3. 次に、multipart/relatedを使用してmultipart/alternative、画像と添付ファイルのヘッダーを含めます。

  4. 最後に、ダウンロード可能な添付ファイルをの最後の境界内に含めますmultipart/mixed


11
例を含めると参考になります。
マキエン

7
さらに便利なのは、仕様への参照です。
jbruni 2015年

2

Martyn Daviesによるこの問題への3つの異なるアプローチの長所と短所をリストした非常に優れたブログ投稿があります。https://sendgrid.com/blog/embedding-images-emails-facts/で読むことができます

CSSの背景画像を使用する4番目のアプローチを追加したいと思います。

追加

<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によって提供されるソリューションで説明されている手順に従って、Outlookによってブロックされることなく、インライン画像を表示することができました(以前の方法でブロックされていました) 。私たちのように交換を使用している場合は、次のことも行います。

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

ExchangeサービスのURLホストに渡す必要があります。それ以外の場合、このソリューションでは、埋め込まれた画像を簡単に送信できます。


1

[挿入/画像]メニュー機能を使用して画像ファイルを挿入した場合、OutlookとOutlook Expressの両方がこれらのマルチパート画像の電子メール形式を生成できることに注意してください。

明らかに、電子メールタイプはHTML(プレーンテキストではない)に設定する必要があります。

その他の方法(ドラッグ/ドロップ、またはコマンドライン呼び出しなど)では、画像が添付ファイルとして送信されます。

次に、そのようなメールを自分に送信すると、どのようにフォーマットされているかを確認できます。:)

FWIW、コマンドラインモードからインラインイメージを実行するスタンドアロンのWindows実行可能ファイルを探していますが、何もないようです。これは多くの人が行ってきたパスです...適切にフォーマットされた.emlファイルを渡すことにより、たとえばOutlook Expressでそれを行うことができます。


0

以下は、これを実現する2つの方法を使用した作業コードです。

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

Pavel Pernaの投稿に対する1つの追加のヒントは、私を非常に助けました(私の評判にはコメントできないため、これを回答として投稿します):一部のバージョンのMicrosoft Exchangeでは、インラインコンテンツの配置が削除されています(Microsoftによるこの投稿を参照してください)。画像は、ユーザーがOutlookで表示するメールには含まれていません。回避策として、代わりに「Content-Disposition:attachement」を使用してください。Outlook 2016では、「Content-Disposition:添付ファイル」を使用していますが、メールメッセージで使用される添付ファイルとして画像は表示されません。


-30

Outlookを使用してハイパーリンク付きの静止画像を送信する場合、Wordを使用するのが簡単な方法です。

  1. MS Wordを開く
  2. 画像を空白のページにコピーする
  3. 画像にハイパーリンクを追加(Ctrl + K)
  4. 画像をメールにコピーします
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.