IWICImagingFactory::CreateDecoderFromStream()失败,错误消息消息没有帮助
IWICImagingFactory::CreateDecoderFromStream() fails, error message message is not helpful
我正在尝试从位图资源加载ID2D1Bitmap。为此,我查阅了MSDN指南,该指南告诉我在Direct2D使用图像之前使用Windows映像组件(IWIC)来处理图像。
然而,当我调用CreateDecoderFromStream()
时,它失败了,它返回一条奇怪的错误消息0x88982f50
,告诉我任何信息。我搜索了谷歌,并使用DirectX错误查找。DirectX错误查找工具只告诉我这一点:
HRESULT: 0x88982f50 (2291674960)
Name: Unknown
Description: n/a
Severity code: Failed
Facility Code: FACILITY_DWRITE (2200)
Error Code: 0x2f50 (12112)
这是我用来尝试从资源加载ID2D1Bitmap的代码:
int LoadBitmapFromResource( IWICImagingFactory *pIWICFactory, ID2D1RenderTarget *pRT, int resID, ID2D1Bitmap **ppD2DBitmap )
{
int errmsg;
HRSRC hbmp;
HGLOBAL hbmpdata;
void *pbmp; //system memory pointer to bitmap resource
DWORD bmpsize;
IWICStream *pStream;
IWICBitmapDecoder *pbmpdecoder;
IWICBitmapFrameDecode *pSource;
IWICFormatConverter *pConverter;
hbmp = FindResourceW( GetModuleHandleW(NULL), MAKEINTRESOURCEW(resID), RT_BITMAP );
if( NULL == hbmp )
{
printf("LoadBitmapFromResource::FindResourceW() error: %drn", GetLastError() );
return GetLastError();
}
hbmpdata = LoadResource( GetModuleHandleW(NULL), hbmp );
if( NULL == hbmpdata )
{
printf("LoadBitmapFromResource::LoadResource() error: %drn", GetLastError() );
return GetLastError();
}
pbmp = LockResource( hbmpdata );
if( NULL == pbmp )
{
printf("LoadBitmapFromResource::LockResource() error: %drn", GetLastError() );
return GetLastError();
}
bmpsize = SizeofResource( GetModuleHandleW(NULL), hbmp );
if( NULL == bmpsize )
{
printf("LoadBitmapFromResource::SizeofResource() error: %drn", GetLastError() );
return GetLastError();
}
errmsg = pIWICFactory->CreateStream( &pStream );
if( !SUCCEEDED(errmsg) )
{
printf("LoadBitmapFromResource::CreateStream() error: %xrn", errmsg );
return errmsg;
}
errmsg = pStream->InitializeFromMemory( (BYTE*)pbmp, bmpsize );
if( !SUCCEEDED(errmsg) )
{
printf("LoadBitmapFromResource::InitializeFromMemory() error: %xrn", errmsg );
return errmsg;
}
errmsg = pIWICFactory->CreateDecoderFromStream( pStream, NULL, WICDecodeMetadataCacheOnLoad, &pbmpdecoder );
if( !SUCCEEDED(errmsg) )
{
printf("LoadBitmapFromResource::CreateDecoderFromStream() error: %xrn", errmsg );
return errmsg;
}
errmsg = pbmpdecoder->GetFrame( 0, &pSource );
if( !SUCCEEDED(errmsg) )
{
printf("LoadBitmapFromResource::GetFrame() error: %xrn", errmsg );
return errmsg;
}
errmsg = pIWICFactory->CreateFormatConverter( &pConverter );
if( !SUCCEEDED(errmsg) )
{
printf("LoadBitmapFromResource::CreateFormatConverter() error: %xrn", errmsg );
return errmsg;
}
errmsg = pConverter->Initialize( pSource, GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone, NULL, 0.0f, WICBitmapPaletteTypeMedianCut );
if( !SUCCEEDED(errmsg) )
{
printf("LoadBitmapFromResource::Initialize() error: %xrn", errmsg );
return errmsg;
}
errmsg = pRT->CreateBitmapFromWicBitmap( pConverter, ppD2DBitmap );
if( !SUCCEEDED(errmsg) )
{
printf("LoadBitmapFromResource::CreateBitmapFromWicBitmap() error: %xrn", errmsg );
return errmsg;
}
pConverter->Release();
pSource->Release();
pbmpdecoder->Release();
pStream->Release();
return 0;
}
事实证明,我不应该将WIC解码器用于位图资源,因为它显然是无法解码的原始像素数据。
我有与您完全相同的代码,用于使用WIC从exe文件中的资源加载ID2D1Bitmap,只是我的代码工作得很好。我可以完美地从我的exe文件中加载位图。我在您的代码中看到的与我的代码不同的一点是,我使用的不是(BYTE*)强制转换,而是repret_cast。
所以不是
errmsg = pStream->InitializeFromMemory( (BYTE*)pbmp, bmpsize );
if( !SUCCEEDED(errmsg) )
{
printf("LoadBitmapFromResource::InitializeFromMemory() error: %xrn", errmsg );
return errmsg;
}
我会尝试做
errmsg = pStream->InitializeFromMemory( reinterpret_cast<BYTE*>(pbmp), bmpsize );
if( !SUCCEEDED(errmsg) )
{
printf("LoadBitmapFromResource::InitializeFromMemory() error: %xrn", errmsg );
return errmsg;
}
发生此问题的原因是LockResource()返回的位图数据不包含前14个字节的位图标头。您可以将从LockResource()返回的数据与原始位图文件进行比较。这是C中的简单测试代码。您可以将其添加到SizeofResource()之后,然后检查out.bmp文件,这是一个无效的位图文件。由于图像数据不好,它没有任何有效的解码器(WINCODEC_ERR_COMPONENTNOTFOUND)。
FILE* file;
fopen_s( &file, "out.bmp", "wb");
fwrite((const char*)(pbmp), 1, bmpsize, file);
fclose(file);
有两个明显的解决方案。
不要从资源创建IWICStream/IWICBitmapDecoder。相反,直接使用外部位图文件来创建它们。请查看MSDN的示例代码。https://learn.microsoft.com/en-us/windows/win32/direct2d/how-to-load-a-direct2d-bitmap-from-a-file
在资源数据前面添加位图标头。类似于:
BITMAPFILEHEADER header; header.bfType = 0x4D42; // 'BM' header.bfSize = bmpsize + 14; // resource data size + 14 bytes header header.bfReserved1 = 0; header.bfReserved2 = 0; header.bfOffBits = 14 + 40; // details in bitmap format BYTE* buffer = new BYTE[header.bfSize]; memcpy(buffer, &header, 14); memcpy(buffer + 14, pbmp, bmpsize); // Initialize the stream with the memory pointer and size. hr = pStream->InitializeFromMemory( reinterpret_cast<BYTE*>(buffer), header.bfSize );
小心,在IWICStream的生命周期中,"缓冲区"必须是活的。
- boost::进程间消息队列引发错误
- C++错误消息*成员参考.**初学者*
- 如何通过参数抛出错误消息
- glad 导致 glfwSwapBuffers 返回错误消息
- FindPackageHandleStandardArgs.cmake:137 的 CMake 错误(消息):找不到 Boost (缺少:正则表达式)(找到合适的版本"1.72.0",
- 如何接受 [ENTER] 键作为无效输入并发送错误消息
- 重新定义预定义的 errno 错误消息 (E2BIG)
- SDL 映像:无法打开映像,仅显示错误消息
- 错误消息:使用"string* +="后"no match for 'operator+='"
- 使用公钥加密消息:BER 解码错误
- 我在主函数的左括号上不断收到错误,消息为obj\Debug\main.o||在函数"ZN11linked_listC1Ev"中:|
- 错误消息"expected expression"....有人知道它为什么这么说吗?
- 在 Eclipse: "error: no match for 'operator='" 中获取错误消息
- 出现分段错误时,更改显示的消息错误
- 使用C 中的OPENSL RSA函数解密消息错误
- Linux汇编程序消息错误c++
- C++写入消息错误
- 发送http post消息错误报告的安全方式
- C++,在尝试创建类时收到此消息:错误:没有在类“media”中声明的“void media::*()”成员函数
- 编译器错误消息错误:令牌之前的预期')' '*'。我的构造函数出错