Base64 encode and decode images in Delphi¶
Quite some time ago, I blogged about how to encode and decode data as Base64. The post is still accessed on a regular basis. However, I have received a question multiple times and want to provide the solution: How can images be encoded and decoded?
The key lies in the polymorphism of TPicture
that allows you to implement a solution that is not even depending on one file format. Developers often make the mistake to use TBitmap . At that moment you become set on bitmaps.
The solution I present here will allow you to encode any binary data as Base64. In order to encode images, one has to write the image data as binary. Obviously, we do not interpret the file format at any time. Still, it is possible to display the image after decoding as the VCL is pretty smart 😉
Let’s build a VCL Form application with the following main form:
I used a TAdvMemo
from TMS Software as it shows line numbers and a gutter. It looks nicer, but can also be replaced with a standard TMemo
in this case.
The two buttons will either load an image and generate the Base64 encoded text in the memo or load a Base64 text and show the decoded image.
Here’s the source code for encoding the image file:
procedure TFrmMain.btnLoadImageClick(Sender: TObject);
var
LInput : TMemoryStream;
LOutput: TMemoryStream;
begin
// show open file dialog
if
dlgOpen.Execute then
begin
// load image into image component (TPicture)
Image.Picture.LoadFromFile(dlgOpen.FileName);
LInput := TMemoryStream.Create;
LOutput := TMemoryStream.Create;
// write picture to stream and encode
try
Image.Picture.SaveToStream(LInput);
LInput.Position := 0;
TNetEncoding.Base64.Encode( LInput, LOutput );
LOutput.Position := 0;
Memo.Lines.LoadFromStream( LOutput );
finally
LInput.Free;
LOutput.Free;
end;
end;
end;
We use the TPicture
property of the TImage
component on the form. Of course, we could use a TPicture
object that we create ourselves as well to make the method independent of our GUI. However, for a demo this will suffice. Key is to save the picture to the stream. Do not use a bitmap, etc. – use TPicture
. The Base64 algorithm does not care for the input as long as it is a TStream . The memo then loads the data from the stream to display it.
The other direction works just the same way:
procedure TFrmMain.btnLoadTextClick(Sender: TObject);
var
LInput: TMemoryStream;
LOutput: TMemoryStream;
begin
if dlgOpen.Execute then
begin
Memo.Lines.LoadFromFile(dlgOpen.FileName);
LInput := TMemoryStream.Create;
LOutput := TMemoryStream.Create;
try
Memo.Lines.SaveToStream(LInput);
LInput.Position := 0;
TNetEncoding.Base64.Decode( LInput, LOutput );
LOutput.Position := 0;
Image.Picture.LoadFromStream(LOutput);
finally
LInput.Free;
LOutput.Free;
end;
end;
end;
Encode
, we call Decode
for the Base64 class, of course. Otherwise, we load the text into the memo, save its contents to a stream and then decode that stream. The stream then is loaded into the TPicture
property.
Again, be aware that this works for PNG, JPEG, … or whatever file format you include in your binary. For this demo, I included the following units in my project file so that I can use JPEG and PNG:
Of course, the Base64 encoding classes are found in theSystem.NetEncoding
unit:
Here’s an example what an encoding of a picture looks like: