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

DirectWrite使用Clear()方法实现标签透明背景的问题

问题

背景

需要禁用Windows系统的屏幕字体平滑边缘设置,路径为:控制面板 > 系统和安全 > 系统 > 高级系统设置 > 高级选项卡 > 性能区域 > 设置 > 视觉效果选项卡 > 屏幕字体平滑边缘。

当前问题

禁用该设置后,系统字体均无平滑效果,但通过DirectWrite/Direct2D创建的标签仍能正常显示平滑字体。不过在调用DrawText()前使用Clear()设置透明背景(代码:_d2d1DeviceContext->Clear(D2D1::ColorF(D2D1::ColorF::White, 0.0f)))时,标签背景会显示为黑色。

需求

  • 实现标签的透明背景
  • 保留使用ID2D1Bitmap1获取像素数据的方式,用于在Rogue Wave Views框架中创建IlvBitmap()并显示在面板上

已尝试方案

  • 使用DirectWrite的图层推入/弹出机制,问题依旧,背景还是黑色
  • 自定义继承自IDWriteTextRenderer的GlyphRunHandler类,实现QueryInterface()和DrawGlyphRun()方法,但未生效

解决方案

1. 确保Bitmap和渲染目标支持Alpha通道

黑色背景的核心原因是创建ID2D1Bitmap1或渲染目标时未启用Alpha通道支持,透明区域被默认填充为黑色。需调整创建参数:

配置渲染目标

D2D1_RENDER_TARGET_PROPERTIES renderTargetProps = D2D1::RenderTargetProperties(
    D2D1_RENDER_TARGET_TYPE_DEFAULT,
    D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED),
    0.0f,
    0.0f
);

创建支持Alpha的Bitmap

D2D1_BITMAP_PROPERTIES1 bitmapProps = D2D1::BitmapProperties1(
    D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW,
    D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED),
    dpiX,
    dpiY
);

2. 优化透明背景渲染流程

避免直接调用Clear()设置全透明,改用轴对齐裁剪图层控制绘制区域,确保透明区域不被填充:

// 推入裁剪图层,限定绘制范围
_d2d1DeviceContext->PushAxisAlignedClip(
    D2D1::RectF(0, 0, bitmapWidth, bitmapHeight),
    D2D1_ANTIALIAS_MODE_PER_PRIMITIVE
);

// 关闭文本抗锯齿,匹配系统禁用平滑的设置
_d2d1DeviceContext->SetTextAntialiasMode(D2D1_TEXT_ANTIALIAS_MODE_NONE);

// 绘制文本
_d2d1DeviceContext->DrawText(
    L"目标标签文本",
    wcslen(L"目标标签文本"),
    _pTextFormat,
    D2D1::RectF(10, 10, bitmapWidth-10, bitmapHeight-10),
    _pBrush
);

// 弹出裁剪图层
_d2d1DeviceContext->PopAxisAlignedClip();

3. 正确传递像素数据到IlvBitmap

读取ID2D1Bitmap1的像素数据时,确保获取包含Alpha通道的完整数据,创建IlvBitmap时指定RGBA格式:

// 分配4通道像素缓冲区(BGR+Alpha)
BYTE* pixelBuffer = new BYTE[bitmapWidth * bitmapHeight * 4];
// 从Bitmap读取像素数据
_d2d1Bitmap->CopyFromMemory(nullptr, pixelBuffer, bitmapWidth * 4);

// 创建带透明通道的IlvBitmap
IlvBitmap* panelBitmap = new IlvBitmap(
    bitmapWidth,
    bitmapHeight,
    IlvRGBAPixelFormat,
    pixelBuffer,
    IlvTrue
);

// 记得释放缓冲区
delete[] pixelBuffer;

4. 同步系统字体平滑设置

如果需要让DirectWrite文本与系统字体保持一致(无平滑),需在文本格式中明确关闭抗锯齿:

_pTextFormat->SetTextAntialiasMode(DWRITE_TEXT_ANTIALIAS_MODE_NONE);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 01:35:15