0

ビットマップリソースからID2D1Bitmapを読み込もうとしています。そのために、Direct2Dが使用する前にWindows Imaging Component(IWIC)を使用して画像を処理するように指示されたMSDNガイドを参照しました。

ただし、を呼び出すと失敗しCreateDecoderFromStream()、奇妙なエラーメッセージが返されます– 0x88982f50–それは何も教えてくれません。Googleを検索し、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: %d\r\n", GetLastError() );
        return GetLastError();
    }

    hbmpdata = LoadResource( GetModuleHandleW(NULL), hbmp );
    if( NULL == hbmpdata )
    {
        printf("LoadBitmapFromResource::LoadResource() error: %d\r\n", GetLastError() );
        return GetLastError();
    }

    pbmp = LockResource( hbmpdata );
    if( NULL == pbmp )
    {
        printf("LoadBitmapFromResource::LockResource() error: %d\r\n", GetLastError() );
        return GetLastError();
    }

    bmpsize = SizeofResource( GetModuleHandleW(NULL), hbmp );
    if( NULL == bmpsize )
    {
        printf("LoadBitmapFromResource::SizeofResource() error: %d\r\n", GetLastError() );
        return GetLastError();
    }

    errmsg = pIWICFactory->CreateStream( &pStream );
    if( !SUCCEEDED(errmsg) )
    {
        printf("LoadBitmapFromResource::CreateStream() error: %x\r\n", errmsg );
        return errmsg;
    }

    errmsg = pStream->InitializeFromMemory( (BYTE*)pbmp, bmpsize );
    if( !SUCCEEDED(errmsg) )
    {
        printf("LoadBitmapFromResource::InitializeFromMemory() error: %x\r\n", errmsg );
        return errmsg;
    }

    errmsg = pIWICFactory->CreateDecoderFromStream( pStream, NULL, WICDecodeMetadataCacheOnLoad, &pbmpdecoder );
    if( !SUCCEEDED(errmsg) )
    {
        printf("LoadBitmapFromResource::CreateDecoderFromStream() error: %x\r\n", errmsg );
        return errmsg;
    }

    errmsg = pbmpdecoder->GetFrame( 0, &pSource );
    if( !SUCCEEDED(errmsg) )
    {
        printf("LoadBitmapFromResource::GetFrame() error: %x\r\n", errmsg );
        return errmsg;
    }

    errmsg = pIWICFactory->CreateFormatConverter( &pConverter );
    if( !SUCCEEDED(errmsg) )
    {
        printf("LoadBitmapFromResource::CreateFormatConverter() error: %x\r\n", errmsg );
        return errmsg;
    }

    errmsg = pConverter->Initialize( pSource, GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone, NULL, 0.0f, WICBitmapPaletteTypeMedianCut );
    if( !SUCCEEDED(errmsg) )
    {
        printf("LoadBitmapFromResource::Initialize() error: %x\r\n", errmsg );
        return errmsg;
    }

    errmsg = pRT->CreateBitmapFromWicBitmap( pConverter, ppD2DBitmap );
    if( !SUCCEEDED(errmsg) )
    {
        printf("LoadBitmapFromResource::CreateBitmapFromWicBitmap() error: %x\r\n", errmsg );
        return errmsg;
    }

    pConverter->Release();
    pSource->Release();
    pbmpdecoder->Release();
    pStream->Release();

    return 0;
}
4

3 に答える 3

0

デコードできない生のピクセルデータであるため、ビットマップリソースにWICデコーダーを使用するべきではないことがわかりました。

于 2012-04-08T16:52:30.820 に答える
0

(私は少し古いこの投稿を理解していますが、他の誰かまたはOPがこれを再び見た場合に役立つ場合に備えて、これをここに置いています。)

私はWICを使用してexeファイルのリソースからID2D1Bitmapをロードするためのあなたとまったく同じコードを持っていますが、私のものは完全に機能します。exeファイルからビットマップを問題なくロードできます。私のコードとは異なるコードの1つの違いは、(BYTE *)キャストを使用する代わりに、reinterpret_castを使用することです。

だから代わりに

errmsg = pStream->InitializeFromMemory( (BYTE*)pbmp, bmpsize );
    if( !SUCCEEDED(errmsg) )
    {
        printf("LoadBitmapFromResource::InitializeFromMemory() error: %x\r\n", errmsg );
        return errmsg;
    }

やってみます

errmsg = pStream->InitializeFromMemory( reinterpret_cast<BYTE*>(pbmp), bmpsize );
    if( !SUCCEEDED(errmsg) )
    {
        printf("LoadBitmapFromResource::InitializeFromMemory() error: %x\r\n", errmsg );
        return errmsg;
    }
于 2012-10-28T22:19:30.970 に答える
0

この問題は、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);

2つの明白な解決策があります。

  1. リソースからIWICStream/IWICBitmapDecoderを作成しないでください。代わりに、外部ビットマップファイルを直接使用して作成します。これについては、MSDNのサンプルコードを確認してください。https://docs.microsoft.com/en-us/windows/win32/direct2d/how-to-load-a-direct2d-bitmap-from-a-file

  2. リソースデータの前にビットマップヘッダーを追加します。何かのようなもの:

     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のライフサイクル中に存続している必要があることに注意してください。

于 2021-01-27T05:41:29.050 に答える