c++ - MFC显示透明背景的png

标签 c++ mfc png

我需要一种方法来在具有渐变颜色的背景上显示具有透明背景的 PNG 图像。

我试过这个:

CImage img;
CBitmap bmp;
img.Load(_T(".\\res\\foo.png"));
bmp.Attach(img.Detach());
CDC dcStatus;
dcStatus.CreateCompatibleDC(&dc);
dcStatus.SelectObject(&bmp);
dcStatus.SetBkColor(TRANSPARENT);
dc.BitBlt(rectText.left + 250, rectText.top, 14, 14, &dcStatus, 0, 0, SRCCOPY);
bmp.DeleteObject();

但是 foo.png 在原始图像中透明的地方会变成黑色背景。

我确实尝试制作一个用透明颜色绘制的新位图,并对其进行了所有可能的操作,但这没有帮助。一种排列的样本:

CImage img;
CBitmap bmp;
img.Load(_T(".\\res\\foo.png"));
bmp.Attach(img.Detach());
CBitmap bmpMaska;
bmpMaska.CreateBitmap(14, 14, 1, 1, NULL);
CDC dcStatus;
dcStatus.CreateCompatibleDC(&dc);
dcStatus.SelectObject(&bmp);
CDC dcMaska;
dcMaska.CreateCompatibleDC(&dc);
dcMaska.SelectObject(&bmpMaska);
dcMaska.SetBkColor(dcStatus.GetPixel(0, 0));
//TODO: Bitmap ni transparent
dc.BitBlt(rectText.left + 250, rectText.top, 14, 14, &dcMaska, 0, 0, SRCCOPY);
dc.BitBlt(rectText.left + 250, rectText.top, 14, 14, &dcStatus, 0, 0, SRCAND);  
bmp.DeleteObject();
bmpMaska.DeleteObject();

这并没有成功。要么,屏幕上全是黑色方 block ,要么结果和原来一样。

我也检查了 AlphaBlend API,但我的代码必须是纯 MFC + C++,没有任何额外的 API。 [编辑]:公司政策是 API 越少越好。该代码应该在嵌入式 Windows 系统上实时运行。

[编辑 2]:我不受 PNG 图像格式的约束,意思是,任何将显示为透明的东西。

请告诉我我做错了什么?

最佳答案

  • 将 png 转换为 32 位 bmp 文件。谷歌“AlphaConv”并使用它。 PNG 是一种可以使用的 PITA - 一些 API 声称支持它们但实际上不支持,或仅部分支持,或仅在某些平台等上支持。
  • 使用 CBitmap::LoadBitmap 加载 32 位 bmp(来自资源 - 这是迄今为止最简单的)
  • 然后使用 CDC::AlphaBlend() 绘制位图。 TransparentBlt() 不适用于 alpha channel - 它只是绘制或不绘制像素。 AlphaBlend 是 win32 API 的一部分,如果您愿意,您仍然可以研究 CImage::AlphaBlend,但是它在某个地方有一个错误(我忘了具体是什么)所以我总是使用原始的::AlphaBlend。
  • 但请注意 - 您需要预乘 alpha channel 才能正确显示。在 How to draw 32-bit alpha channel bitmaps? 上查看我的回答.

您所描述的任何变体都不起作用。您需要另一个 API 才能使其正常工作。或者,您可以使用 GetDIBits 并执行您自己的::AlphaBlend() 版本 :)

关于c++ - MFC显示透明背景的png,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26517577/

相关文章:

c++ - 下面的程序在 C++ 中如何工作?

c++ - 字符串转为二进制

c++ - Qt QGraphicsView 和 QGraphicSscene 鼠标位置

c++ - 在一次处理大量数据时避免Windows中的 "(Not Responding)"标签

Javascript 以 dataURL 格式生成透明的 1X1 像素

python - 如何通过 cython 将 numpy 数组列表传递给 C++

c++ - 如何以 Visual C++ 形式创建 InputTextBox

c++ - MySQL 错误 2005(使用 MySql C++ 连接器):

css - IE PNG 透明度问题 + TwinHelix

android - 减小 .png 文件的大小对内存中的结果位图有一些影响