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

如何在Delphi FireMonkey中用Skia4Delphi绘制4K/8K屏清晰文本?

在Delphi FireMonkey中用Skia4Delphi实现4K/8K显示器清晰文本的最优方案

针对4K/8K高分辨率显示器,可通过以下几点优化提升文本清晰度:

  • 启用亚像素渲染与抗锯齿
    Skia默认渲染设置不足以适配高DPI屏幕,需显式开启抗锯齿和亚像素渲染,尤其是Windows平台的ClearType优化:

    LPaint.AntiAlias := True;
    LPaint.SubpixelText := True;
    LPaint.TextRenderingHint := TSkTextRenderingHint.ClearType;
    
  • 适配显示器DPI缩放比例
    FMX本身具备DPI感知能力,需将屏幕缩放因子同步到Skia的字体和绘制流程中,避免文本因缩放不匹配模糊:

    var LDpiScale: Single;
    begin
      LDpiScale := Screen.Scale;
      // 调整字体大小适配DPI
      id.font.Size := id.font.Size * LDpiScale;
      // 绘制时应用缩放矩阵(需同步调整坐标)
      ACanvas.Save;
      ACanvas.Scale(LDpiScale, LDpiScale);
      // 绘制逻辑...
      ACanvas.Restore;
    end;
    
  • 使用可靠的文本Blob创建方法
    原代码的MakeFromText可能无法完整传递字体属性,改用MakeFromTextWithFont确保Skia使用正确的字体配置:

    LBlob := TSkTextBlob.MakeFromTextWithFont(id.value, id.font);
    
  • 优化文本位置计算
    基于Skia字体的基线(Baseline)而非文本Bounds计算垂直居中位置,避免像素偏移导致的模糊:

    var
      LMetrics: TSkFontMetrics;
      LTextWidth: Single;
    begin
      id.font.GetMetrics(LMetrics);
      LTextWidth := id.font.MeasureText(id.value, LPaint);
      tx := x + (w/2 - LTextWidth/2) / LDpiScale;
      ty := y + (h/2 + (LMetrics.Ascent - LMetrics.Descent)/2) / LDpiScale;
    end;
    
  • 设置画布正确DPI
    确保Skia画布的DPI与显示器物理DPI匹配:

    ACanvas.SetCanvasDPI(Screen.PixelsPerInch);
    

优化后的完整代码示例

var 
  LBlob: ISkTextBlob;
  LPaint: ISkPaint;
  LTextWidth: Single;
  LMetrics: TSkFontMetrics;
  tx, ty: Single;
  LDpiScale: Single;
begin
  LDpiScale := Screen.Scale;

  LPaint := TSkPaint.Create;
  LPaint.Color := TAlphaColors.Black;
  LPaint.Style := TSkPaintStyle.Fill;
  // 启用高清晰度渲染设置
  LPaint.AntiAlias := True;
  LPaint.SubpixelText := True;
  LPaint.TextRenderingHint := TSkTextRenderingHint.ClearType;

  // 适配DPI调整字体大小
  id.font.Size := id.font.Size * LDpiScale;

  // 获取字体度量与文本宽度
  id.font.GetMetrics(LMetrics);
  LTextWidth := id.font.MeasureText(id.value, LPaint);

  // 计算居中坐标(适配缩放后的画布)
  tx := x + (w/2 - LTextWidth/2) / LDpiScale;
  ty := y + (h/2 + (LMetrics.Ascent - LMetrics.Descent)/2) / LDpiScale;

  // 创建文本Blob
  LBlob := TSkTextBlob.MakeFromTextWithFont(id.value, id.font);

  // 应用DPI缩放绘制
  ACanvas.Save;
  ACanvas.Scale(LDpiScale, LDpiScale);
  ACanvas.DrawTextBlob(LBlob, tx, ty, LPaint);
  ACanvas.Restore;
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.07.02 23:47:05