19

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

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

GdiPlus 解决方案似乎仅限于宽度可被 4 整除的图像。在调用 Save() 期间,其他任何事情都会失败。有谁知道这个限制的原因以及我如何/是否可以解决它?

更新:赏金

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

4

8 回答 8

20

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

于 2009-02-14T19:31:05.200 回答
15

我使用libpng读写 PNG ,它似乎可以处理我扔给它的所有东西(我在单元测试中使用了它,比如 257x255 图像,它们不会造成任何麻烦)。我相信API足够灵活,不会被绑定到文件 I/O(或者至少您可以覆盖其默认行为,例如参见自定义png_set_write_fn部分)

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

于 2009-02-11T20:57:32.147 回答
12

在此站点上,代码显示了如何将位图转换为 PNG 并将其写入文件:http ://dotnet-snippets.de/dns/gdi-speichern-eines-png-SID814.aspx 。除了写入文件,SaveBitmap 的方法还支持写入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+ 包含在 Windows XP 以上的 Windows 中,并且可以在 Windows 98 以上的 Windows 中运行。我从来没有用它做过什么,只是用谷歌搜索了一下。不过,看起来你可以使用它。

于 2008-12-14T17:54:49.613 回答
8

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。

于 2009-02-12T10:40:09.207 回答
6

我使用 GDI+ 将位图作为 PNG 保存到文件中。您可能应该在此处查看有关 GDI+ 的 MSDN 信息,尤其是此功能GdipSaveImageToStream

此处的本教程可能也会提供一些帮助。

于 2008-12-14T18:38:26.920 回答
5

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

于 2009-02-11T19:57:51.497 回答
3

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

于 2009-02-12T03:34:06.903 回答
2

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

查看freeImage

于 2008-12-14T17:51:11.553 回答