Home > other >  How can I put images in the body of a message in delphi 7?
How can I put images in the body of a message in delphi 7?

Time:08-17

I am working with sending mails through the smtp protocol using the Indy idMessage object in delphi 7 (therefore the Indy version is 9). I was sending messages in html format without problems, but now I would like to embed an image in the body of the message. I saw that it would not be as easy as putting:

<img src='C:\Foo\image.png'>

From what I saw, you have to initialize an IdAttachment and reference it in the html, but I couldn't make it work as such.

Next I leave the code used to create the body of the message

procedure TfmMail.SendMail;
var
  IdMensaje: TIdMessage;
  smtp: TIdSMTP;
begin
  IdMensaje := TIdMessage.Create(nil);
  IdMensaje.Clear;
  IdMensaje.Body.Clear;
  IdMensaje.ContentType := 'text';
  IdMensaje.From.Text :=  'Title from email';
  IdMensaje.Body.Text := 'greeting';
  IdMensaje.ContentType := 'text/html';
  //<img src='C:\Foo\image.png> -> Don't work
  IdMensaje.Body.Text := IdMensaje.Body.Text   '<p> Other text to body </p>;

CodePudding user response:

For Indy 9, you need to:

  • set the TIdMessage.ContentType property to multipart/related; type="text/html",

  • add a TIdText object to the TIdMessage.MessageParts property (instead of using TIdMessasage.Body), containing the HTML content. The HTML's <img> tags can refer to each attachment using a cid:<content-id> identifier in their src attribute.

  • add a separate TIdAttachment object to TIdMessage.MessageParts for each image, and assign a unique Content-ID header assigned to each one.

Try something like this:

procedure TfmMail.SendMail;
var
  IdMensaje: TIdMessage;
  ...
begin
  IdMensaje := TIdMessage.Create(nil);
  try
    ...

    IdMensaje.ContentType := 'multipart/related; type="text/html"';

    with TIdText.Create(IdMensaje.MessageParts, nil) do
    begin
      ContentType := 'text/html';
      Body.Text := '... <img src="cid:myimageid"> ...';
    end;

    with TIdAttachment.Create(IdMensaje.MessageParts, 'C:\Foo\image.png') do
    begin
      ContentType := 'image/png';

      ContentID := '<myimageid>';
      //
      // or, if ContentID is not available:
      //
      // Headers.Values['Content-ID'] := '<myimageid>';
      // or:
      // ExtraHeaders.Values['Content-ID'] := '<myimageid>';
    end;

    // use IdMensaje as needed ...
  finally
    IdMensaje.Free;
  end;
end;

CodePudding user response:

You can either point the img tag to an external url (keep in mind that Outlook will block image downloads by default unless the user explicitly clicks on "Download images") or you can add images as attachments, set their Content-Id MIME header (e.g. to 'xyz') on the attachment MIME part, then refer to that image in the HTML body though that content-id, e.g., <img src="cid:xyz">

Third option would be embedding image data in the img tag, but not all email clients understand that - older versions of Outlook won't render images like that: <img src="data:image/jpeg;base64, LzlqLzRBQ..." />

  • Related