Jump to content
mazluta

The image in the target mail don't respect the height/width prop

Recommended Posts

Hi, 

i'm using TIdMessageBuilderHtml to build the message body from HTML,

the base HTML is Attach - myMail.html.

it's Base64 + some CSS - style="height:144px; width:120px;

 

when open this HTML with browser all look fine.

 

after sending this with the SMPT protocol the size of the image become the TRUE SIZE of the image.

and this is not what i want.

 

image.thumb.png.0ea636711211266311c4ed50cefa9c32.png

 

myMail.msg is the email as received in my outlook.

 

how can i fix it?

 

uSendSMTPMail.pas

myMail.html

MyMail.msg

Share this post


Link to post
7 hours ago, mazluta said:

i'm using TIdMessageBuilderHtml to build the message body from HTML,

What versions of Delphi and Indy are you using?

7 hours ago, mazluta said:

after sending this with the SMPT protocol the size of the image become the TRUE SIZE of the image.

and this is not what i want.

Did you compare the HTML that Outlook has to the HTML that you sent?

7 hours ago, mazluta said:

myMail.msg is the email as received in my outlook.

.msg files are binary files that Outlook creates for itself after converting the original data. It is not "received" from the sender.  So, it is hard to diagnose them.  Can you export an .eml file instead?  Or at least view the source data for the .msg file?  How does its HTML compare to the original HTML?

7 hours ago, mazluta said:

Not related to your problem, but why are you UTF-8 encoding the strings you give to Indy?  Don't do that.  Use plain strings instead, and let Indy encode them for you.

 

Also, you should not be messing with the TIdMessage properties after you have called TIdMessageBuilderHtml.FillMessage().  It has already set the properties accordingly for you.

7 hours ago, mazluta said:

Your HTML has conflicting charsets in its <meta> elements.

 

Also, it is unusual to use a "data:" url to display an image in an HTML email.  Why are you not attaching the image file to the email and then using a "cid:" url to display it?  Granted, TIdMessageBuilderHtml doesn't care what HTML you give it, but it is designed for "cid:" urls in mind.

Share this post


Link to post

Hi Remy 

Thanks for your answers.

 

1. What versions of Delphi and Indy are you using?

    delphi 10.3 + indy 10

2. Did you compare the HTML that Outlook has to the HTML that you sent?

   yes they are the same.

3. the msg file was just to let those how answer to see what i get.

4.  why are you UTF-8 encoding.

     because of the Hebrew characters.

5. Your HTML has conflicting charsets in its <meta> elements.

    what are the conflicts?

6. the 'body' is result of CkEditor. and i don't want to change there components.

    and the <IMG> is most likely the Company logo.

 

maybe if i change the base64 to the size of the style - it will work.

 

Share this post


Link to post

Image attributes are not correct

 

h1XZgdBrJ2IOlrmq1SofeBwIdLyQHgGPgEfAIzCICNgIw6YHUZdhkvl//UZHbn5keAcAAAAASUVORK5CYII=";
            height="144px"; width="120px"; /></div>

 

There should be no ; between attributes

Share this post


Link to post
Posted (edited)
5 hours ago, mazluta said:

2. Did you compare the HTML that Outlook has to the HTML that you sent?

   yes they are the same.

Then the problem is not with Indy itself.  It is entirely a problem with the email reader.  It likely just doesn't support CSS, or doesn't handle it correctly.

Quote

3. the msg file was just to let those how answer to see what i get.

My point is, a .msg file is a binary file that is useless to people who don't use Outlook and can't open it (like me).  Whereas an .eml file is plain text instead.

Quote

4.  why are you UTF-8 encoding.

     because of the Hebrew characters.

You are using a Unicode version of Delphi, and Indy handles Unicode strings for you.  You don't need to encode the strings manually, nor is it beneficial to do so because you are assigning UTF8String's where UnicodeString's are expected, thus the Delphi compiler+RTL is simply going to implicitly decode your UTF-8 back to UTF-16 before Indy even sees the data.  So just use plain Delphi strings, don't encode them manually.  Indy defaults to UTF-8 in Unicode versions of Delphi when encoding the email data.

Quote

