如何从TBlob到TBitmap制作LiveBinding转换器

时间:2014-08-13 00:58:27

标签: delphi firemonkey delphi-xe6 livebindings

我的软件主要基于Firemonkey TListView,它是根据Delphi Samples项目中的“SampleListViewMultiDetailAppearanceProject”定制的。

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

这就是使用PrototypeBindSource:

的样子

TListView Sample

每条记录显示1张图片和4个文字项目。

我使用TMS Aurelius作为数据集,它连接到BindSource。它是使用所有标准字段类型的TDataset后代。

它实现了内部的TBlobField:

  TBlob = record
  private
    FIntData: TArray<byte>;

在DataSet上,此字段被定义为“like”一个计算字段,因为它是一个基于实体的框架(ORM),每个记录代表一个对象,但最后是相同的东西,检索的数据是一个带有原始的字段数据

我的目的是根据记录的某些状态设置从项目资源(项目 - >资源和图像)加载的不同图像。存储的图像是一个小的PNG图像(48x48)。

要读取从资源中存储的PNG图像我正在使用:

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;

当livebinding系统检索到TBlobField时,调用的函数是:

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

  result := FImage;
end;

FImage是一种带有一些辅助功能的TBlob类型,但就像我说的是TArray并且没有任何类型的处理,只是一个容器。

因此,FImage将直接进入FMX TListView的TBitmap。

没有任何反应,也没有显示图像。

我尝试过以下代码:

  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
    ));

从其他与图像无关的转换中获取此代码。但它显然是错误的,除了它汇编的事实。

此代码中的问题: - 它似乎已经注册,我放置了一个断点,并且RegisterConversion确实被执行了,但是在匿名过程中的一个断点永远不会被执行。我在创建包含TLisviews的任何帧之前在初始化部分注册了这个。 - 在匿名程序中,转换本身就是纯粹的虚构;因为我相信Blob存储为png,输出应该是fmx位图。我不知道在那里写什么。

该主题的文档很少,对我的理解没有帮助。

我想知道如何在此过程中正确制作序列:

  • 我需要从png转换为位图吗?怎么样?
  • 我是否需要注册转换适配器?怎么样?为什么不被解雇?
  • 此转换适配器中的正确转换代码是什么?

OR

我看到TDataset上有一个ftGraphic TField,我可以创建一个这种类型的字段。但是存在这样的问题: - 这种类型的预期TField回报是多少? - 我的代码在平台之间共享:VCL和FMX,TBitMap或TGraphic两者都不一样。这种共享是由一个没有作用域的bpl包完成的。这是必要的,因为我注册了其他bpls的冲突。我有一个共享的共同bpl和其他使用它的平台特定bpl。

由于我还没有找到解决这个bpl共享和平台单元不兼容的方法,我切换到了第一个选项,尝试在数据库级别处理原始数据,并让转换发生在livebinding级别,已经在域中每个平台

我是一个完全无知的与图像相关的操作,特别是在转换和正确的对象创建时,以避免内存泄漏。

重要提示:它必须是跨平台的,因为fmx应用程序是在android上使用的。

1 个答案:

答案 0 :(得分:1)

无需进行任何转换。

根据David Heffernan的信息,FMX中的TBitmap自然地识别出PNG格式,我发现错误与我调用我的AssignResource函数的方式有关:

procedure TEntity.AssignResource(AName: String; ABlob: TBlob);

然而这是正确的:

procedure TEntity.AssignResource(AName: String; VAR ABlob: TBlob);

进行此项更改可以纠正问题和数周的搜索和痛苦。