【发布时间】:2018-12-13 01:03:53
【问题描述】:
我在一个 MFC 应用程序中。我使用内存 DC 创建了一个位图,我想将其保存到 DIB 文件中。
到目前为止,我发现这段代码最优雅:
void Save(CBitmap * bitmap) {
CImage image;
image.Attach((HBITMAP)pcBitmap->GetSafeHandle());
image.Save("bla.bmp", Gdiplus::ImageFormatBMP);
}
生成的文件是 32 BPP 颜色空间,所有 alpha 值都设置为“0”。
现在我想使用位图作为工具栏位图:
CMFCToolbar::GetImages()->Load("bla.bmp");
但是所有的图标都不见了。
MFC 在导入位图时在内部调用 PreMultiplyAlpha()。 那么所有像素的RGB分量都是'0'。实际上整个位图都归零了。
如何在保存之前将每个像素的 alpha 值设置为“0xFF”?
我试过了:
void Save(CBitmap * bitmap) {
CImage image;
image.Attach((HBITMAP)pcBitmap->GetSafeHandle());
image.SetHasAlphaChannel(true);
image.AlphaBlend(myBitmapDC, 0, 0);
image.Save("bla.bmp", Gdiplus::ImageFormatBMP);
}
但这只会影响像素的 RGB 值。
到目前为止,我拒绝遍历每个像素并修改位图的内存。我要求一个优雅的解决方案。也许是单线。
【问题讨论】:
-
你想要 0xff 的 alpha,而不是 0 - 不是吗?
-
尝试使用 GDI+ 进行保存,它可以很好地处理 alpha 通道。
CImage只是HBITMAP的包装器,它没有任何 alpha 通道的概念。 -
CImage.Save() 在内部调用 GDI+。我用调试器验证了。我的内存 DC 与我的窗口 DC 兼容,因此图像为 32 BPP。 GDI+ 将所有像素的 alpha 值设置为 0。但我希望所有像素的 alpha 值都为 0xFF,因为这样可以将图像加载到 CMFCToolbar 对象中。
-
好吧,我忘了。查看
CImage::Save()源,它检查m_bHasAlphaChannel(由您的SetHasAlphaChannel()调用设置)并使用PixelFormat32bppARGB创建GDI+ 位图。因此,这应该保留您拥有的任何 Alpha 通道数据。您只需要在调用Save()函数之前设置 alpha 通道值。 -
SetHasAlphaChannel设置一个标志并在最后创建一个 32 位图像,或者用于绘制透明,但不影响可能保持为零的 alpha。
标签: winapi mfc gdi+ gdi cmfctoolbar