c++ - GDI+ 是否有标准图像编码器 CLSID?

标签 c++ winapi gdi+ clsid

GDI+ Image::Save方法需要一个 CLSID 参数来指定要使用的编码器。文档指向 some sample code用于获取与特定 MIME 类型关联的编码器,例如 image/jpeg 或 image/png。但是,我对复制半页函数只是为了支持单行调试辅助的想法犹豫不决,我将中间结果保存到磁盘。

标准编码器不应该有一个标准 CLSID 列表吗?我在哪里可以找到这样的列表?我一直无法通过搜索 Microsoft 的包含文件找到一个。

最佳答案

没有一个。我认为他们希望编解码器列表可扩展并支持插件,但从未解决过。鉴于他们在相当长的一段时间内没有对 GDI+ 进行任何更改,他们很可能不会很快更改。您可能可以根据 Gdiplus::GetImageEncoders 的枚举生成自己的硬编码列表。

即:

image/bmp  : {557cf400-1a04-11d3-9a73-0000f81ef32e}
image/jpeg : {557cf401-1a04-11d3-9a73-0000f81ef32e} 
image/gif  : {557cf402-1a04-11d3-9a73-0000f81ef32e} 
image/tiff : {557cf405-1a04-11d3-9a73-0000f81ef32e}
image/png  : {557cf406-1a04-11d3-9a73-0000f81ef32e}

这是我经常在项目之间剪切和粘贴的函数,用于获取编码器的 CLSID。您可以将其修改为表查找。

#include <windows.h>
#include <gdiplus.h>
#include <string>
#include <vector>

HRESULT GetGdiplusEncoderClsid(const std::wstring& format, GUID* pGuid)
{
    HRESULT hr = S_OK;
    UINT  nEncoders = 0;          // number of image encoders
    UINT  nSize = 0;              // size of the image encoder array in bytes
    std::vector<BYTE> spData;
    Gdiplus::ImageCodecInfo* pImageCodecInfo = NULL;
    Gdiplus::Status status;
    bool found = false;

    if (format.empty() || !pGuid)
    {
        hr = E_INVALIDARG;
    }

    if (SUCCEEDED(hr))
    {
        *pGuid = GUID_NULL;
        status = Gdiplus::GetImageEncodersSize(&nEncoders, &nSize);

        if ((status != Gdiplus::Ok) || (nSize == 0))
        {
            hr = E_FAIL;
        }
    }

    if (SUCCEEDED(hr))
    {

        spData.resize(nSize);
        pImageCodecInfo = (Gdiplus::ImageCodecInfo*)&spData.front();
        status = Gdiplus::GetImageEncoders(nEncoders, nSize, pImageCodecInfo);

        if (status != Gdiplus::Ok)
        {
            hr = E_FAIL;
        }
    }

    if (SUCCEEDED(hr))
    {
        for (UINT j = 0; j < nEncoders && !found; j++)
        {
            if (pImageCodecInfo[j].MimeType == format)
            {
                *pGuid = pImageCodecInfo[j].Clsid;
                found = true;
            }
        }

        hr = found ? S_OK : E_FAIL;
    }

    return hr;
}


int main()
{
    Gdiplus::GdiplusStartupInput gdiplusStartupInput;
    ULONG_PTR gdiplusToken;
    GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

    GUID guidBmp = {};
    GUID guidJpeg = {};
    GUID guidGif = {};
    GUID guidTiff = {};
    GUID guidPng = {};

    GetGdiplusEncoderClsid(L"image/bmp", &guidBmp);
    GetGdiplusEncoderClsid(L"image/jpeg", &guidJpeg);
    GetGdiplusEncoderClsid(L"image/gif", &guidGif);
    GetGdiplusEncoderClsid(L"image/tiff", &guidTiff);
    GetGdiplusEncoderClsid(L"image/png", &guidPng);

    return 0;
}

关于c++ - GDI+ 是否有标准图像编码器 CLSID?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5345803/

相关文章:

c++ - 如何确定线程模拟级别

未收到 C++ Windows 异步 IO 命名管道第一条消息

c# - 如何确定将在矩形中绘制的文本的高度?

c++ - 使用继承时构造函数/析构函数调用的顺序

c++ - 如何在函数内返回值后删除指针

c++ - GetAsyncKeyState() 占用大量 CPU?我使用正确吗?

.net - 如何从 .NET 中的图标文件中提取特定图像?

c++ - 如何使用 Window 的 C++ 图形 (GDI+) 库移动对象?

c++ - 在 C++ 中正确对齐

c++ - Clang Diagnostics,如何忽略编译器特定的扩展