简单的GDI贴图应用

本文介绍了如何在Windows GDI中实现透明贴图,通过透明Blt、MaskBlt和BitBlt的光栅操作三种方法,详细阐述了透明显示的步骤,并解释了相关API的工作原理。特别指出,TransparentBlt和MaskBlt在Windows 95/98/me版本不支持,仅适用于NT/2000/XP及以上版本。
摘要由CSDN通过智能技术生成

怎样去除图片上的背景颜色实现透明贴图?

查了一些资料并参考一些帖子总结了一下有几种方法

由简单到复杂:

方法一:

使用TransparentBlt;

 

void  CGdiDlg::OnPaint()
{
    
if (IsIconic())
    
{
        CPaintDC dc(
this); // 用于绘制的设备上下文

        SendMessage(WM_ICONERASEBKGND, reinterpret_cast
<WPARAM>(dc.GetSafeHdc()), 0);

        
// 使图标在工作矩形中居中
        int cxIcon = GetSystemMetrics(SM_CXICON);
        
int cyIcon = GetSystemMetrics(SM_CYICON);
        CRect rect;
        GetClientRect(
&rect);
        
int x = (rect.Width() - cxIcon + 1/ 2;
        
int y = (rect.Height() - cyIcon + 1/ 2;

        
// 绘制图标
        dc.DrawIcon(x, y, m_hIcon);
    }

    
else
    
{
        CPaintDC dc(
this);
        CDC memDc;
        memDc.CreateCompatibleDC(
&dc);
        BITMAP bm;
        m_bitmap.GetBitmap(
&bm);
        memDc.SelectObject(
&m_bitmap);
                         dc.TransparentBlt(
1010, bm.bmWidth, bm.bmHeight, &memDc, 00, bm.bmWidth, bm.bmHeight, RGB(255255255));
                     }

}

        

方法二:

使用MaskBlt;

{
    ......        
    CPaintDC dc(
this);
    CDC memDc;
    memDc.CreateCompatibleDC(
&dc);
    
//CBitmap memBitmap;
    BITMAP bm;
    m_bitmap.GetBitmap(
&bm);
    memDc.SelectObject(
&m_bitmap);

    CDC dcmask;
    dcmask.CreateCompatibleDC(
&dc);
    CBitmap bmpmask;
    bmpmask.CreateBitmap(bm.bmWidth, bm.bmHeight, 
11, NULL);
    dcmask.SelectObject(
&bmpmask);
    
    dcmask.FillSolidRect(
00, bm.bmWidth, bm.bmHeight, RGB(255255255));
    dc.MaskBlt(
00, bm.bmWidth, bm.bmHeight, &memDc, 00, bmpmask, 00, MAKEROP4(SRCAND, SRCINVERT));
    ......
}

 

方法三:

使用BitBlt的光栅操作

{
    .....
    CPaintDC dc(
this);
    CDC memDc;
    memDc.CreateCompatibleDC(
&dc);
    BITMAP bm;
    m_bitmap.GetBitmap(
&bm);
    memDc.SelectObject(
&m_bitmap);

    CDC dcmask;
    dcmask.CreateCompatibleDC(
&dc);
    CBitmap bmpmask;
    bmpmask.CreateBitmap(bm.bmWidth, bm.bmHeight, 
11, NULL);
    dcmask.SelectObject(
&bmpmask);
    memDc.SetBkColor(RGB(
255255255));
    dcmask.BitBlt(
00, bm.bmWidth, bm.bmHeight, &memDc, 00, SRCCOPY);

    dc.BitBlt(
00, bm.bmWidth, bm.bmHeight, &memDc, 00, SRCINVERT);

    dc.BitBlt(
00, bm.bmWidth, bm.bmHeight, &dcmask, 00, SRCAND);
    dc.BitBlt(
00, bm.bmWidth, bm.bmHeight, &memDc, 00, SRCINVERT);
    .....
}

上述代码的原理,直观的说,目标就是,把memDc绘制到dc上的时候,
不绘制跟背景相同的颜色的部分。
1.用BitBlt API进行透明显示的步骤:
①处理dcmask为黑白DC,使memDc上颜色为背景的部分在dcmask显示为白色,其余地方显示为黑色。
②将memDc用BitBlt绘制到dc上,使用SRCINVERT方式
③将dcmask用BitBlt绘制到dc上,使用SRCAND方式
④再将memDc用BitBlt绘制到dc上,使用SRCINVERT方式

ROP中,SRCINVERT是图像间异或处理,SRCAND是图像间与处理。可以简单证明上述的
操作过程会得到我们想要的结果:

对于某一个位置,dc上颜色为B,memDc上颜色为A。
当A == 背景色的时候,dcmask上这个位置的颜色M为白色。则上面的②~④步可以表示为:
((B xor A) and M) xor A
⇔ (B xor A) xor A
⇔ B
当A != 背景色的时候,dcmask上这个位置的颜色M为黑色。则上面的②~④步可以表示为:
((B xor A) and M) xor A
⇔ 0 xor A
⇔ A

前两种方法TransparentBlt和MaskBlt API windows 95/98/me不支持,只支持NT/2000/XP及以后版本

可参考:

Transparent   Blts   in   Windows   NT   Q89375  
HOWTO:   Drawing   Transparent   Bitmaps   Q79212

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值