5. Your HTML has conflicting charsets in its <meta> elements.

    what are the conflicts?

Look for yourself.  You have a <meta charset> that states "utf-8", followed by a <meta http-equiv> that states "windows-1255".

Quote

6. the 'body' is result of CkEditor. and i don't want to change there components.

    and the <IMG> is most likely the Company logo.

 

maybe if i change the base64 to the size of the style - it will work.

Doubtful.

Edited by Remy Lebeau

Share this post


Link to post
Posted (edited)
4 hours ago, Alexander Sviridenkov said:

Image attributes are not correct

 

h1XZgdBrJ2IOlrmq1SofeBwIdLyQHgGPgEfAIzCICNgIw6YHUZdhkvl//UZHbn5keAcAAAAASUVORK5CYII=";
            height="144px"; width="120px"; /></div>

 

There should be no ; between attributes

The style attribute on the <img> element is formatted correctly:

<img src="data:image/png;base64,..." style="height:150px; width:125px" />

Multiple CSS styles in a single "style" attribute ARE supposed to be separated by semicolons.

Edited by Remy Lebeau

Share this post


Link to post

Hi Remy

Thanks for you detailed answers.

 

i see your point. i will check it all and get back to you

Share this post


Link to post
8 hours ago, Remy Lebeau said:

The style attribute on the <img> element is formatted correctly: 


<img src="data:image/png;base64,..." style="height:150px; width:125px" />

Multiple CSS styles in a single "style" attribute ARE supposed to be separated by semicolons.

There are two attached messages. In MyMail there is style attribute but no width/height attributes. Outlook does not handle image size in style attribute correctly, it requires explicit width/height.

In MyTest2-2 there are width/height attributes but incorrectly separated by semicolon.

Share this post


Link to post
On 8/13/2024 at 5:00 AM, Remy Lebeau said:

......

Doubtful.

image.thumb.png.8481a385af2fc7d279dfd0ea2f3e16c6.png

that work.

1. i remove the html conflict.

2. i gat the return string from the CkEditor.

3. i build simple HTML with 2 function.

    one to iterate all image.

    and for each <img> element i convert the base64 to be the same as the attribute (second function).

4. now, when i send the - "message" - its all look "normal"..

 

thank Remy and Alexander.

 

BTW - attach is the HTML file i build to convert the Images

 

mtTag_11197140.html

Share this post


Link to post

ok. now there is new problem.

Gmail want show message with image base on base64 string.

is there simple convert outlook message to Gmail Message?

Share this post


Link to post

i see i can build the eMail for Gmail using IDMessage.

i can iterate in all base64 img convert them to png file but i dont see way to embedded the image it self into the html message back... 

Share this post


Link to post
Posted (edited)
1 hour ago, mazluta said:

ok. now there is new problem.

Gmail want show message with image base on base64 string.

is there simple convert outlook message to Gmail Message?

Outlook and Gmail use the same core SMTP and email standards.  However, embedding images using "data:" urls may be common practice for web browsers, but it is not common practice for email.

 

According to:

https://stackoverflow.com/questions/6070196/what-is-data-uri-support-like-in-major-email-client-software

https://stackoverflow.com/questions/8580355/can-you-send-images-in-datauri-format-to-gmail

 

Gmail dropped support for "data:" urls over a decade ago.

 

I strongly suggest you stick to using "cid:" urls with file attachments in emails.  All major html-aware email readers know how to handle "cid:" attachments.  And TIdMessageBuilderHtml is designed with "cid:" in mind.

26 minutes ago, mazluta said:

i see i can build the eMail for Gmail using IDMessage.

That is the same component you used to send an email to Outlook.

26 minutes ago, mazluta said:

i can iterate in all base64 img convert them to png file but i dont see way to embedded the image it self into the html message back...

Because you don't embed it directly.  You would need to instead attach the png file to the email, assign the attachment an ID in its "Content-ID" header, and then refer to that ID in a "cid:" url in the HTML <img> src.  Have a look at the following articles on Indy's blog:

 

https://www.indyproject.org/2005/08/17/html-messages/

https://www.indyproject.org/2008/01/16/new-html-message-builder-class/

 

