zoukankan      html  css  js  c++  java
  • 使用TransparentBlt函数实现绘制透明位图

    转载:https://www.write-bug.com/article/1574.html

    总结:使用TransparentBlt 函数,指定透明色

    函数介绍

    TransparentBlt 函数

    对指定的源设备环境中的矩形区域像素的颜色数据进行位块(bit_block)转换,并将结果置于目标设备环境。

    函数声明

    BOOL TransparentBlt(
          HDC hdcDest, 
          int nXOriginDest, 
          int nYOriginDest, 
          int nWidthDest, 
          int hHeightDest, 
          HDC hdcSrc, 
          int nXOriginSrc, 
          int nYOriginSrc, 
          int nWidthSrc, 
          int nHeightSrc, 
          UINT crTransparent
      );

    参数

    • hdcDest:指定目标的句柄。
    • nXOriginDest:指定目标矩形左上角的X轴坐标,坐标以逻辑单位表示。
    • nYOriginDest:指定目标矩形左上角的Y轴坐标,坐标以逻辑单位表示。
    • nnWidthDest:指定目标矩形的宽度。
    • nHeightDest:指定目标矩形的高度。
    • hdcSrc:源图的句柄。
    • nXOriginSrc:指定源矩形(左上角)的X轴坐标,坐标以逻辑单位表示。
    • nYOriginsrc:指定源矩形(左上角)的Y轴坐标,坐标以逻辑单位表示。
    • nWidthSrc:指定源矩形的宽度。
    • nHeightSrc:指定源矩形的高度。
    • crTransparent:源位图中的RGB值当作透明颜色。(用RGB(0,0,0)也就是黑色不行)。

    返回值

    • 如果函数成功,那么返回TRUE;如果函数失败,则返回FALSE。

    什么是位图透明处理?

    至于如何使用 BitBlt 函数绘制位图,我在《BMP位图的绘制》这篇有讲过,当然这只是其中一种绘图方法而已,并不是唯一的。

    那我就先来介绍下,什么是透明位图的绘制。用下面的图片直观表示吧:

    如果我们有两张图片,一张是背景图:

    一张是人物图:

    现在,我想把人物绘制到背景图上,那么按照通常的方法就是,把人物的图片直接在背景图上显示就好,效果如下所示:

    大家可能会看到有些问题了吧,我们其实想要的是下面这张图片的效果:

    没错,所谓的透明位图的绘制就像上面图片表示出来的那样。就是我们只绘制图片特定的地方,而且形状都是不规则的,其他的不进行绘制。就对上上面的例子来说,就是把人物抠出来绘制,背景的蓝色不绘制,即背景像似透明一样,所以这便是位图的透明绘制。

    编程实现原理

    对于,TransparentBlt 函数来说,它的最后一个参数指定除黑色RGB(0, 0, 0)外的其它透明颜色。所谓的透明颜色是指,只要是指定RGB值的颜色,使用Transparent函数都不会绘制,只绘制其他非指定透明颜色RGB值的颜色。

    对于上面的例子来说,我们只要指定透明颜色RGB为蓝色(0, 0, 255),这样,就可以不绘制蓝色,而只绘制非蓝色部分的人物图像了。

    对于,为何指定了透明颜色,就可以实现透明处理,其本质的原理可以参考我写的《使用BitBlt函数实现绘制透明位图》和《使用StretchBlt函数实现绘制透明位图》这两篇文章中的透明原理的分析。Transparent 函数的实现,应该是调用 StretchBlt 函数去实现的。

    编码实现

    导入库文件

    #include <WinGDI.h>
    #pragma comment(lib, "Msimg32.lib")

    绘制背景位图

    BOOL PaintBmp(HWND hWnd)
    {
        // 获取窗口的客户区域的显示设备上下文环境的句柄
        HDC hDC = ::GetDC(hWnd);
        // 创建一个与hDC兼容的内存设备上下文环境
        HDC hBuf = ::CreateCompatibleDC(hDC);
        // 加载位图, 获取位图句柄
        HBITMAP hBmp = (HBITMAP)::LoadImage(NULL, "image\bg.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
        // 选择位图句柄到hBuf中, 并获取返回的原来位图句柄
        HBITMAP hOldBmp = (HBITMAP)::SelectObject(hBuf, hBmp);
        // 绘图
        ::BitBlt(hDC, 0, 0, 764, 397, hBuf, 0, 0, SRCCOPY);
        // 还原位图对象
        ::SelectObject(hBuf, hOldBmp);
        // 释放位图
        ::DeleteObject(hBmp);
        // 释放兼容的内存设备上下文环境
        ::DeleteDC(hBuf);
        // 释放设备上下文环境
        ::ReleaseDC(hWnd, hDC);
        return TRUE;
    }

    绘制透明位图

    BOOL PaintTransparentBmp(HWND hWnd)
    {
        // 获取窗口的客户区域的显示设备上下文环境的句柄
        HDC hDC = ::GetDC(hWnd);
        // 创建一个与hDC兼容的内存设备上下文环境
        HDC hBuf = ::CreateCompatibleDC(hDC);
        // 加载位图, 获取位图句柄
        HBITMAP hBmp = (HBITMAP)::LoadImage(NULL, "image\1.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
        // 选择位图句柄到hBuf中, 并获取返回的原来位图句柄
        HBITMAP hOldBmp = (HBITMAP)::SelectObject(hBuf, hBmp);
        // 透明色为蓝色 绘制
        ::TransparentBlt(hDC, 280, 210, 200, 200, hBuf, 0, 0, 101, 121, RGB(0, 0, 255));
        // 还原位图对象
        ::SelectObject(hBuf, hOldBmp);
        // 释放位图
        ::DeleteObject(hBmp);
        // 释放兼容的内存设备上下文环境
        ::DeleteDC(hBuf);
        // 释放设备上下文环境
        ::ReleaseDC(hWnd, hDC);
        return TRUE;
    }

    程序测试

    调用上述封装好的函数,直接测试。人物位图成功背景透明绘制到背景图上。而且,人物还能成功拉伸绘制。

    总结

    使用 TransparentBlt 函数实现透明位图处理,应该是这三种实现方法中最为简单,也是最容易理解的。而且,使用起来还比较简洁灵活。

  • 相关阅读:
    C# MessageBox.Show()超时后 自动关闭
    WPF中的依赖属性和附加属性
    c# 获取当前活动窗口句柄,获取窗口大小及位置
    c# 数组间相互转换 int[] string[] object[]
    WPF中判断DataGrid增加复选框和头部全选,以及判断哪一行的checkbox被选中
    WPF DataGridTemplateColumn添加按钮和按钮事件获取行参数
    WPF 自定义分页控件 ---- DataPager
    WPF的MVVM模式给ComboBox绑定数据和读取
    DataBinding 绑定计算表达式
    c# 调用方法超时直接返回的功能
  • 原文地址:https://www.cnblogs.com/Toya/p/13412093.html
Copyright © 2011-2022 走看看