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

FireMonkey中如何捕获包含TText的TLayout为Bitmap?

解决FireMonkey中TLayout捕获TText控件的问题

在RAD Studio 12的FireMonkey项目中,直接使用TLayout.PaintTo或MakeScreenshot无法捕获TText控件的原因是:TText属于轻量级的TGraphicControl子类,这类控件的绘制逻辑与TLabel(TControl子类)不同,默认的PaintTo方法不会自动触发其绘制流程。以下是两种可行的解决方法:

方法一:使用RenderToBitmap方法(推荐)

FireMonkey从RAD Studio 10.4开始提供了TControl.RenderToBitmap方法,专门用于将控件及其所有层级的子控件完整渲染到位图中,能完美处理TText这类轻量级控件。

C++代码示例:

#include <FMX.Controls.hpp>
#include <FMX.Graphics.hpp>

TBitmap* CaptureFullLayout(TLayout* TargetLayout)
{
    if (!TargetLayout || !TargetLayout->Visible)
        return nullptr;

    TBitmap* ResultBmp = new TBitmap();
    try
    {
        // 设置位图尺寸与布局一致
        ResultBmp->SetSize(TargetLayout->Width, TargetLayout->Height);
        // 渲染布局及其所有子控件到位图
        TargetLayout->RenderToBitmap(
            ResultBmp,
            TargetLayout->BoundsRect,  // 源区域(布局自身范围)
            TRectF(0, 0, TargetLayout->Width, TargetLayout->Height)  // 目标区域(位图范围)
        );
        return ResultBmp;
    }
    catch (...)
    {
        delete ResultBmp;
        throw;
    }
}

使用时直接调用该函数,获取返回的TBitmap后即可保存或使用,记得使用完后手动释放内存。

方法二:手动递归绘制所有控件

如果需要兼容旧版本(或自定义绘制逻辑),可以手动遍历布局的所有子控件,逐个调用PaintTo方法,确保所有层级的控件都被绘制。

C++代码示例:

#include <FMX.Controls.hpp>
#include <FMX.Graphics.hpp>

void PaintControlHierarchy(TControl* Control, TBitmap* DestBmp, const TRectF& DestRect)
{
    if (!Control || !Control->Visible || !DestBmp)
        return;

    // 绘制当前控件
    Control->PaintTo(DestBmp->Canvas, DestRect);

    // 递归绘制所有子控件
    for (int i = 0; i < Control->ChildrenCount; ++i)
    {
        TControl* ChildCtrl = static_cast<TControl*>(Control->Children[i]);
        TRectF ChildSrc = ChildCtrl->BoundsRect;
        // 计算子控件在目标位图中的位置
        TRectF ChildDest(
            DestRect.Left + ChildSrc.Left,
            DestRect.Top + ChildSrc.Top,
            DestRect.Left + ChildSrc.Right,
            DestRect.Top + ChildSrc.Bottom
        );
        PaintControlHierarchy(ChildCtrl, DestBmp, ChildDest);
    }
}

TBitmap* CaptureLayoutManual(TLayout* TargetLayout)
{
    if (!TargetLayout || !TargetLayout->Visible)
        return nullptr;

    TBitmap* ResultBmp = new TBitmap();
    ResultBmp->SetSize(TargetLayout->Width, TargetLayout->Height);
    PaintControlHierarchy(TargetLayout, ResultBmp, TRectF(0, 0, TargetLayout->Width, TargetLayout->Height));
    return ResultBmp;
}

额外注意事项

  • 确保TText控件的Visible属性为true,Opacity为1,且没有被其他控件完全遮挡;
  • 如果需要捕获整个窗体,直接将上述代码中的TLayout替换为TForm即可,逻辑完全通用;
  • 使用完TBitmap后务必调用delete释放内存,避免内存泄漏。

内容的提问来源于stack exchange,提问作者Barry Andrews

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 00:42:33