Your PNGs would be "related attachments" for the HTML, and can be attached using the TIdMessageBuilerHtml.HtmlFiles property, and identified with the TIdMessageBuilderAttachment.ContentID proeprty.

Edited by Remy Lebeau

Share this post


Link to post

Ok. That Work.

 

function  Tdm_Image.DoFixMailTextBody(MAIL_TextBody : String; Attach_Base64 : TStringList) : String;
Var
  CurTry      : Integer;
  CurPos      : Integer;
  CurChar     : Integer;
  UniqueNo    : Integer;
  StartFrom   : Integer;
  EndTo       : Integer;
  Base64Str   : String;
  base64      : TBase64Encoding;
  StrArray    : TBytes;
  DibGraphic  : TDibGraphic;
  TmpPNG      : TPngGraphic;
  TestStr     : String;
  fTempDir    : String;
  PngFileName : String;
  NewImgSrc   : String;
  FileExtn    : String;
begin
  Result := MAIL_TextBody;
  Attach_Base64.Clear;
  CurTry := 0;
  While CurTry < 250 Do
  begin
    CurTry := CurTry + 1;

    FileExtn := '';

    FileExtn := 'png';
    CurPos := pos(Base64_01,MAIL_TextBody);
    if CurPos < 1 then
    begin
      FileExtn := 'jpg';
      CurPos := pos(Base64_02,MAIL_TextBody);
    end;
    if CurPos < 1 then
    begin
      FileExtn := 'svg';
      CurPos := pos(Base64_03,MAIL_TextBody);
    end;
    if CurPos < 1 then
    begin
      FileExtn := 'png';
      CurPos := pos(Base64_04,MAIL_TextBody);
    end;
    if CurPos < 1 then
    begin
      FileExtn := 'jpg';
      CurPos := pos(Base64_05,MAIL_TextBody);
    end;
    if CurPos < 1 then
    begin
      FileExtn := 'bmp';
      CurPos := pos(Base64_06,MAIL_TextBody);
    end;
    if CurPos < 1 then
    begin
      FileExtn := 'gif';
      CurPos := pos(Base64_07,MAIL_TextBody);
    end;
    if CurPos < 1 then
    begin
      FileExtn := 'tif';
      CurPos := pos(Base64_08,MAIL_TextBody);
    end;
    if CurPos < 1 then
    begin
      FileExtn := 'wmf';
      CurPos := pos(Base64_09,MAIL_TextBody);
    end;
    if CurPos < 1 then
    begin
      FileExtn := 'emf';
      CurPos := pos(Base64_10,MAIL_TextBody);
    end;

    if CurPos > 0 then
    begin
      UniqueNo  := GetUniqueNumber; {This will be tje dic Number}
      StartFrom := 0;
      EndTo     := 0;

      // first find the , char - after that start the base64 string
      For CurChar := CurPos + 5 to Length(MAIL_TextBody) Do
      begin
        if MAIL_TextBody[CurChar] = ',' then
        begin
          StartFrom := CurChar + 1;
          Break;
        end;
      end;

      // the find the next " char - this close the base64 string
      For CurChar := StartFrom + 5 to Length(MAIL_TextBody) Do
      begin
        if MAIL_TextBody[CurChar] = '"' then
        begin
          EndTo := CurChar - 1;
          Break;
        end;
      end;

      // take the Base64 String And Convert to png file
      DibGraphic := TDibGraphic.Create;
      Try
        fTempDir := RemoveBackSlashChar(RemoveSlashChar(UniServerModule.LocalCachePath));

        Base64Str := Copy(MAIL_TextBody,StartFrom, EndTo - StartFrom);

        if Base64ToImg(Base64Str,DibGraphic, FileExtn) then
        begin
          PngFileName := fTempDir + '\' + IntToStr(UniqueNo) + '.png';
          TmpPNG := TPngGraphic.Create;
          Try
           TmpPNG.Assign(DibGraphic);
           TmpPNG.SaveToFile(PngFileName);
           Attach_Base64.Add(PngFileName);
           Delete(MAIL_TextBody, CurPos + 5, EndTo - CurPos - 4);
           NewImgSrc := 'cid:' + IntToStr(UniqueNo) +'.png';
           Insert(NewImgSrc, MAIL_TextBody, CurPos + 5);
          Finally
           FreeAndNil(TmpPNG);
          End;
        end;
      Finally
        FreeAndNil(DibGraphic);
      End;
    end
    else
    begin
      Break;
    end;
  end;

  Result := MAIL_TextBody;
