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

在GNOME/gdk/gtkmm/cairo下如何实现MS Windows TransparentBlt()等效功能

MFC TransparentBlt 移植到 gtkmm/Cairo 平台等效实现方案

gtkmm 原生的 copy_area() 方法不支持指定透明关键色,要实现和 MFC TransparentBlt() 一致的效果,可以选择以下两种适配方案:

方案一:预处理 Gdk::Pixbuf 加透明通道(兼容原有 copy_area 逻辑)

该方案适合不需要保留源位图原始内容的场景,性能更高,可直接复用现有代码逻辑:

// 定义你需要的透明关键色,这里对应示例中的RGB(255,255,255)白色
const guint8 key_r = 255, key_g = 255, key_b = 255;

// 先给不带alpha通道的源Pixbuf添加alpha通道,通道数会变成4
if (image1->get_n_channels() == 3) {
    image1 = image1->add_alpha(false, 0, 0, 0);
}

int rowstride = image1->get_rowstride();
guint8* pixels = image1->get_pixels();

// 遍历要复制的区域像素,匹配关键色的像素设为全透明
for (int y = 0; y < height; y++) {
    for (int x = 0; x < width; x++) {
        guint8* pixel = pixels + y * rowstride + x * 4;
        if (pixel[0] == key_r && pixel[1] == key_g && pixel[2] == key_b) {
            pixel[3] = 0; // alpha通道设为0,全透明
        } else {
            pixel[3] = 255; // 不透明
        }
    }
}

// 预处理完成后直接调用原有copy_area逻辑即可,透明像素会自动被跳过
image1->copy_area(0, 0, width, height, Total, position.x, position.y);

方案二:基于Cairo临时表面实现(不修改源位图)

如果需要保留源位图的原始内容,使用临时Cairo表面做中间处理即可:

// 目标上下文cr是对应TotalDC的Cairo::RefPtr<Cairo::Context>对象
const guint8 key_r = 255, key_g = 255, key_b = 255;

// 创建和源位图尺寸一致的临时ARGB表面
Cairo::RefPtr<Cairo::ImageSurface> temp_surface = Cairo::ImageSurface::create(
    Cairo::FORMAT_ARGB32, width, height
);
Cairo::RefPtr<Cairo::Context> temp_cr = Cairo::Context::create(temp_surface);

// 将源Pixbuf绘制到临时表面
Gdk::Cairo::set_source_pixbuf(temp_cr, image1, 0, 0);
temp_cr->paint();

unsigned char* surface_data = temp_surface->get_data();
int stride = temp_surface->get_stride();
// 遍历临时表面像素过滤关键色,注意Cairo ARGB32为小端存储,像素顺序为B、G、R、A
for (int y = 0; y < height; y++) {
    for (int x = 0; x < width; x++) {
        unsigned char* pixel = surface_data + y * stride + x * 4;
        if (pixel[2] == key_r && pixel[1] == key_g && pixel[0] == key_b) {
            pixel[3] = 0;
        }
    }
}

// 将处理后的临时表面绘制到目标位置
cr->set_source(temp_surface, position.x, position.y);
cr->paint();

注意事项

  • 方案一修改了源Pixbuf的内容,如果你后续还需要用到原始的源位图,不要使用该方案
  • 两种方案都兼容GTK3、GTK4版本的gtkmm封装,无需依赖第三方库

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 03:18:05