将位图 (bmp) 转换为具有透明度的 png (Windows c++)

Posted

技术标签:

【中文标题】将位图 (bmp) 转换为具有透明度的 png (Windows c++)【英文标题】:Converting a bitmap (bmp) to png with transparency (Windows c++) 【发布时间】:2020-09-05 17:40:02 【问题描述】:

我需要将 bmp 文件转换为 png 文件,同时将 bmps 中的一种颜色视为透明。我的应用程序使用 MFC,但我并不依赖于在解决方案中使用 MFC。我在从 gdi 移植到 Direct2D 时这样做,所以我确实可以访问 Direct2D(尽管我是 Direct2D 的真正新手)。我想避免使用 gdi+ 和外部源代码(例如 libpng),但我会重新考虑它是否提供易于实现的解决方案。性能不是问题。

如此处所示,MFC 可以很容易地从 bmp 文件创建 png 文件,但我不知道如何将 bmp 中的“透明颜色”转换为 png 中的 alpha 蒙版。 (不太理想,但我可以创建 png 文件,然后读取它,将图像的“透明颜色”更改为透明度,然后写入它。)

// Convert bmp to png.
CImage image;
if(image.Load(bmpFilename) == S_OK)

    image.Save(pngFilename, Gdiplus::ImageFormatPNG) == S_OK);

我看到this thread 提出了一个非常相似的问题,但它的答案是高级别的(例如,“使用 libpng”、“使用 gdi+”、“使用 BITMAPINFOHEADER::biCompression == BI_PNG”等)。我正在寻找细节和(相对)易于实施。

谢谢!

【问题讨论】:

不确定为什么要避免使用 GDI+;毕竟是Windows的系统组件。你也不想使用Windows Imaging Component吗? 【参考方案1】:

应该这样做:

void CImageCopy(CImage& dest, CImage& src)

    // rescale user image
    dest.Destroy();
    dest.Create(src.GetWidth(), src.GetHeight(), 32, CImage::createAlphaChannel);
    HDC hdc = dest.GetDC();

    src.AlphaBlend(hdc, 0,0,src.GetWidth(), src.GetHeight(),  0,0,src.GetWidth(),src.GetHeight());
    dest.ReleaseDC();




void Fix24BitTransparency(CImage& img)

    if(img.GetBPP()<32 )
    
        // alpha bits
        CImage imgout;
        imgout.Create(img.GetWidth(), img.GetHeight(), 32, CImage::createAlphaChannel);

        for(int x=0; x<img.GetWidth(); ++x)
        for(int y=0; y<img.GetHeight(); ++y)
        
            COLORREF c1;
            c1 = img.GetPixel(x,y);  // user image
            imgout.SetPixel(x,y,c1);
            if( c1 == RGB(255,0,128) ) // or whatever you decide transparent...
            
                imgout.SetPixel(x,y, RGB(255,255,255) );
                BYTE* pAlpha = (BYTE*)imgout.GetPixelAddress(x, y)+3;
                *pAlpha = 0;
            
            else
            
                BYTE* pAlpha = (BYTE*)imgout.GetPixelAddress(x, y)+3;
                *pAlpha = 255;
            
        
        CImageCopy(img, imgout);
    

【讨论】:

太棒了,KungPhoo! (我确实需要删除“if(img.GetBPP() @ste 请注意,这是使用 GDI+。

以上是关于将位图 (bmp) 转换为具有透明度的 png (Windows c++)的主要内容,如果未能解决你的问题,请参考以下文章

将 Png 转换为 Bmp 和位图数组

在 Delphi 2007 中将具有透明度的位图保存为 PNG

如何通过 Bitmap::GetHBITMAP 将位图转换为带有 alpha 的 HBITMAP?

iOS:将 png 图像转换为 1 位 bmp 图像

将具有 4 个波段的 PNG 转换为具有 1 个波段和颜色表的任何格式

需要帮助将 BMP 图像转换为 [R] 中的矩阵吗?