After dealing with Base64 images now I have a function that can convert PNG
After dealing with Base64 images now I have a function that can convert PNG,
last lines are:
Img.Picture.LoadFromStream(MemoryStream);
Bmp.Assign(Img.Picture.Graphic);
Where the MemoryStream var is the decoded data from string. Now make it work for sure I have to save it as file Bmp.SaveToFile(); But why I cannot simply return:
Result := Bmp ???
If I do that, I get no error, but the image won't show.
Function returning is a TBitmap type.
last lines are:
Img.Picture.LoadFromStream(MemoryStream);
Bmp.Assign(Img.Picture.Graphic);
Where the MemoryStream var is the decoded data from string. Now make it work for sure I have to save it as file Bmp.SaveToFile(); But why I cannot simply return:
Result := Bmp ???
If I do that, I get no error, but the image won't show.
Function returning is a TBitmap type.
Does calls that measure size / bit'edness / encoding / etc of the bmp - work ok?
ReplyDeleteLars Fosdal No. My lack of understanding says that if I am loading from the memory stream, assign to a TBitmap object (Bmp) it is already a valid one, or should. Really don't know how to solve that, seems to be very easy but it is not
ReplyDeleteShow your code.
ReplyDeleteReset the original stream's position to zero. It's caught me off guard so many times.
ReplyDeleteAchim Kalwa Here code, I don't want to need to save and load it:
ReplyDeletefunction ImgBase64ToBitmap(FileName, sBase64: AnsiString): TImage;
var
MS: TMemoryStream;
Decode: TIdDecoderMIME;
Img: TImage;
begin
Img := TImage.Create(nil);
MS := TMemoryStream.Create;
try
Decode := TIdDecoderMIME.Create;
try
Decode.DecodeBegin(MS);
Decode.Decode(sBase64);
Decode.Decode(MS);
Decode.DecodeEnd();
MS.Position := 0;
Img.Picture.LoadFromStream(MS);
MS.Position := 0; // dahh
Result := Img;
// ** I DON'T want it...
MS.SaveToFile(Concat(FileName, '.png'));
finally
Decode.Free;
end;
finally
MS.Free;
Img.Free;
end;
end;
Andrea Raimondi I tried, but maybe at the incorrect place...
ReplyDeleteI was able to do it by changing the function to procedure and doing that:
ReplyDeleteImgBase64ToBitmap(FileName, sBase64: AnsiString; var MemoryStream: TMemoryStream);
So, now I get a new parameter (MemoryStream) and the main code is like:
MS := TMemoryStream.Create;
ImgBase64ToBitmap('imageBase64', sImg, MS);
ImageCode64.Picture.LoadFromStream(MS);
MS.Free;
But I don't know if it is a good approach, at least it's working.
Magno Lima the reason why you function does not work is in the finally block: You free Img, but it is the function result. Better rename the function to CreateImageFromBase64 and do not free Img in the finally block.
ReplyDeleteThe calling code is responsible for destroying the image object.
Achim Kalwa So my newest version works because of that, the Img object I am passing as var parameter. Thank you for the answer.
ReplyDelete