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

如何消除C++/WinRT中使用GDI打印Bitmap时的细黑边?

打印Bitmap出现细黑边的原因及解决方法

原因分析

  1. Rectangle函数的绘制边界特性:
    Rectangle(hdc_bitmap, 0, 0, width, height) 的绘制逻辑是右边界和下边界独占——实际填充的区域仅到(width-1, height-1),最右侧一列和最底部一行像素未被白色画刷覆盖,保留了Bitmap创建时的默认黑色,最终打印时呈现为细黑边。

  2. 打印机可打印区域的潜在影响:
    GetDeviceCaps获取的HORZRES/VERTRES是整张纸的像素尺寸,但绝大多数打印机存在不可打印边距。直接按全纸尺寸绘制打印,部分边缘内容可能被打印机裁剪,或驱动自动调整时产生黑边。

解决方法

方法1:替换Rectangle为FillRect/PatBlt(彻底解决边界未填充问题)

放弃Rectangle,改用能完整填充指定区域的函数:

  • 使用FillRect:
RECT rect = {0, 0, width, height};
FillRect(hdc_bitmap, &rect, hbrush);
  • 或使用PatBlt:
PatBlt(hdc_bitmap, 0, 0, width, height, PATCOPY);

这两个函数会完整覆盖0到width、0到height的所有像素,不会留下未填充边缘。

方法2:修正Rectangle的参数

若坚持使用Rectangle,需将右、下边界各加1,确保覆盖全部像素:

Rectangle(hdc_bitmap, 0, 0, width + 1, height + 1);

方法3:适配打印机可打印区域(避免裁剪黑边)

获取打印机实际可打印的尺寸与偏移,调整绘制目标:

// 获取可打印区域的偏移和有效尺寸
int printOffsetX = GetDeviceCaps(hdc_printer, PHYSICALOFFSETX);
int printOffsetY = GetDeviceCaps(hdc_printer, PHYSICALOFFSETY);
int printWidth = GetDeviceCaps(hdc_printer, PHYSICALWIDTH) - 2 * printOffsetX;
int printHeight = GetDeviceCaps(hdc_printer, PHYSICALHEIGHT) - 2 * printOffsetY;

// 创建适配可打印区域的Bitmap
HBITMAP bitmap = CreateBitmap(printWidth, printHeight, 1, 32, NULL);
// 绘制时偏移到可打印区域起点
BitBlt(hdc_printer, printOffsetX, printOffsetY, printWidth, printHeight, hdc_bitmap, 0, 0, SRCCOPY);

额外注意事项

  • 操作GDI对象时必须保存旧对象并恢复,避免资源泄漏:
HBRUSH oldBrush = (HBRUSH)SelectObject(hdc_bitmap, hbrush);
// 执行绘制操作
SelectObject(hdc_bitmap, oldBrush);
DeleteObject(hbrush);
  • 确保hdc_bitmap正确关联创建的bitmap,代码中注释的SelectObject(hdc_bitmap, bitmap)需要实际执行,否则绘制目标并非预期Bitmap。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 06:05:00