end;
 

 

and to send the Mail :

 

 

function SendMailBySMTP(SMTP_Host : String;
                        SMTP_User : String;
                        SMTP_Password : String;
                        SMTP_Port : Integer;
                        Send_FromAddress : String;
                        Send_FromName : String;
                        Send_ToAddress : String;
                        Send_ToName : String;
                        Send_Subject : String;
                        Send_TextBody : String;
                        UseCid : Boolean;
                        Attach_Base64 : TStringList;
                        Attach_List : TStringList) : Boolean;
Var
  cid   : WideString;
  SMTP  : TIdSMTP;
  AMsg  : TidMessage;
  CurAttch    : Integer;
  FoundBase64 : Boolean;
Const
  Base64_01 : String = 'src="data:image/png;base64,';
  Base64_02 : String = 'src="data:image/jpeg;base64,';
  Base64_03 : String = 'src="data:image/image/svg+xml;base64,';
  Base64_04 : String = 'src="data:image/image/apng;base64,';
  Base64_05 : String = 'src="data:image/jpg;base64,';
  Base64_06 : String = 'src="data:image/image/bmp;base64,';
  Base64_07 : String = 'src="data:image/image/gif;base64,';
  Base64_08 : String = 'src="data:image/image/tiff;base64,';
  Base64_09 : String = 'src="data:image/image/wmf;base64,';
  Base64_10 : String = 'src="data:image/image/emf;base64,';

begin
  Result := False;
  Try
    if UseCid Then
    begin
      FoundBase64 := False;
      if (pos(Base64_01,Send_TextBody) > 0) Or
         (pos(Base64_02,Send_TextBody) > 0) Or
         (pos(Base64_03,Send_TextBody) > 0) Or
         (pos(Base64_04,Send_TextBody) > 0) Or
         (pos(Base64_05,Send_TextBody) > 0) Or
         (pos(Base64_06,Send_TextBody) > 0) Or
         (pos(Base64_07,Send_TextBody) > 0) Or
         (pos(Base64_08,Send_TextBody) > 0) Or
         (pos(Base64_09,Send_TextBody) > 0) Or
         (pos(Base64_10,Send_TextBody) > 0) then
        FoundBase64 := True;

      if not FoundBase64 Then
        UseCid := False;
    end;

    if UseCid then
    begin

    end;

    Try
      SMTP:= TIdSMTP.Create(nil);
      SMTP.Disconnect();
      SMTP.Host     := SMTP_Host;
      SMTP.Username := SMTP_User;
      SMTP.Password := SMTP_Password;
      SMTP.Port     := SMTP_Port;

      AMsg := TidMessage.Create(nil);
      AMsg.Encoding := meDefault;
      AMsg.ContentType := 'text/html';
      if Attach_List.Count > 0 then
        AMsg.ContentType := 'multipart/mixed';
      AMsg.CharSet := 'UTF-8';
      //AMsg.ContentTransferEncoding := '8bit';

      AMsg.subject := UTF8Encode(Send_Subject);
      AMsg.From.Name := UTF8Encode(Send_FromName);
      AMsg.From.Address := Send_FromAddress;
      with AMsg.Recipients.Add do
      begin
       Name := UTF8Encode(Send_ToName);
       Address := Send_ToAddress;
      end;

      with TIdMessageBuilderHtml.Create do
      try
        HtmlCharSet := 'UTF-8';
        Html.Text := UTF8Encode(Send_TextBody);

        if Attach_List.Count > 0 then
        begin
          for CurAttch := 0 To Attach_List.Count - 1 Do
          begin
            Attachments.Add(Attach_List.Strings[CurAttch]);
          end;
        end;

        if Attach_Base64.Count > 0 then
        begin
          for CurAttch := 0 To Attach_Base64.Count - 1 Do
          begin
            HtmlFiles.Add(Attach_Base64.Strings[CurAttch]);
          end;
        end;

        FillMessage(AMsg);

      finally
        Free;
      end;

      SMTP.Connect;
      SMTP.Send(AMsg);

      Result := True;
    Finally
      AMsg.Free;
      SMTP.Disconnect;
      SMTP.Free;
    End;
  Except
    on E: Exception do
    begin
      AddMsgToEventLog('', J_FirstFileName(ParamStr(0)), 'Fail send SMPT Mail, Error :' + e.Message,EVENTLOG_ERROR_TYPE, 4, 1);
      Result := False;
    end;
  End;
