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

如何在TSkPaintBox的Canvas上显示相机捕获的图片?当前实现无效

问题分析与解决方案

你的代码存在核心API误用,导致无法显示图片:

  • 你调用的SkPaintBox1.Canvas.LoadFontFromStream(LStream)是用来加载字体文件(如TTF)的方法,和加载、显示图片完全无关,这是根本错误。
  • TSkPaintBox基于Skia引擎,需要使用Skia的图像类和绘制API来处理图片,不能直接用VCL的TBitmap操作Skia画布。

修正步骤

1. 新增字段保存捕获的图片

在窗体类的私有区域添加字段,用于存储相机捕获的Skia格式图片:

private
  FCapturedBitmap: TSkBitmap;

2. 修改相机回调方法

将相机返回的TBitmap转换为Skia的TSkBitmap,并触发PaintBox重绘:

procedure TMyPhotoEdit.ActionCameraDidFinishTaking(Image: TBitmap);
var
  LTempSkBitmap: TSkBitmap;
begin
  // 释放旧的图片资源
  FCapturedBitmap?.Free;
  
  // 将VCL的TBitmap转换为Skia位图
  LTempSkBitmap := TSkBitmap.Create;
  try
    LTempSkBitmap.Assign(Image);
    FCapturedBitmap := LTempSkBitmap.Clone;
  finally
    LTempSkBitmap.Free;
  end;
  
  // 触发PaintBox重绘,执行OnPaint事件
  SkPaintBox1.Invalidate;
end;

3. 实现PaintBox的OnPaint事件

在SkPaintBox的OnPaint事件中绘制保存的图片:

procedure TMyPhotoEdit.SkPaintBox1Paint(Sender: TObject; const Canvas: ISkCanvas);
var
  DrawRect: TRectF;
begin
  if Assigned(FCapturedBitmap) then
  begin
    // 计算绘制区域,按PaintBox尺寸自适应(保持图片比例)
    DrawRect := TRectF.Create(0, 0, SkPaintBox1.Width, SkPaintBox1.Height);
    // 居中、按比例绘制图片,使用高质量滤镜
    Canvas.DrawBitmap(FCapturedBitmap, nil, DrawRect, 1, TSkFilterQuality.High);
  end;
end;

4. 清理资源(可选)

在窗体销毁时释放图片资源,避免内存泄漏:

procedure TMyPhotoEdit.FormDestroy(Sender: TObject);
begin
  FCapturedBitmap?.Free;
end;

内容的提问来源于stack exchange,提问作者Martin Kakhuis

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 23:12:22