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

Ass*_*vie 16 c++ winapi png

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

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

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

更新:赏金

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

Joh*_*ski 18

LodePNG(GitHub)是一个无库的PNG编码器/解码器.


tim*_*day 15

我使用libpng读取和编写PNG ,它似乎处理我抛出它(我已经在单元测试中使用它,如257x255图像,它们没有引起麻烦).我相信API足够灵活,不会被绑定到文件I/O(或者至少你可以覆盖它的默认行为,例如参见自定义png_set_write_fn部分)

在实践中,我总是通过更清晰的boost :: gil PNG IO扩展来使用它,但不幸的是,这需要char*文件名,如果你深入研究它的实现中的类png_writerfile_mgr它似乎非常相关FILE*(尽管如果你在Linux上使用的是一个版本) fmemopen和内存缓冲区可能很容易被煮熟.)


Joh*_*itb 11

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


dje*_*dot 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();
Run Code Online (Sandbox Code Playgroud)

不过,我不知道你是否想要使用ATL或MFC.


Two*_*ymz 5

我使用GDI +将位图作为PNG保存到文件中.你应该在这里查看关于GDI +的MSDN信息,特别是这个函数GdipSaveImageToStream.

本教程在这里可能会提供一些帮助为好.


Aar*_*ark 5

GDI(老派,非加)有一个GetDIBits方法,可以要求使用 PNG 压缩(BITMAPINFOHEADER::biCompression == BI_PNG)输出位。我想知道这是否可以用来创建 PNG 文件?使用GetDIBits编写标准位图文件已经足够复杂了 - 所以我怀疑这会更加困难。

  • 对于任何可能想走这条路的人,请参阅[“GetDIBits() 因 PNG 压缩而失败”的答案](/sf/answers/217076331/),或“[JPEG 和 PNG 扩展”对于特定位图函数和结构](https://msdn.microsoft.com/en-us/library/dd145023(VS.85).aspx)”在 MSDN 上,它链接到。 (3认同)