実現したいこと
こちらの記事を参考にし、Gdiplus::Bitmap::FromStreamで、メモリ上に展開されたpngファイルを読みます
前提
復号化したpngファイルをメモリ内に保持し、IStream化後、Gdiplus::Bitmapにすることを想定しています。
発生している問題・エラーメッセージ
FromStreamでBitmapは生成されますが、その大きさが0✕0です。
このときのBitmapで、GetLastStatus()を行うと2(invalidParameter)
となります。
しかも、この事象は、同じ画像ファイルでも現れるときと現れないときが
ランダムに起きるため、困っています。
該当のソースコード
C++
1void CreateJpegTexture(const void* iData, uint32_t iDataSize) 2{ 3 // グローバルメモリを確保してロック 4 HGLOBAL aGlobalHandle = GlobalAlloc(GMEM_MOVEABLE, iDataSize); 5 if(aGlobalHandle) 6 { 7 void* aGlobalBuffer = GlobalLock(aGlobalHandle); 8 if(aGlobalBuffer) 9 { 10 // グローバルメモリにコピー 11 CopyMemory(aGlobalBuffer, iData, iDataSize); 12 13 // ストリーム作成 14 IStream* aIStream = NULL; 15 if(CreateStreamOnHGlobal(aGlobalHandle, FALSE, &aIStream) == S_OK) 16 { 17 // GDI+ビットマップ生成(グローバルメモリは解放) 18 Gdiplus::Bitmap* aBitmap = Gdiplus::Bitmap::FromStream(aIStream); 19 aIStream->Release(); 20 if(aBitmap && aBitmap->GetLastStatus() == Gdiplus::Ok) 21 { 22 // バッファにコピー 23 UINT aWidth = aBitmap->GetWidth(); 24 UINT aHeight = aBitmap->GetHeight(); 25 Gdiplus::Rect aRect(0, 0, aWidth, aHeight); 26 Gdiplus::BitmapData aBitmapData; 27 aBitmap->LockBits(&aRect, Gdiplus::ImageLockModeRead, PixelFormat32bppARGB, &aBitmapData); 28 const uint8_t* aPixels = reinterpret_cast<const uint8_t*>(aBitmapData.Scan0); 29 std::vector<uint32_t> aBuffer(aWidth * aHeight); 30 for(UINT aY = 0; aY != aHeight; ++aY) 31 { 32 for(UINT aX = 0; aX != aWidth; ++aX) 33 { 34 const uint8_t* aPixel = aPixels + aY * aBitmapData.Stride + aX * 4; 35 uint32_t aR = aPixel[2]; 36 uint32_t aG = aPixel[1]; 37 uint32_t aB = aPixel[0]; 38 uint32_t aA = aPixel[3]; 39 aR = aR * aA / 255; 40 aG = aG * aA / 255; 41 aB = aB * aA / 255; 42 aBuffer[aY * aWidth + aX] = (aA << 24) | (aB << 16) | (aG << 8) | aR; 43 } 44 } 45 aBitmap->UnlockBits(&aBitmapData); 46 47 // 解放 48 delete aBitmap; 49 50 // ~aBufferにピクセルデータが格納されている~ 51 } 52 } 53 54 // アンロック 55 GlobalUnlock(aGlobalHandle); 56 } 57 58 // 解放 59 GlobalFree(aGlobalHandle); 60 } 61}
上記20行目でaBitmap->GetLastStatus() == Gdiplus::Okにならないことがあります。
試したこと
ランダムに発生する事象なので、確保したが初期化されてないメモリが影響したと思い、10行目に
C++
1memset(aGlobalBuffer, 0, iDataSize);
で、確保されたメモリを0で埋めましたが、結果は変わっていません。
補足情報(FW/ツールのバージョンなど)
Microsoft Visual Studio Community 2022 (64 ビット) - Current
Version 17.4.4
よろしくお願いいたします。
回答1件
あなたの回答
tips
プレビュー