IWICImagingFactory 的 CoCreateInstance

Posted

技术标签:

【中文标题】IWICImagingFactory 的 CoCreateInstance【英文标题】:CoCreateInstance of IWICImagingFactory 【发布时间】:2013-02-10 15:15:45 【问题描述】:

我在我的 Windows 7 机器上运行 Visual Studio 2012。

当我运行这里找到的 SimpleDirect2dApplication 时:http://technet.microsoft.com/en-us/subscriptions/dd940321%28v=vs.85%29.aspx

    hr = CoCreateInstance(
    CLSID_WICImagingFactory,
    NULL,
    CLSCTX_INPROC_SERVER,
    IID_PPV_ARGS(&m_pWICFactory)
    );

CoCreateInstance 因“未注册类”而失败,工厂的 ptr 为 0。

任何帮助将不胜感激。

【问题讨论】:

所以在提出问题后,我立即在这里找到了答案social.msdn.microsoft.com/Forums/en-US/windowswic/thread/…CLSID_WICImagingFactory 需要更改为 CLSID_WICImagingFactory1 才能使其适用于 windows7。 其实看SDK版本。较旧的 SDK 有 CLSID_WICImagingFactory 指向正确的 CLSID,并且代码可以正常工作。 Windows SDK 上的意外、不明显且可能不准确的更改。 这是在 wincodec.idl 中正确定义的,它们具有完全相同的 guid。也许这在 8 SDK 的测试版中被破坏了,现在不是。 【参考方案1】:

根据 Microsoft 论坛中的 answer,Windows SDK 8.0 的一项重大更改要求您将 _WIN32_WINNT 定义为 0x0600 以向后兼容 Windows Vista 或定义为 0x0601 以向后兼容 Windows 7。

【讨论】:

【参考方案2】:

以下是我用来为 WIC 和 WIC2 场景创建 WIC 的代码:

namespace

    bool g_WIC2 = false;

    BOOL WINAPI InitializeWICFactory(PINIT_ONCE, PVOID, PVOID *ifactory) noexcept
    
    #if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) || defined(_WIN7_PLATFORM_UPDATE)
        HRESULT hr = CoCreateInstance(
            CLSID_WICImagingFactory2,
            nullptr,
            CLSCTX_INPROC_SERVER,
            __uuidof(IWICImagingFactory2),
            ifactory
        );

        if (SUCCEEDED(hr))
        
            // WIC2 is available on Windows 10, Windows 8.x, and Windows 7 SP1 with KB 2670838 installed
            g_WIC2 = true;
            return TRUE;
        
        else
        
            hr = CoCreateInstance(
                CLSID_WICImagingFactory1,
                nullptr,
                CLSCTX_INPROC_SERVER,
                __uuidof(IWICImagingFactory),
                ifactory
            );
            return SUCCEEDED(hr) ? TRUE : FALSE;
        
    #else
        return SUCCEEDED(CoCreateInstance(
            CLSID_WICImagingFactory,
            nullptr,
            CLSCTX_INPROC_SERVER,
            __uuidof(IWICImagingFactory),
            ifactory)) ? TRUE : FALSE;
    #endif
    


bool IsWIC2() noexcept

    return g_WIC2;


IWICImagingFactory* GetWIC() noexcept

    static INIT_ONCE s_initOnce = INIT_ONCE_STATIC_INIT;

    IWICImagingFactory* factory = nullptr;
    if (!InitOnceExecuteOnce(
        &s_initOnce,
        InitializeWICFactory,
        nullptr,
        reinterpret_cast<LPVOID*>(&factory)))
    
        return nullptr;
    
    return factory;

这处理从任何线程创建一次工厂。您只需调用即可使用它:

auto pWIC = GetWIC();
if (!pWIC)
    // error

对于您关心 WIC 与 WIC2 的少数情况,您可以使用 IsWIC2

if (targetFormat && memcmp(&guidContainerFormat, &GUID_ContainerFormatBmp, sizeof(WICPixelFormatGUID)) == 0 && IsWIC2())

    // Opt-in to the WIC2 support for writing 32-bit Windows BMP files with an alpha channel
    PROPBAG2 option = ;
    option.pstrName = const_cast<wchar_t*>(L"EnableV5Header32bppBGRA");

    VARIANT varValue;
    varValue.vt = VT_BOOL;
    varValue.boolVal = VARIANT_TRUE;
    (void)props->Write(1, &option, &varValue);

我过去曾为此代码使用 C++11 lambda,但 clang/LLVM 不太喜欢它。

【讨论】:

【参考方案3】:

使用这个

#if defined(CLSID_WICImagingFactory)
#undef CLSID_WICImagingFactory
#endif

然后你就可以通过了

参考: http://skia.googlecode.com/svn/trunk/src/ports/SkImageDecoder_WIC.cpp

【讨论】:

此答案中的链接已损坏。 很难理解这个答案中提出的解决方案(#undef-存在CLSID_WICImagingFactory 宏)应该如何工作。能详细点吗? 链接现在在这里:github.com/Igalia/skia/blob/master/src/ports/…

以上是关于IWICImagingFactory 的 CoCreateInstance的主要内容,如果未能解决你的问题,请参考以下文章

IWICImagingFactory 这个类怎么创建

电脑显示iwicimagingfactory:%1 不是有效的win32 应用程序800700c

COM笔记-CoCreateInstance

Png异形窗口

如何从 WIC 解码器确定自上而下/自下而上?

Delphi 缩放图像代码 - 支持PNG透明通道(利用了Windows的windowscodecs.dll)