You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

技术求助:如何将FMX.TImage赋值给VCL.TBitmap?

嗨,这个问题我之前踩过坑!FMX的TImage和VCL的TBitmap属于Delphi里两套完全独立的UI框架体系,它们的底层内存布局、像素处理逻辑完全不一样,直接跨框架操作肯定会出问题。下面给你几个实用的解决思路:

解决FMX Image与VCL Bitmap互操作的问题

1. 通用格式中转(最稳妥的方案)

把VCL的位图转成PNG、JPEG这类通用图像格式,再加载到FMX的Image组件里,反过来操作也适用。示例代码:

// VCL BMP 转 FMX Image
var
  VCLBmp: VCL.Graphics.TBitmap;
  MemStream: TMemoryStream;
  FMXBitmap: FMX.Graphics.TBitmap;
begin
  VCLBmp := VCL.Graphics.TBitmap.Create;
  try
    // 假设这里已经给VCLBmp填充了图像内容
    MemStream := TMemoryStream.Create;
    try
      VCLBmp.SaveToStream(MemStream);
      MemStream.Position := 0;
      
      FMXBitmap := FMX.Graphics.TBitmap.Create;
      try
        FMXBitmap.LoadFromStream(MemStream);
        Image1.Bitmap := FMXBitmap;
      finally
        FMXBitmap.Free;
      end;
    finally
      MemStream.Free;
    end;
  finally
    VCLBmp.Free;
  end;
end;

2. 直接像素内存复制(追求性能的选择)

如果对性能要求高,可以直接复制像素数据,但要提前对齐两者的像素格式(比如都用32位BGRA),不然会出现颜色错乱或者内存访问错误。示例代码:

// 前提:确保VCLBmp和FMXBitmap的尺寸、像素格式一致
var
  VCLScanLine, FMXScanLine: PByte;
  RowIdx: Integer;
begin
  FMXBitmap.SetSize(VCLBmp.Width, VCLBmp.Height);
  FMXBitmap.PixelFormat := TPixelFormat.BGRA;
  VCLBmp.PixelFormat := pf32bit;

  for RowIdx := 0 to VCLBmp.Height - 1 do
  begin
    VCLScanLine := VCLBmp.ScanLine[RowIdx];
    FMXScanLine := FMXBitmap.Scanline[RowIdx];
    // 复制整行的像素数据
    Move(VCLScanLine^, FMXScanLine^, VCLBmp.Width * 4);
  end;
  Image1.Bitmap := FMXBitmap;
end;

3. 统一框架处理(从根源避免问题)

如果你的项目同时用到FMX和VCL,尽量把图像相关的逻辑统一到一个框架里:比如UI是FMX的,就全程用FMX的TBitmap;如果是VCL界面,就用VCL的位图对象,减少跨框架转换的麻烦。

补充:如果你的错误提示是“类型不兼容”或者“内存访问违规”,基本就是因为直接把VCL的BMP对象赋值给FMX Image了——这俩完全不是一个东西,必须走转换流程才行。

内容的提问来源于stack exchange,提问作者Error - CPU Not Foud

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 09:37:32