mazluta 0 Posted August 12 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. 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
Alexander Sviridenkov 356 Posted August 12 Try to use width/height attrubutes instead of CSS. Share this post Link to post
mazluta 0 Posted August 12 i tried but with no help. it's look like outlook does what he want.... myTest-2.msg Share this post Link to post
Remy Lebeau 1392 Posted August 12 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: uSendSMTPMail.pas 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: myMail.html 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
mazluta 0 Posted August 12 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
Alexander Sviridenkov 356 Posted August 12 Image attributes are not correct h1XZgdBrJ2IOlrmq1SofeBwIdLyQHgGPgEfAIzCICNgIw6YHUZdhkvl//UZHbn5keAcAAAAASUVORK5CYII="; height="144px"; width="120px"; /></div> There should be no ; between attributes Share this post Link to post
Remy Lebeau 1392 Posted August 13 (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 August 13 by Remy Lebeau Share this post Link to post
Remy Lebeau 1392 Posted August 13 (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 August 13 by Remy Lebeau Share this post Link to post
mazluta 0 Posted August 13 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
Alexander Sviridenkov 356 Posted August 13 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
mazluta 0 Posted August 16 On 8/13/2024 at 5:00 AM, Remy Lebeau said: ...... Doubtful. 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
mazluta 0 Posted August 16 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
mazluta 0 Posted August 16 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
Remy Lebeau 1392 Posted August 16 (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 August 16 by Remy Lebeau Share this post Link to post
mazluta 0 Posted August 17 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
Remy Lebeau 1392 Posted August 18 (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 August 18 by Remy Lebeau Share this post Link to post
mazluta 0 Posted August 18 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
Remy Lebeau 1392 Posted August 19 (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 August 19 by Remy Lebeau Share this post Link to post
mazluta 0 Posted August 19 (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 August 19 by mazluta Share this post Link to post
Remy Lebeau 1392 Posted August 19 (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 August 19 by Remy Lebeau Share this post Link to post
mazluta 0 Posted August 19 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