end;

 

function IsTherBase64InHTML(HTML_Text : String) : Boolean;
Const
  Base64_01 : String = 'src="data:image/png;base64,';
  Base64_02 : String = 'src="data:image/jpeg;base64,';
  Base64_03 : String = 'src="data:image/image/svg+xml;base64,';
  Base64_04 : String = 'src="data:image/image/apng;base64,';
  Base64_05 : String = 'src="data:image/jpg;base64,';
  Base64_06 : String = 'src="data:image/image/bmp;base64,';
  Base64_07 : String = 'src="data:image/image/gif;base64,';
  Base64_08 : String = 'src="data:image/image/tiff;base64,';
  Base64_09 : String = 'src="data:image/image/wmf;base64,';
  Base64_10 : String = 'src="data:image/image/emf;base64,';

begin
  Result := (pos(Base64_01,HTML_Text) > 0) Or
            (pos(Base64_02,HTML_Text) > 0) Or
            (pos(Base64_03,HTML_Text) > 0) Or
            (pos(Base64_04,HTML_Text) > 0) Or
            (pos(Base64_05,HTML_Text) > 0) Or
            (pos(Base64_06,HTML_Text) > 0) Or
            (pos(Base64_07,HTML_Text) > 0) Or
            (pos(Base64_08,HTML_Text) > 0) Or
            (pos(Base64_09,HTML_Text) > 0) Or
            (pos(Base64_10,HTML_Text) > 0);
end;

 

 

thanks Remy for your Help.

 

Share this post


Link to post
Posted (edited)

Wow, that is some really overcomplicated and inefficient code for such a simple task. That code can be greatly simplified. I'm not at a computer right now, otherwise I would whip up something smaller for you. Maybe I can later tonight or tomorrow...

 

Also, why are most of your "data:" media types prefixed with "image/image/" instead of just "image/"? That is just plain wrong, media types do not have such long  hierarchies. 

 

Also, TIdMessageBuilderHtml (and TIdMessage) supports attaching TStream objects, so you can avoid creating temp files on disk if you save your PNGs to memory instead.

Edited by Remy Lebeau

Share this post


Link to post
24 minutes ago, Remy Lebeau said:

with "image/image/" instead of just "image/"?

yeeee that abug

 

24 minutes ago, Remy Lebeau said:

Also, TIdMessageBuilderHtml (and TIdMessage) supports attaching TStream objects, so you can avoid creating temp files on disk if you save your PNGs to memory instead.

yes. you right

 

25 minutes ago, Remy Lebeau said:

Wow, that is some really overcomplicated and inefficient code for such a simple task.

🙂

 

Share this post


Link to post
Posted (edited)
18 hours ago, Remy Lebeau said:

That code can be greatly simplified. I'm not at a computer right now, otherwise I would whip up something smaller for you. Maybe I can later tonight or tomorrow...

Try something more like the following (I will leave sending PNGs from memory as an exercise for you):

uses
  ..., IdGlobal, IdGlobalProtocols;
  
