Reputation: 1760
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 (48x48).
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:
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.
Upvotes: 2
Views: 1657
Reputation: 1760
There is no need to make any conversion.
Following David Heffernan information that TBitmap in FMX recognizes the PNG format naturally I have found that the error was in the way I was calling my AssignResource function:
procedure TEntity.AssignResource(AName: String; ABlob: TBlob);
however this is the correct:
procedure TEntity.AssignResource(AName: String; VAR ABlob: TBlob);
Making this change corrected the problems and weeks of searching and agony.
Upvotes: 2