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

时间:2011-03-17 21:59:47

标签: c++ winapi gdi+ clsid

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

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

3 个答案:

答案 0 :(得分:5)

没有一个。我认为他们希望编解码器列表是可扩展的并支持插件,但从未接触过它。鉴于他们在很长一段时间内没有对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。您可以将其修改为表查找。

HRESULT GetGdiplusEncoderClsid(__in LPCWSTR pwszFormat, __out GUID *pGUID)
{
    HRESULT hr = E_FAIL;
    UINT  nEncoders = 0;          // number of image encoders
    UINT  nSize = 0;              // size of the image encoder array in bytes
    CAutoVectorPtr<BYTE> spData;
    Gdiplus::ImageCodecInfo* pImageCodecInfo = NULL;
    Gdiplus::Status status;
    bool fFound = false;

    // param check

    if ((pwszFormat == NULL) || (pwszFormat[0] == 0) || (pGUID == NULL))
    {
        return E_POINTER;
    }

    *pGUID = GUID_NULL;

    status = Gdiplus::GetImageEncodersSize(&nEncoders, &nSize);

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


    spData.Allocate(nSize);

    if (spData == NULL)
    {
        return E_FAIL;
    }

    pImageCodecInfo = (Gdiplus::ImageCodecInfo*)(BYTE*)spData;

    status = Gdiplus::GetImageEncoders(nEncoders, nSize, pImageCodecInfo);

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

    for(UINT j = 0; j < nEncoders; ++j)
    {
        if( wcscmp(pImageCodecInfo[j].MimeType, pwszFormat) == 0 )
        {
            *pGUID = pImageCodecInfo[j].Clsid;
            fFound = true;
            break;
        }    
    }

    hr = fFound ? S_OK : E_FAIL;

    return hr;
}

答案 1 :(得分:2)

您可能希望将ImageCodecInfoGetImageEncodersSize()GetImageEncoders()一起使用我不知道任何更简单的方法。

编辑:如果你特别知道你想要什么,该死的所有其他你可以做这样的事情......

CLSID pngClsid;
GetEncoderClsid("image/png", &pngClsid);
image.Save("imagename.png", &pngClsid, NULL);

答案 2 :(得分:2)

如果你只想写一个PNG,这似乎有效:

// image/png  : {557cf406-1a04-11d3-9a73-0000f81ef32e}
const CLSID pngEncoderClsId = { 0x557cf406, 0x1a04, 0x11d3,{ 0x9a,0x73,0x00,0x00,0xf8,0x1e,0xf3,0x2e } }; 
stat = image->Save(L"test.png", &pngEncoderClsId, NULL);

请注意重新格式化十六进制值。

自: How to initialize a constant CLSID