function Tdm_Image.DoFixMailTextBody(MAIL_TextBody : String; Attach_PNGs : TStrings) : String;
var
  StartFrom, EndTo : Integer;
  TmpDir : String;

  function FindNextDataUrl(var DataUrl: String): Boolean;
  begin
    Result := False;
    // you can use StrUtils.PosEx() if System.Pos() doesn't have an Offset parameter...
    StartFrom := Pos('src="data:', MAIL_TextBody, StartFrom);
    if StartFrom = 0 then Exit;
    Inc(StartFrom, 5);
    EndFrom := Pos('"', MAIL_TextBody, StartFrom);
    if EndFrom = 0 then Exit;
    DataUrl := Copy(MAIL_TextBody, StartFrom, EndFrom - StartFrom);
    Result := True;
  end;
  
  function ExtractImageBase64FromDataUrl(DataUrl : String; var ImgType, Base64Str : String): Boolean;
  begin
    Result := False;
    Fetch(DataUrl, ':');
    ImgType := Fetch(DataUrl, ',');
    Result := TextEndsWith(ImgType, ';base64');
    if not Result then Exit;
    SetLength(ImgType, Length(ImgType)-7);
    Result := IsHeaderMediaType(ImgType, 'image');
    if not Result then Exit;
    ImgType := ExtractHeaderMediaSubType(ImgType);
    Base64Str := DataUrl;
    Result := True;
  end;

  function Base64ToPngFile(const ImgType, Base64Str: String; var UniqueNo: Integer): Boolean;
  var
    DibGraphic  : TDibGraphic;
    PngGraphic  : TPngGraphic;
    FileExtn    : String;
    PngFileName : String;
  begin
    Result := False;
    case PosInStrArray(ImgType, ['png', 'apng', 'jpeg', 'jpg', 'svg+xml', 'bmp', 'gif', 'tiff', 'wmf', 'emf'], False) of
      0, 1: FileExtn := 'png';
      2, 3: FileExtn := 'jpg';
      4:    FileExtn := 'svg';
      5:    FileExtn := 'bmp';
      6:    FileExtn := 'gif';
      7:    FileExtn := 'tif';
      8:    FileExtn := 'wmf';
      9:    FileExtn := 'emf';
    else
      Exit;
    end;
    // take the Base64 String And Convert to png file
    PngGraphic := TPngGraphic.Create;
    try
      DibGraphic := TDibGraphic.Create;
      try
        Result := Base64ToImg(Base64Str, DibGraphic, FileExtn);
        if not Result then Exit;
        PngGraphic.Assign(DibGraphic);
      finally
        DibGraphic.Free;
      end;
      if PngGraphic.Empty then Exit;
      UniqueNo := GetUniqueNumber; {This will be the cid Number}
      PngFileName := TmpDir + IntToStr(UniqueNo) + '.png';
      PngGraphic.SaveToFile(PngFileName);
    finally
      PngGraphic.Free;
    end;
    Attach_PNGs.Add(PngFileName);
    Result := True;
  end;  

  procedure ConvertDataUrlToCidUrl(UniqueNo : Integer);
  var
    NewImgSrc : String;
  begin
    Delete(MAIL_TextBody, StartFrom, EndTo - StartFrom);
    NewImgSrc := 'cid:' + IntToStr(UniqueNo) + '.png';
    Insert(NewImgSrc, MAIL_TextBody, StartFrom);
    EndFrom := StartFrom + Length(NewImgSrc);
  end;

  procedure ReplaceDataUrlsWithCidUrls;
  var
    DataUrl, ImgType, Base64Str : String;
    UniqueNo: Integer;
  begin
    StartFrom := 1;
    while FindNextDataUrl(DataUrl) do
    begin
      if ExtractImageBase64FromDataUrl(DataUrl, ImgType, Base64Str) then
        if Base64ToPngFile(ImgType, Base64Str, UniqueNo) then
          ConvertDataUrlToCidUrl(UniqueNo);
      StartFrom := EndFrom + 1;
    end;
  end;

begin
  Attach_PNGs.Clear;
  TmpDir := IncludeTrailingPathDelimiter(RemoveBackSlashChar(RemoveSlashChar(UniServerModule.LocalCachePath)));
  ReplaceDataUrlsWithCidUrls;
  Result := MAIL_TextBody;
end;
 
function SendMailBySMTP(SMTP_Host : String;
                        SMTP_User : String;
                        SMTP_Password : String;
                        SMTP_Port : Integer;
                        Send_FromAddress : String;
                        Send_FromName : String;
                        Send_ToAddress : String;
                        Send_ToName : String;
                        Send_Subject : String;
                        Send_TextBody : String;
                        Attach_List : TStrings;
                        UseCid : Boolean) : Boolean;
