我是否可以仅使用Platform SDK将位图转换为内存中的PNG(即无需写入文件)?(即没有libpng等).
我还希望能够为此图像定义透明色(不是Alpha通道).
GdiPlus解决方案似乎仅限于宽度可被4整除的图像.在调用Save()期间,其他任何操作都失败了.有谁知道这种限制的原因以及我是否可以解决这个问题?
更新:赏金
我正在开始赏金(我真的希望这个工作).我实现了GDI +解决方案,但正如我所说,它仅限于四边形图像.赏金将发送给任何可以解决此宽度问题的人(不改变图像尺寸),或者可以提供可行的替代非GDI +解决方案.
LodePNG(GitHub)是一个无库的PNG编码器/解码器.
我使用libpng读取和编写PNG ,它似乎处理我抛出它(我已经在单元测试中使用它,如257x255图像,它们没有引起麻烦).我相信API足够灵活,不会被绑定到文件I/O(或者至少你可以覆盖它的默认行为,例如参见自定义png_set_write_fn
部分)
在实践中,我总是通过更清晰的boost :: gil PNG IO扩展来使用它,但不幸的是,这需要char*
文件名,如果你深入研究它的实现中的类png_writer
和file_mgr
它似乎非常相关FILE*
(尽管如果你在Linux上使用的是一个版本) fmemopen和内存缓冲区可能很容易被煮熟.)
在此站点上,代码显示了如何将位图转换为PNG将其写入文件:http://dotnet-snippets.de/dns/gdi-speichern-eines-png-SID814.aspx.而不是写入文件,Save
Bitmap 的方法也支持写入IStream
(http://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搜索.看起来你可以使用它.
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.
我使用GDI +将位图作为PNG保存到文件中.你应该在这里查看关于GDI +的MSDN信息,特别是这个函数GdipSaveImageToStream.
本教程在这里可能会提供一些帮助为好.