Jan Wytze
Jan Wytze

Reputation: 3497

convert base64 to bitmap

I try to convert a base64 string to bitmap but then i get a black image.. This is the script that i use to decode:

function Base64ToBitmap(const S: string): TBitmap;
var
SS: TStringStream;
V: string;
begin
V := Decode(S);
SS := TStringStream.Create(V);
try
Result := TBitmap.Create;
Result.LoadFromStream(SS);
finally
SS.Free;
end;
end;

This is the decode script:

function Decode(const Input: AnsiString): string;
var
  bytes: TBytes;
  utf8: UTF8String;
begin
  bytes := EncdDecd.DecodeBase64(Input);
  SetLength(utf8, Length(bytes));
  Move(Pointer(bytes)^, Pointer(utf8)^, Length(bytes));
  Result := string(utf8);
end;

BitMap to base64

function BitmapToBase64(ABitmap: TBitmap): string;
var
SS: TStringStream;
V: string;
begin
SS := TStringStream.Create('');
try
ABitmap.SaveToStream(SS);
V := SS.DataString;
Result := Encode(V);
finally
SS.Free;
end;
end;

Encode:

function Encode(const Input: string): AnsiString;
var
  utf8: UTF8String;
begin
  utf8 := UTF8String(Input);
  Result := EncdDecd.EncodeBase64(PAnsiChar(utf8), Length(utf8));
end;

Why i get a black screen? the base64 string is a screenshot.

Upvotes: 3

Views: 15506

Answers (2)

Ali Reza Nazari
Ali Reza Nazari

Reputation: 41

if base64 encoded from tbitmap stream :

  Function Decode_Base64_to_bitmap (imgstr: String ): Tbitmap;
    VaR
      SS: tstringstream;
      MS: tmemorystream;
      Bitmap: tbitmap;
    Begin
      SS: = Tstringstream. Create (imgstr );
      MS: = Tmemorystream. Create;
      TBase64Encoding.Base64String.Decode(SS, MS ); // Restore base64 streams to memory streams
      Ms. Position: = 0 ;
      Bitmap: = Tbitmap. Create;
      Bitmap. loadfromstream (MS );
      SS. Free;
      Ms. Free;
      Result: = Bitmap;
    End ;

if base64 encoded from jpeg file or stream

// Converts a base64 string (jpeg) to A Bitmap bitmap.
  Function Stringtobitmap (imgstr: String ): Tbitmap;
    VaR
      SS: tstringstream;
      MS: tmemorystream;
      Jpg : TJpegImage;
      Bitmap: tbitmap;
    Begin
      SS := Tstringstream. Create (imgstr );
      MS := Tmemorystream. Create;
      try
        TBase64Encoding.Base64String.Decode(SS, MS ); // Restore base64 streams to memory streams
      finally
      end;
      Ms. Position := 0 ;
      Jpg := TJpegImage.Create;
      Bitmap := Tbitmap. Create;
      try
        Jpg.LoadFromStream( MS );
        Bitmap.Assign(Jpg);
      finally

      end;
      Jpg.Free;
      SS. Free;
      Ms. Free;
      Result := Bitmap;
    End ;

Upvotes: 0

David Heffernan
David Heffernan

Reputation: 613451

Your code is needlessly complex. This is all you need:

{$APPTYPE CONSOLE}

uses
  System.SysUtils,
  System.Classes,
  Vcl.Graphics,
  Soap.EncdDecd;

function Base64FromBitmap(Bitmap: TBitmap): string;
var
  Input: TBytesStream;
  Output: TStringStream;
begin
  Input := TBytesStream.Create;
  try
    Bitmap.SaveToStream(Input);
    Input.Position := 0;
    Output := TStringStream.Create('', TEncoding.ASCII);
    try
      Soap.EncdDecd.EncodeStream(Input, Output);
      Result := Output.DataString;
    finally
      Output.Free;
    end;
  finally
    Input.Free;
  end;
end;

function BitmapFromBase64(const base64: string): TBitmap;
var
  Input: TStringStream;
  Output: TBytesStream;
begin
  Input := TStringStream.Create(base64, TEncoding.ASCII);
  try
    Output := TBytesStream.Create;
    try
      Soap.EncdDecd.DecodeStream(Input, Output);
      Output.Position := 0;
      Result := TBitmap.Create;
      try
        Result.LoadFromStream(Output);
      except
        Result.Free;
        raise;
      end;
    finally
      Output.Free;
    end;
  finally
    Input.Free;
  end;
end;

var
  Bitmap: TBitmap;
  s: string;

begin
  Bitmap := TBitmap.Create;
  Bitmap.SetSize(100,100);
  Bitmap.Canvas.Brush.Color := clRed;
  Bitmap.Canvas.FillRect(Rect(20, 20, 80, 80));
  s := Base64FromBitmap(Bitmap);
  Bitmap.Free;
  Bitmap := BitmapFromBase64(s);
  Bitmap.SaveToFile('C:\desktop\temp.bmp');
end.

Upvotes: 12

Related Questions