var
  SMTP  : TIdSMTP;
  AMsg  : TIdMessage;
  CurAttch    : Integer;
  Attach_PNGs : TStringList;
begin
  Result := False;
  Try
    Attach_PNGs := nil;
    try
      if UseCid then
      begin
        Attach_PNGs := TStringList.Create;
        Send_TextBody := DoFixMailTextBody(Send_TextBody, Attach_PNGs);
      end;

      SMTP := TIdSMTP.Create(nil);
      try
        SMTP.Host     := SMTP_Host;
        SMTP.Username := SMTP_User;
        SMTP.Password := SMTP_Password;
        SMTP.Port     := SMTP_Port;

        AMsg := TIdMessage.Create(SMTP);
        AMsg.Subject := Send_Subject;
        AMsg.From.Name := Send_FromName;
        AMsg.From.Address := Send_FromAddress;
        with AMsg.Recipients.Add do
        begin
          Name := Send_ToName;
          Address := Send_ToAddress;
        end;

        with TIdMessageBuilderHtml.Create do
        try
          HtmlCharSet := 'utf-8';
          Html.Text := Send_TextBody;

          if (Attach_List <> nil) and (Attach_List.Count > 0) then
          begin
            for CurAttch := 0 To Attach_List.Count - 1 do
              Attachments.Add(Attach_List.Strings[CurAttch]);
          end;

          if (Attach_PNGs <> nil) and (Attach_PNGs.Count > 0) then
          begin
            for CurAttch := 0 To Attach_PNGs.Count - 1 do
              HtmlFiles.Add(Attach_PNGs.Strings[CurAttch]);
          end;

          FillMessage(AMsg);
        finally
          Free;
        end;

        SMTP.Connect;
        try
          SMTP.Send(AMsg);
          Result := True;
        finally
          SMTP.Disconnect;
        end;
      finally
        SMTP.Free;
      end;
    finally
      Attach_PNGs.Free;
    end;
  except
    on E: Exception do
    begin
      AddMsgToEventLog('', J_FirstFileName(ParamStr(0)), 'Fail send SMPT Mail, Error :' + e.Message, EVENTLOG_ERROR_TYPE, 4, 1);
      Result := False;
    end;
  end;
end;

 

Edited by Remy Lebeau

Share this post


Link to post
Posted (edited)
1 hour ago, Remy Lebeau said:

I will leave sending PNGs from memory as an exercise for you

Thanks Remy. no doubt your code is more efficient.
but on save the base64 as PNG is not the right way.
the base 64 is string depend on the file type.

i work with Envision https://www.intervalsoftware.com/envision.html
So i load any one of the type with appropriate object and convert it all to PNG, create the PNG, load it to the Html Files of the mail body and send the mail.

 

You are the MASTER.

UDDF - Tao of Programming.mht

Edited by mazluta

Share this post


Link to post
Posted (edited)
1 hour ago, Remy Lebeau said:

I will leave sending PNGs from memory as an exercise for you

Here is a hint: you can save a PNG to a TMemoryStream using TPngImage.SaveToStream(), and then attach it to the email using the TStream overload of the TIdMessageBuilderHtml.HtmlFiles.Add() method.

7 minutes ago, mazluta said:

but on save the base64 as PNG is not the right way.
the base 64 is string depend on the file type.

i work with Envision https://www.intervalsoftware.com/envision.html
so i convert all types to PNG, create the PNG, load it to the HtmlFiles of the mail body and send the mail.

If you read the code I just gave you, it does exactly that.  It is the same logic you posted earlier, I just reorganized and simplified it.

Edited by Remy Lebeau

Share this post


Link to post
1 minute ago, Remy Lebeau said:

it does exactly that

you right. sorry.

 PngGraphic := TPngGraphic.Create;
    try
      DibGraphic := TDibGraphic.Create;
      try
        Result := Base64ToImg(Base64Str, DibGraphic, FileExtn);
        if not Result then Exit;
        PngGraphic.Assign(DibGraphic);
      finally
        DibGraphic.Free;
      end;
      if PngGraphic.Empty then Exit;

did you read the TAO? it's old as the wheel of time......

 

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×