我正在编辑一些旧的GDI代码以使用GDI +,并且在绘制具有透明背景的BMP文件时遇到了问题。旧的GDI代码没有使用任何明显的额外代码来绘制背景透明,所以我想知道如何使用GDI +实现这一点。
我目前的代码如下所示
HINSTANCE hinstance = GetModuleHandle(NULL);
bmp = Gdiplus::Bitmap::FromResource(hinstance, MAKEINTRESOURCEW(IDB_BMP));
Gdiplus::Graphics graphics(pDC->m_hDC);
graphics.DrawImage(&bmp, posX, posY);
我还尝试使用clone方法从资源创建一个新的位图,并将位图绘制到新创建的位图,但都没有帮助。两次我都使用PixelFormat32bppPARGB。
然后我尝试使用alpha混合,但这样整个图像变得透明,而不仅仅是背景:
Gdiplus::ColorMatrix clrMatrix = {
1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 0.5f, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f, 1.0f
};
Gdiplus::ImageAttributes imgAttr;
imgAttr.SetColorMatrix(&clrMatrix);
graphics.DrawImage(&bmp, destRect, 0, 0, width(), height(), Gdiplus::UnitPixel, &imgAttr);
透明度信息已包含在图像中,但我不知道如何在绘制图像时应用它。如何实现这一目标?
答案 0 :(得分:1)
最简单的解决方案是使用除BMP之外的某种格式。
您需要包含alpha数据的位,并且您需要Bitmap采用具有alpha数据的格式。当您使用GDI +加载BMP时,即使BMP具有Alpha通道,它也将始终使用不带alpha的格式。我相信数据存在于图像位中,但它没有被使用。
克隆或绘制到PixelFormat32bppPARGB位图时的问题是GDI +会将图像数据转换为新格式,这意味着丢弃alpha数据。
假设它正确加载了这些位,你需要做的是将这些位直接复制到另一个具有正确格式的位图。您可以使用Bitmap::LockBits和Bitmap::UnlockBits执行此操作。 (确保使用其原生像素格式锁定每个位图,以便不进行转换。)
答案 1 :(得分:1)
迟到的回答但是:
ImageAttributes imAtt;
imAtt.SetColorKey(Color(255,255,255), Color(255,255,255), ColorAdjustTypeBitmap);
将white (255,255,255)
透明放在您使用此图像属性的任何位图上。
答案 2 :(得分:0)
我遇到了同样的问题。透明BMP未正确显示,遗憾的是,PNG无法直接从资源加载(除非添加了相当多的代码,将它们复制到流中并从流中加载它们)。我想避免这个代码。
我使用的位图也只使用两种颜色(背景和徽标)。拥有alpha通道意味着我需要使用更高的颜色深度而不是仅仅2位颜色深度来保存它们。
Evan的答案正是我一直在寻找: - )
我使用左上角像素的颜色作为透明色,而不是白色:
Gdiplus::Color ColourOfTopLeftPixel;
Gdiplus::Status eStatus = m_pBitmap->GetPixel(0, 0, &ColourOfTopLeftPixel);
_ASSERTE(eStatus == Gdiplus::Ok);
// The following makes every pixel with the same colour as the top left pixel (ColourOfTopLeftPixel) transparent.
Gdiplus::ImageAttributes ImgAtt;
ImgAtt.SetColorKey(ColourOfTopLeftPixel, ColourOfTopLeftPixel, Gdiplus::ColorAdjustTypeBitmap);