保存的 Gdiplus::Bitmap 始终具有 Alpha 通道 (RGBA/ARGB)

Posted

技术标签:

【中文标题】保存的 Gdiplus::Bitmap 始终具有 Alpha 通道 (RGBA/ARGB)【英文标题】:Saved Gdiplus::Bitmap always has Alpha Channel (RGBA/ARGB) 【发布时间】:2018-11-20 17:45:42 【问题描述】:

我有一个 PixelFormat32bppARGB 格式的 Gdiplus::Bitmap(在 C++ 中)并使用以下方法将其转换为 PixelFormat32bppRGB:

        Gdiplus::Bitmap* bitmapRGB = new Gdiplus::Bitmap(bitmap->GetWidth(), bitmap->GetHeight(), PixelFormat32bppRGB);
        Gdiplus::Graphics graphics(bitmapRGB);
        graphics.DrawImage(bitmap, Gdiplus::Point(0, 0));

如果我检查 RGB 位图的格式,它是正确的 (RGB):

bitmapRGB ->GetPixelFormat() == PixelFormat32bppRGB

如果我保存位图并检查其格式(即使用 Gimp),则有第四个通道。

    CLSID pngClsid;
    GetEncoderClsid(L"image/png", &pngClsid);
    bitmapRGB ->Save(path, &pngClsid, NULL);

如何获得具有 RGB 像素格式的 png?

【问题讨论】:

"我有一个 Gdiplus::Bitmap (in C)" 这是不可能的。这不是有效的 C 代码。 C 没有 ::new 运算符。 C++ 可以,但它是一种完全不同的语言。请花几秒钟时间选择正确的标签。 为什么人们总是说“C++ 是一种完全不同的语言”?恕我直言,这掩盖了这样一个事实,即您可以编写“C 中的 C++”风格,获得更好的类型检查的好处(并发现 C 确实默默接受的错误)。因此,“完全不同的语言”是不允许的。 (你不能限制你在 LISP 程序中使用的内容并希望 C 编译器编译它,因为 LISP 是一种完全不同的语言)。我为许多项目用 C++ 编写了“C”并获得了好处,包括当嵌入式系统只有 C 编译器时能够“回退”到 C 编译器。 【参考方案1】:

PixelFormat32bppRGB 仍然是 32 位。 24 位格式需要PixelFormat24bppRGB

Gdiplus::Bitmap* bitmapRGB = new Gdiplus::Bitmap(
    bitmap->GetWidth(), bitmap->GetHeight(), PixelFormat24bppRGB);

new 运算符不是必需的,使用适当的构造函数之一确保没有内存泄漏:

//convert:
Gdiplus::Bitmap bitmap(L"source.jpg");
Gdiplus::Bitmap bitmapRGB(bitmap.GetWidth(), bitmap.GetHeight(), PixelFormat24bppRGB);

Gdiplus::Graphics graphics(&bitmapRGB);
graphics.DrawImage(&bitmap, Gdiplus::Point(0, 0));

CLSID pngClsid;
GetEncoderClsid(L"image/png", &pngClsid);
bitmapRGB.Save(L"destination.png", &pngClsid);

【讨论】:

以上是关于保存的 Gdiplus::Bitmap 始终具有 Alpha 通道 (RGBA/ARGB)的主要内容,如果未能解决你的问题,请参考以下文章

Gdiplus::Bitmap::FromHICON 失败

如何从 Gdiplus::Bitmap 快速复制数据

Gdiplus :: Bitmap到BYTE数组?

React:LocalStorage 始终具有非空值

保存后CoreData objectID始终相同

如何将具有动态 ID 的文档保存到 Cloud Firestore?总是在变化