首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >WIC的JPEG解码问题

WIC的JPEG解码问题
EN

Stack Overflow用户
提问于 2020-08-09 22:25:31
回答 1查看 191关注 0票数 0

我目前正在尝试使用WIC将图像从磁盘加载到内存中。我使用MSDN文档here来编写我的代码。

加载PNG图像一切正常。加载JPEG图像没有任何错误,但不会产生正确的结果!有趣的是,当我将图像从JPEG转换为PNG (使用irfan视图)时,错误仍然存在。

考虑以下测试映像:

如你所见,图像在x方向上缩小了,所有的颜色信息都消失了。然而,当您放大时,您可以看到仍然存在一些颜色,但它看起来并不像预期的那样:

(将图像作为纹理上传到GPU时问题仍然存在)

为了提高可读性,我去掉了WIC加载代码,省略了错误处理和资源释放:

代码语言:javascript
复制
// CoInitialize(NULL) called in main

// WIC Factory
IWICImagingFactory* ptrFactory = NULL;
CoCreateInstance(CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&ptrFactory));

// Open decoder
IWICBitmapDecoder* ptrDecoder = NULL;
ptrFactory->CreateDecoderFromFilename(fileName, NULL, GENERIC_READ, WICDecodeMetadataCacheOnDemand, &ptrDecoder)

// Get first frame
IWICBitmapFrameDecode* ptrFrameDecoder = NULL;
ptrDecoder->GetFrame(0, &ptrFrameDecoder));

// Read formate
WICPixelFormatGUID frameNativeFormat;
ptrFrameDecoder->GetPixelFormat(&frameNativeFormat);

// Computing target format selectConverterWic(...) and selectConverterDx(...) are just some very basic functions for selecting the right convert to formate by iterating over an std::array witch contains the mappings suggested by the MSDC article mentioned above
WICPixelFormatGUID targetFormat;
DXGI_FORMAT targetFormatDx;
if (!selectConverterDx(frameNativeFormat, &targetFormatDx)) {
    // Try to find WIC to WIC converter
    selectConverterWic(frameNativeFormat, &targetFormat)
    selectConverterDx(targetFormat, &targetFormatDx)
}else {
    memcpy(&targetFormat, &frameNativeFormat, sizeof(GUID));
}

// Get format info
IWICComponentInfo* ptrCmpInfo = NULL;
ptrFactory->CreateComponentInfo(targetFormat, &ptrCmpInfo);

// Get type
WICComponentType ptrCmpType;
ptrCmpInfo->GetComponentType(&ptrCmpType);


// Get info from type
IWICPixelFormatInfo* ptrFormatInfo = NULL;
ptrCmpInfo->QueryInterface(IID_PPV_ARGS(&ptrFormatInfo));

// Get BBP
UINT uiBitsPerPixel;
ptrFormatInfo->GetBitsPerPixel(&uiBitsPerPixel);

// ID3D12Device->CheckFeatureSupport(...) and fallback omitted

// Image size
UINT width, height;
ptrFrameDecoder->GetSize(&width, &height);

// Tempory memory allocation
UINT rowPitch = (width * uiBitsPerPixel + 7) / 8;
SIZE_T imageSize = (SIZE_T)rowPitch * (SIZE_T)height;
void* workMemory = malloc(imageSize);

// Check if direct copy is possible
if (memcmp(&frameNativeFormat, &targetFormat, sizeof(GUID)) == 0){
    ptrFrameDecoder->CopyPixels(NULL, rowPitch, (UINT)imageSize, (BYTE*)workMemory);
}else{
    // Format conversion (Got never hit by a jpeg file; I tried to force it but results weren't right asswell)
    IWICFormatConverter* ptrFormatConverter = NULL;
    ptrFactory->CreateFormatConverter(&ptrFormatConverter);
    ptrFormatConverter->Initialize(ptrFrameDecoder, targetFormat, WICBitmapDitherTypeErrorDiffusion, NULL, 0, WICBitmapPaletteTypeCustom);
    ptrFormatConverter->CopyPixels(NULL, rowPitch, (UINT)imageSize, (BYTE*)workMemory);
    
}

// I inspected workMemory and got the result you saw above
// Some more code for copying data to user supplied parameters

提前感谢您的帮助!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-08-11 21:13:49

上面的代码完全没问题,而且工作正常!问题出在省略的DirectX 12功能支持检查中:

代码语言:javascript
复制
ID3D12Device->CheckFeatureSupport(...)

我忘记了一个反转,它导致以下代码片段被执行

代码语言:javascript
复制
memcpy(&frameNativeFormat, &GUID_WICPixelFormat32bppRGBA, sizeof(GUID));
targetFormatDx = DXGI_FORMAT_R8G8B8A8_UNORM;
uiBitsPerPixel = 32;

第二个错误是我覆盖了"frameNativeFormat“而不是"targetFormat”,这导致没有执行任何转换(至少对于JPEG)。

修复了这两个问题,给了我一个不错的纹理加载算法(至少在Windows上)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63327473

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档