效果:
代码:
struct BitmapInDC { HDC m_hdc; HBITMAP m_hbmp; HGDIOBJ m_hbmpOld; BitmapInDC(HDC hdc, HBITMAP bmp) { m_hdc = CreateCompatibleDC(hdc); m_hbmp = bmp; m_hbmpOld = SelectObject(m_hdc, m_hbmp); } ~BitmapInDC() { SelectObject(m_hdc, m_hbmpOld); DeleteObject(m_hbmp); DeleteDC(m_hdc); } operator HDC () { return m_hdc; } }; void TransparentBlt2(HDC hdc, int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest, HDC hdcSrc, int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc, UINT crTransparent) { BitmapInDC image(hdc, CreateCompatibleBitmap(hdc, nWidthDest, nHeightDest)); // HBITMAP CreateBitmap(nWidth, nHeight, nPlanes, nBitCount, lpBits); BitmapInDC mask(hdc, CreateBitmap(nWidthDest, nHeightDest, 1, 1, NULL)); // 把hdcSrc中的图片复制到到image if (nWidthDest == nWidthSrc && nHeightDest == nHeightSrc) { BitBlt(image, 0, 0, nWidthDest, nHeightDest, hdcSrc, nXOriginSrc, nYOriginSrc, SRCCOPY); } else { StretchBlt(image, 0, 0, nWidthDest, nHeightDest, hdcSrc, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, SRCCOPY); } // 单色位图每个像素都是0或1。 // DWORD real_color[2] = { BkColor, TextColor }; // i = (color == BkColor ? 1 : 0); // 把image复制到mask. The transparent region as white (all 1), the non-transparent area Black (all 0). SetBkColor(image, crTransparent); BitBlt(mask, 0, 0, nWidthDest, nHeightDest, image, 0, 0, SRCCOPY); // This way, the background color (black) area of the mask bitmap is reserved in, and the foreground color (white) // part becomes black. SetBkColor(image, RGB(0,0,0)); SetTextColor(image, RGB(255,255,255)); BitBlt(image, 0, 0, nWidthDest, nHeightDest, mask, 0, 0, SRCAND); // SRCAND后,背景不变,主体成为黑洞 SetBkColor(hdc, RGB(255,255,255)); SetTextColor(hdc, RGB(0,0,0)); BitBlt(hdc, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, mask, 0, 0, SRCAND); // SRCPAINT combines the colors of the source and destination rectangles by using the Boolean OR operator. BitBlt(hdc, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, image, 0, 0, SRCPAINT); }View Code
如果一张图片只有两种颜色,那么每个像素都可以用1个bit表示。这是bitmap这个名字的来历。早期内存非常贵,有图就不错了。这种二值图像,可以把0显示为黑色RGB(0, 0, 0),1显示为白色RGB(255, 255, 255),也可以0显示为RGB(0, 255, 0)等等。即先用0或1查颜色表(或者叫palette)。颜色“丰富”的图片,可以每个像素用4位表示,能显示16种颜色,具体啥颜色还是查表。到了24位,就可以不用查表了,RGB各用8位表示。
灰度图像与二值图像不同。灰度图像可以有各种亮度的灰色,与“五彩斑斓的黑”不同,这个没毛病。
BitBlt是Bit Block Transfer的缩写,就是把一个矩形内的图片数据复制到另外一个矩形。我有破电脑后遗症,倾向于苦思冥想如何优化,其实BitBlt的软件实现可能就是for循环里赋值和if. 高速一点点是memcpy,which用rep movsb (repeat move string byte), 最快还是硬件,这个虽然我不会,但对会者来说很简单。
DC是device context(设备上下文)的缩写。设备就是显卡。VGA是640x480, 每个像素16种颜色,如何把一张8位颜色深度(color depth)的图片显示出来?24位的呢?这个我懒得想,只知道CreateBitmap和CreateCompatibleBitmap()都返回HBITMAP, 后者和DC兼容(格式一样),BitBlt时不用转换,速度快。H代表Handle.
CreateBitmap function (wingdi.h) - Win32 apps | Microsoft Learn说:The CreateBitmap function creates a device-dependent bitmap. After a bitmap is created, it can be selected into a device context by calling the SelectObject function. However, the bitmap can only be selected into a device context if the bitmap and the DC have the same format. [CreateBitmp()根本就没有HDC这个参数,咋个device-dependent?]
CreateCompatibleBitmap function (wingdi.h) - Win32 apps | Microsoft Learn说:The CreateCompatibleBitmap function creates a bitmap compatible with the device that is associated with the specified device context. [这个有HDC参数。]
还有BitBlt的参数,有了SRCAND,再有SRCOR天经地义,结果来了个SRCPAINT不知所云。
如何查看颜色的RGB值?啥软件都没有的话,可以用系统自带的画图。用吸管工具在点上点一下,再点“编辑颜色”。
标签:贴图,nHeightDest,image,nWidthDest,详解,hdc,BitBlt,255 From: https://www.cnblogs.com/funwithwords/p/16950431.html