Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用WIC的JPEG解码问题_C++_Windows_Jpeg_Wic - Fatal编程技术网

C++ 使用WIC的JPEG解码问题

C++ 使用WIC的JPEG解码问题,c++,windows,jpeg,wic,C++,Windows,Jpeg,Wic,我目前正在尝试使用WIC将图像从磁盘加载到内存中。我使用MSDN文档来编写代码 加载PNG图像时一切正常。加载JPEG图像可以正常工作,但不会产生正确的结果!有趣的是,当我将图像从JPEG转换为PNG(使用irfan视图)时,错误仍然存在 考虑以下测试图像: 正如您所见,图像在x方向上缩小,所有颜色信息都消失了。但是,当您放大时,您可以看到仍然存在一些颜色,但看起来与预期不同: (将图像作为纹理上载到GPU时,问题仍然存在) 我已将WIC加载代码剥离出来,省去了错误处理和资源释放,以提高可

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

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

考虑以下测试图像:

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

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

我已将WIC加载代码剥离出来,省去了错误处理和资源释放,以提高可读性:

//在main中调用了CoInitialize(NULL)
//WIC工厂
IWICImagingFactory*ptrFactory=NULL;
CoCreateInstance(CLSID_WICImagingFactory,NULL,CLSCTX_INPROC_服务器,IID_PPV_参数(&ptrFactory));
//开放式解码器
IWICBitmapDecoder*ptrDecoder=NULL;
ptrFactory->CreateDecoderFromFilename(文件名、NULL、泛型读取、WICDecodeMetadataCacheOnDemand和ptrDecoder)
//获得第一帧
IWICBitmapFrameDecode*ptrFrameDecoder=NULL;
ptrDecoder->GetFrame(0和ptrFrameDecoder));
//读格式化
WICPixelFormatGUID frameNativeFormat;
ptrFrameDecoder->GetPixelFormat(&frameNativeFormat);
//计算目标格式selectConverterWic(…)和selectConverterDx(…)只是一些非常基本的函数,用于通过迭代包含上述MSDC文章建议的映射的std::数组来选择正确的格式转换
WICPixelFormatGUID targetFormat;
DXGI_格式targetFormatDx;
如果(!selectConverterDx(frameNativeFormat和targetFormatDx)){
//尝试查找WIC到WIC转换器
选择Converterwic(frameNativeFormat和targetFormat)
选择ConverterDX(targetFormat和targetFormatDx)
}否则{
memcpy(&targetFormat,&frameNativeFormat,sizeof(GUID));
}
//获取格式信息
IWICComponentInfo*ptrCmpInfo=NULL;
ptrFactory->CreateComponentInfo(targetFormat和ptrCmpInfo);
//获取类型
WICComponentType ptrCmpType;
ptrCmpInfo->GetComponentType(&ptrCmpType);
//从类型获取信息
IWICPixelFormatInfo*ptrFormatInfo=NULL;
ptrCmpInfo->QueryInterface(IID_PPV_ARGS(&ptrFormatInfo));
//获得BBP
UINT-uiBitsPerPixel;
ptrFormatInfo->getBitSperpix(&UIBitSperpix);
//ID3D12Device->CheckFeatureSupport(…)并省略回退
//图像大小
单元宽度、高度;
ptrFrameDecoder->GetSize(&width,&height);
//临时内存分配
UINT行间距=(宽度*uiBitsPerPixel+7)/8;
尺寸图像尺寸=(尺寸)行间距*(尺寸)高度;
void*workMemory=malloc(imageSize);
//检查是否可以直接复制
if(memcmp(&frameNativeFormat,&targetFormat,sizeof(GUID))==0){
ptrFrameDecoder->CopyPixels(空,行间距,(UINT)图像大小,(字节*)工作内存);
}否则{
//格式转换(从未被jpeg文件击中;我试图强制它,但结果不正确)
IWICFormatConverter*ptrFormatConverter=NULL;
ptrFactory->CreateFormatConverter(&ptrFormatConverter);
ptrFormatConverter->初始化(ptrFrameDecoder,targetFormat,WICBitmapDitherTypeErrorDiffusion,NULL,0,WICBitmapPaletteTypeCustom);
PTR格式转换器->复制像素(空,行间距,(UINT)图像大小,(字节*)工作内存);
}
//我检查了workMemory,得到了您在上面看到的结果
//更多用于将数据复制到用户提供的参数的代码

提前感谢您的帮助

上面的代码很好用!问题出在省略的DirectX 12功能支持检查中:

ID3D12Device->CheckFeatureSupport(...)
我忘记了一个反转,它导致执行了以下被截取的代码

memcpy(&frameNativeFormat, &GUID_WICPixelFormat32bppRGBA, sizeof(GUID));
targetFormatDx = DXGI_FORMAT_R8G8B8A8_UNORM;
uiBitsPerPixel = 32;
第二个错误是我覆盖了“frameNativeFormat”而不是“targetFormat”,这导致没有执行任何转换(至少对于JPEG)


修复这两个问题给了我一个不错的纹理加载算法(至少对于Windows来说)

它看起来像是一个文件格式问题。检查每个方法调用返回的每个HRESULT如何?可能有一些错误结果。谢谢您的评论!我确实检查了每个方法调用,它返回了if(FAILED(hr=call(…){…return hr;}没有错误。有什么特殊的错误代码我需要明确检查吗?我已经追踪到我的HRESULT hr的值,它从来没有比S_更大的值。你确定你的音高/步幅计算吗?或者发布一个小的复制项目。我不知道。也许这行有什么问题。但是它与PNG和它一起工作在MSDN示例中也是如此。BBP*width/8对我来说很有意义,因为它与扫描线的宽度(以字节为单位)相关。我不知道他们为什么使用+7…但删除它仍然会产生相同的输出。步幅也是正确的,我验证了它(至少对于我的解释而言)。也许+7是为了确保在四舍五入的情况下,计算结果仍然会保持适当的步幅。我现在将从头开始创建一个唯一的图像加载示例。我将很快在这里发布它