在C ++中将位图转换为内存中的PNG(win32)

时间:2008-12-14 17:34:32

标签: c++ winapi png

我是否可以仅使用Platform SDK将位图转换为内存中的PNG(即无需写入文件)? (即没有libpng等)。

我还希望能够为此图像定义透明色(不是Alpha通道)。

GdiPlus解决方案似乎仅限于宽度可被4整理的图像。在调用Save()期间,其他任何操作都失败了。有谁知道这个限制的原因以及我是否可以解决这个问题?

更新:赏金

我正在开始赏金(我真的希望这个工作)。我实现了GDI +解决方案,但正如我所说,它仅限于四边形图像。赏金将发送给任何可以解决此宽度问题的人(不改变图像尺寸),或者可以提供可行的替代非GDI +解决方案。

8 个答案:

答案 0 :(得分:17)

LodePNGGitHub)是一个无库的PNG编码器/解码器。

答案 1 :(得分:15)

我使用libpng读取和写入PNG,它似乎处理了我抛出的东西(我在单元测试中用它来处理像257x255图像这样的东西并没有造成麻烦)。我相信API足够灵活,不会与文件I / O绑定(或者至少可以覆盖其默认行为,例如,请参阅customization部分中的png_set_write_fn

在实践中,我总是通过更干净的boost::gil PNG IO extension使用它,但不幸的是,它会带有char*个文件名,如果你深入了解png_writer和{{1它的实现中的类似乎与file_mgr非常相关(尽管如果你在Linux上,使用fmemopen和内存缓冲区的版本很可能很容易编译)。

答案 2 :(得分:11)

在此网站上,代码显示了如何将位图转换为PNG,将其写入文件:http://dotnet-snippets.de/dns/gdi-speichern-eines-png-SID814.aspx。位图的Save方法也支持写入IStreamhttp://msdn.microsoft.com/en-us/library/ms535406%28VS.85%29.aspx),而不是写入文件。您可以使用CreateStreamOnHGlobal API函数创建由内存备份的Stream。 (http://msdn.microsoft.com/en-us/library/aa378980%28VS.85%29.aspx)。使用过的库GDI +从WindowsXP包含在Windows中,在Windows98中可以在Windows中运行。我从未用它做过什么,只是用Google搜索。看起来你可以使用它。

答案 3 :(得分:7)

CImage类(ATL / MFC)支持保存为PNG格式。与GDI +解决方案一样,它也支持保存到流。这是我用来将它保存到CByteArray的一些代码:

CByteArray baPicture;
IStream *pStream = NULL;
if (CreateStreamOnHGlobal(NULL, TRUE, &pStream) == S_OK)
{
    if (image.Save(pStream, Gdiplus::ImageFormatPNG) == S_OK)
    {
    ULARGE_INTEGER ulnSize;
        LARGE_INTEGER lnOffset;
        lnOffset.QuadPart = 0;
        if (pStream->Seek(lnOffset, STREAM_SEEK_END, &ulnSize) == S_OK)
        {
            if (pStream->Seek(lnOffset, STREAM_SEEK_SET, NULL) == S_OK)
            {                       
                baPicture.SetSize(ulnSize.QuadPart);
                ULONG ulBytesRead;
                pStream->Read(baPicture.GetData(), ulnSize.QuadPart, &ulBytesRead);
            }
        }
    }
}
pStream->Release();

我不知道你是否想要使用ATL或MFC。

答案 4 :(得分:5)

我使用GDI +将位图作为PNG保存到文件中。您应该查看有关GDI + here的MSDN信息,特别是此函数GdipSaveImageToStream

本教程here也可能会提供一些帮助。

答案 5 :(得分:3)

GDI(旧学校,非加)有GetDIBits方法可以要求使用PNG压缩输出位(BITMAPINFOHEADER::biCompression == BI_PNG)。我想知道这是否可用于创建PNG文件?使用GetDIBits编写标准位图文件非常复杂 - 所以我怀疑这会更加困难。

答案 6 :(得分:3)

如果您只想使用Windows API,WIC是实现此目的的方法,它同时支持位图和PNG。

答案 7 :(得分:2)

使用库而不是自己重新发明轮子可能会更好。

查看freeImage