How to make a LiveBinding converter from TBlob to TBitmap

  

My software is heavily based on Firemonkey TListView, that was customized based on the “SampleListViewMultiDetailAppearanceProject” found in the Delphi Samples project.

“C:\Users\Public\Documents\Embarcadero\Studio\14.0\Samples\Object Pascal\Mobile Samples\User Interface\ListView\”

This is how it looks like, using a PrototypeBindSource:

Each record shows up 1 image and 4 text items.

I am using TMS Aurelius as a dataset, that is connected to a BindSource. It is a TDataset descendant using all the standard field types.

It implements the TBlobField that internally is:

TBlob = record
private
FIntData: TArray<byte>;

On the DataSet this field is defined “like” a calculated field, since it is an entity based framework (ORM) each record represent an object, but at the end is the same stuff, the data retrieved is a field with raw data.

My intention is to set different images, loaded from the project resources (project->resources and images), according some state of the record. The image stored is a small PNG image (48×48).

To read the PNG image stored from resource I am using this:

procedure TEntity.AssignResource(AName: String; ABlob: TBlob);
var
InStream: TResourceStream;
begin
InStream := TResourceStream.Create(HInstance, AName, RT_RCDATA);
try
ABlob.LoadFromStream(InStream);
except
InStream.Free;
end;
end;

When the TBlobField is retrieved by the livebinding system, the function called is this:

function TEntity.GetImage: TBlob;
begin
if FImage.IsNull then
AssignResource(‘default’, FImage);

result := FImage;
end;

FImage is a TBlob type with some helper functionality, but like I said is a TArray and there is no processing of any type, just a container.

So, FImage is going directly to the TBitmap of the FMX TListView.

Nothing happens, no image is displayed.

I have tried the following code:

TValueRefConverterFactory.RegisterConversion(TypeInfo(TBlob), TypeInfo(TBitMap), TConverterDescription.Create(

procedure(const I: TValue; var O: TValue)
var
Blob: TBlob;
BitMap: TBitMap;
begin
Blob := I.AsType<TBlob>;

BitMap := O.AsType<TBitMap>;
end,

‘BlobToBitMap’ + GetTypeName(TypeInfo(TBlob)), ‘BlobToBitMap’ + GetTypeName(TypeInfo(TBitMap)), ‘Nahar.LiveBinding’, True, ”, nil
));

Got this code from other kind of conversion not related to image. But it is clearly wrong, besides the fact it compiles.

Problems in this code:
– it seems to get registered, I placed a breakpoint, and the RegisterConversion does get executed, but a breakpoint inside, in the anonymous procedure, is never executed. I am registering this on the initialization part before any frame is created that contains TLisviews.
– the conversion itself, in the anonymous procedure, is pure fiction; since I believe the Blob is stored as png and the output should be fmx bitmap. I have no idea what to write there.

The documentation is scarce on this topic and not helpful for my understanding.

I would like to know how to proper make the sequences on this process:

do I need to convert from png to bitmap? how?
do I need to have to register the conversion adapter? how? Why is not getting fired?
What is the correct conversion code inside this conversion adapter?

OR

I see there is a ftGraphic TField on TDataset, and I can create a field of that type. But there are this problems:
– What is the expected TField return for such type?
– My code is shared between platforms: VCL and FMX, and TBitMap or TGraphic are not the same on both. This sharing is made by a bpl package that is not scoped. It is needed since I was having conflicts of other bpls registered. I have one shared common bpl and others platform specific bpl that uses it.

Since I have not found a way to solve this bpl sharing and incompatibility of platform units I switched to the first option, trying to deal with raw data at database level, and letting the conversion happens at livebinding level, already in the domain of each platform

I am a complete ignorant related to image related manipulation specially when it comes to conversion and the correct object creation, to avoid memory leaking.

IMPORTANT: it has to be cross platform either, since the fmx application is used on android.

Comments are closed.