IWICBitmapScaler 不适用于 96bppRGBFloat 格式?

IWICBitmapScaler doesn't work for 96bppRGBFloat format?

我在使用 WIC 库时遇到了问题。而且我发现我无法使用 IWICBitmapScaler 缩放 R32G32B32 图像...代码示例如下所示:

{
    IWICImagingFactory* m_pWICFactory;
    HRESULT hr = S_OK;
    // Initialize COM
    hr = CoInitialize(nullptr);
    assert(SUCCEEDED(hr));
    // Initialize Factory
    hr = CoCreateInstance(CLSID_WICImagingFactory, nullptr, CLSCTX_INPROC_SERVER,
        __uuidof(IWICImagingFactory), (void**)&m_pWICFactory);
    assert(SUCCEEDED(hr));

    // 4x4 R32G32B32 image
    XMFLOAT3 srcImg[] = { XMFLOAT3(1, 1, 1), XMFLOAT3(1, 1, 1), XMFLOAT3(1, 1, 1), XMFLOAT3(1, 1, 1),
        XMFLOAT3(1, 1, 1), XMFLOAT3(1, 1, 1), XMFLOAT3(1, 1, 1), XMFLOAT3(1, 1, 1),
        XMFLOAT3(1, 1, 1), XMFLOAT3(1, 1, 1), XMFLOAT3(1, 1, 1), XMFLOAT3(1, 1, 1), 
        XMFLOAT3(1, 1, 1), XMFLOAT3(1, 1, 1), XMFLOAT3(1, 1, 1), XMFLOAT3(1, 1, 1), };

    // 2x2 R32G32B32 image
    XMFLOAT3 dstImg[4];

    CComPtr<IWICBitmap> pSrcBitmap;
    hr = m_pWICFactory->CreateBitmapFromMemory(4, 4, GUID_WICPixelFormat96bppRGBFloat, 4 * sizeof(XMFLOAT3),
        4 * sizeof(XMFLOAT3)* 4, (BYTE*)srcImg, &pSrcBitmap);

    IWICBitmapSource *pSrcBitmapSource = pSrcBitmap.p;

    // scale to 2x2
    CComPtr<IWICBitmapScaler> pScaler;
    hr = m_pWICFactory->CreateBitmapScaler(&pScaler);
    hr = pScaler->Initialize(pSrcBitmapSource, 2, 2, WICBitmapInterpolationModeFant);
    pSrcBitmapSource = pScaler.p;

    // copy back
    WICRect rect = { 0, 0, 2, 2 };
    hr = pSrcBitmapSource->CopyPixels(&rect, 2 * sizeof(XMFLOAT3), 2 * sizeof(XMFLOAT3)* 2, (BYTE*)dstImg);

}

我刚在 dstImg 缓冲区中得到 -1.#QNAN000 :( 我不确定是我做错了什么,还是 IWICBitmapScaler 不支持这种格式?

另一个问题是,当我使用 IWICFormatConverter 将 R32G32B32A32(即 128bppRGBFloat)图像转换为 R32Gray(即 32bppGrayFloat)格式时,它总是将值固定为 [0, 1],这是期望的行为吗? (为什么???)

(我的平台:Win 8.1 64bit + VS2013)

您错误地假设 IWICBitmapScaler 总是 returns 数据采用与其输入相同的像素格式。它不是。您必须调用 GetPixelFormat 才能了解结果的格式。此外,在使用 COM API 时,您 必须 检查每个 returns 调用的 HRESULT 以发现问题。

CComPtr<IWICBitmapScaler> pScaler;
hr = m_pWICFactory->CreateBitmapScaler(&pScaler);
if ( FAILED(hr) )
    ...
hr = pScaler->Initialize(pSrcBitmapSource, 2, 2, ICBitmapInterpolationModeFant);
if ( FAILED(hr) )
    ...
pSrcBitmapSource = pScaler.p;

WICPixelFormatGUID pfScaler;
hr = scaler->GetPixelFormat( &pfScaler );
if ( FAILED(hr) )
    ...

// In many cases, pfScaler will not be the same GUID as your pSrcBItmapSource.

您应该查看 DirctXTex 以获得使用 WIC 的大量示例。