C++ にて VMime を使って 埋め込み画像付きのメールを作成する

C++ にて VMime を使って メールを送信する
の続きです。

埋め込み画像付きのメールの仕様

メールに画像を埋め込みHTMLパートから参照することができる。
画像ファイルの添付とは異なる。

RFC 2387に規定がある。

RFC2387   The MIME Multipart/Related Content-type   http://pentan.info/doc/rfc/j2387.html

下記のように、multipart の中に plain の本文とHTMLのパートと埋め込み画像を置く。

Content-Type: multipart/alternative

Content-Type: text/plain
本文のデータ

Content-Type: multipart/related

Content-Type: text/html
HTML のデータ

Content-Type: image/jpg
Content-Id:
Content-Disposition: inline
Content-Transfer-Encoding: base64
埋め込み画像 のデータ

埋め込み画像のヘッダーには、画像ファイルの添付と区別するために Content-Disposition: inline を付ける。
HTMLパートから参照するために Content-Id を付ける。

HTMLパートから参照するときは 識別子 "cid:" を付ける。

参考 Mail RFC embedded image using cid for text/plain
https://stackoverflow.com/questions/48640816/mail-rfc-embedded-image-using-cid-for-text-plain

埋め込み画像付きのメールを作成する

vmime::htmlTextPart::embeddedObject を使用する。

vmime htmlTextPart::embeddedObject Class Reference
https://www.vmime.org/public/documentation/doxygen/classvmime_1_1htmlTextPart_1_1embeddedObject.html

ソースコードに同封されているサンプルコード を参考にする。 https://github.com/kisli/vmime/blob/master/examples/example3.cpp

埋め込み画像は、下記のように記述する。

vmime::messageBuilder mb;

vmime::htmlTextPart& textPart =
            *vmime::dynamicCast <vmime::htmlTextPart>(mb.getTextPart());

vmime::shared_ptr <vmime::utility::fileSystemFactory> fs = 
vmime::platform::getHandler()->getFileSystemFactory();

vmime::shared_ptr <vmime::utility::file> imageFile =
fs->create( fs->stringToPath( fullpath ) );

vmime::shared_ptr <vmime::utility::fileReader> fileReader =
imageFile->getFileReader();

vmime::shared_ptr <vmime::contentHandler> imageCts =
vmime::make_shared <vmime::streamContentHandler>(
                fileReader->getInputStream(),
                imageFile->getLength()
);

vmime::shared_ptr <const vmime::htmlTextPart::embeddedObject> obj =
textPart.addObject(
    imageCts,
    vmime::mediaType(
        vmime::mediaTypes::IMAGE,
        vmime::mediaTypes::IMAGE_JPEG
    )
);

HTMLパートから参照するときは、下記のように記述する。

vmime::string html = "<img src=\"") + obj->getReferenceId() + vmime::string("\"/>");

作成したメールをメールアプリの Thnderbird で見るとこうなる。

f:id:ken_ohwada:20210123092059p:plain
mail embed

全体のコードは、githubに公開した。
https://github.com/ohwada/MAC_cpp_Samples/tree/master/vmime/create