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

标签 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 上,该字段的定义“类似于”计算字段,因为它是基于实体的框架 (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 转换为位图吗?如何?
  • 我需要注册转换适配器吗?如何?为什么没有被解雇?
  • 此转换适配器内的正确转换代码是什么?

或者

我看到 TDataset 上有一个 ftGraphic TField,我可以创建该类型的字段。但存在这样的问题: - 这种类型的预期 TField 返回是多少? - 我的代码在平台之间共享:VCL和FMX,并且TBitMap或TGraphic在这两个平台上不相同。此共享是由未限定范围的 bpl 包进行的。这是需要的,因为我注册的其他 bpls 存在冲突。我有一个共享的通用 bpl 和其他使用它的特定于平台的 bpl。

由于我还没有找到解决此 bpl 共享和平台单元不兼容问题的方法,因此我切换到第一个选项,尝试在数据库级别处理原始数据,并让转换发生在域中已经存在的实时绑定(bind)级别各平台的

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

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

最佳答案

无需进行任何转换。

根据 David Heffernan 的信息,FMX 中的 TBitmap 可以自然地识别 PNG 格式,我发现错误出在我调用分配资源函数的方式上:

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

但是这是正确的:

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

进行此更改解决了问题以及数周的搜索和痛苦。

关于delphi - 如何制作从 TBlob 到 TBitmap 的 LiveBinding 转换器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25276478/

相关文章:

delphi - 我可以修改RTL类System.Classes.TStream中的常量并在Delphi XE6运行时重建它吗?

algorithm - 需要用于 (GPS) 引导的精确并行测绘算法

delphi - 缩放像素值以进行打印

FireMonkey 的 HTML 查看器

delphi - VCL.图形库到FMX

delphi - 在单个函数期间禁用浮点异常

image - 如何从一个PNG复制另一个PNG?

delphi - 使用 Delphi Firemonekey 在 TImage 的 Canvas 上绘制一个圆圈

Delphi XE2 Firemonkey 示例应用程序无法在 MAC 上运行,dock 图标弹起但没有任何显示

delphi - 如何从 shell 中拖放文件?