Home General
New Blog Posts: Merging Reports - Part 1 and Part 2

Base64 image to report using TDBImage

Hello!

I have a MySQL database that saves customer signatures as base64 BLOB field. Is there a way to show that data as an image on the report using TDBImage?

Comments

  • Hi Marko,

    You can use the TDBImage.OnGetPicture event to get the image data before it is assigned to the Picture property. Inside this event, you would need to retrieve the encoded image data, decode it, and assign it to the aPicture parameter.

    ReportBuilder does not have the ability to decode base64 data automatically. When needed, we use the NetEncoding routines to do so:
    TNetEncoding.Base64.DecodeStringToBytes(Value);
    Best Regards,

    Nico Cizik
    Digital Metaphors
    http://www.digital-metaphors.com
  • edited January 28
    I try to add the mentioned code as this:
    procedure DBImage1OnGetPicture(aPicture: TPicture);
    begin
      aPicture.Assign(TNetEncoding.Base64.DecodeStringToBytes(Dokument['StrankaPodpis']));
    end;
    But I have an error "Undeclared identifier TNetEncoding".

    I tried with a TStream, but also have a problem RB not knowing TMemoryStream.
    procedure DBImage1OnGetPicture(aPicture: TPicture);
    var
      Strm: TMemoryStream;
      ImgData: TBytes;
    begin
      Strm := TMemoryStream.Create;
    
      ImgData := Base64Enc.DecodeStringToBytes(Dokument['StrankaPodpis']));
      Strm.WriteData(ImgData, Length(ImgData));
      Strm.Position := 0;
    
      aPicture.LoadFromStream(Strm);
    end;
    
    How do I add uses System.NetEncoding, to the RP template?

  • edited January 29
    Hi Marko,

    It appears you are trying to accomplish this in RAP. RAP does not support the complete Delphi object library so pass-thru function(s) will need to be used to decode the image data. See the main RAP demo for how to implement RAP Pass-thru functions.

    My suggestion is to get this working in Delphi first to be sure the streaming and decoding is functioning correctly. Then move your code to RAP including pass-thru functions for the unsupported aspects (TNetEncoding, TMemoryStream, etc.).
    Best Regards,

    Nico Cizik
    Digital Metaphors
    http://www.digital-metaphors.com
  • yes, I understood that I need to do this in RAP. Thank you for the extra informations, I will check the demo and documentation.
  • Hello,
    just read this.

    I once had a case where base64 data was stored in memo/text fields.

    So, I created a RAP system function, placed an image component on the form, and then passed both the base64 string and the image component to a function.

    TmyUserGetBase64ToPicture = class (TraSystemFunction)
    public
    class function Category: string; override;
    end;

    TmyGetUserGetBase64ToPicture = class (TmyUserGetBase64ToPicture)
    procedure ExecuteFunction(aParams: TraParamList); override;
    class function GetSignature: string; override;
    end;

    class function TmyGetUserGetBase64ToPicture.GetSignature: string;
    begin
    result := 'function GetBase64ToPicture(b64string:string; var myPicture:TPicture):Boolean;';
    end;

    class function TmyUserGetBase64ToPicture.Category: string;
    begin
    result := 'MyFuncs' ;
    end;

    procedure TmyGetUserGetBase64ToPicture.ExecuteFunction(aParams: TraParamList);
    var
    cString: string;
    myPicture: TPicture;
    lbResult: boolean;
    begin
    GetParamValue(0, cString);
    GetParamValue(1, myPicture);

    myPicture.Bitmap := nil;
    if cString <> '' then
    begin
    lbResult := GetBase64ToPicture(cString, myPicture);
    end
    else lbResult := False;

    SetParamValue(0, cString);
    SetParamValue(1, myPicture);
    SetParamValue(2, lbResult);
    end;

    Function to Decode Base64 and Assign to TPicture

    function GetBase64ToPicture(const b64string: string; var myPicture: TPicture): Boolean;
    var
    DecodedBytes: TBytes;
    ByteStream: TBytesStream;
    Base64Content: string;
    CommaPos: Integer;
    begin
    Result := False;

    // Check if there is a data URL prefix and remove it if necessary
    CommaPos := Pos(',', b64string);
    if CommaPos > 0 then
    Base64Content := Copy(b64string, CommaPos + 1, MaxInt)
    else
    Base64Content := b64string;

    // Decode base64 string into bytes
    DecodedBytes := TNetEncoding.Base64.DecodeStringToBytes(Base64Content);

    // Convert bytes to a stream and load into TPicture
    ByteStream := TBytesStream.Create(DecodedBytes);
    try
    myPicture.LoadFromStream(ByteStream);
    Result := True;
    finally
    ByteStream.Free;
    end;
    end;

    Then, the base64 string is read into the image (TPicture) component.

    Hope this helps!

    Best Regards,
    Ralf
Sign In or Register to comment.