HBITMAPからGdiplus :: Bitmapを作成し、アルファチャネル情報を保持する方法は?

StackOverflow https://stackoverflow.com/questions/335273

  •  22-07-2019
  •  | 
  •  

質問

Bitmap :: FromHBITMAP関数を使用して新しいGdiplus :: Bitmapを作成すると、 結果のビットマップは不透明です-元のHBITMAPの部分的な透明度は保持されません。

アルファチャネルデータを転送するHBITMAPからGdiplus :: Bitmapを作成する方法はありますか?

役に立ちましたか?

解決 2

HBITMAPからビットマップを作成する際に、GDI +がアルファチャンネルを通過させることはありません。

答えは次のとおりです。

  • GetObjectをBITMAPおよびHBITMAPに渡し、入力HBITMAPの幅と高さ(および入力ビットマップがDIBの場合はピクセルデータ)を取得します。
  • 32ビットPARGBピクセル形式で正しいサイズのビットマップを作成します。
  • LockBitsを使用して、新しいビットマップのpixelDataメモリを取得します。
  • GetObjectからピクセルを取得した場合は、memcpyを使用してARGB値をコピーします。
  • 新しいビットマップでUnlockBitsを呼び出します。

私の場合、入力HBITMAPの形式は、入力ビットマップピクセルデータから新しいビットマップピクセルデータへのまっすぐなmemcpyを実行するのに適しています。

GetObjectから入力ピクセルデータを取得しなかった場合、GetDIBitsを使用して正しい形式でコピーを取得します。

他のヒント

作業コードは指示よりも便利だと思うので:

#include <GdiPlus.h>
#include <memory>

Gdiplus::Status HBitmapToBitmap( HBITMAP source, Gdiplus::PixelFormat pixel_format, Gdiplus::Bitmap** result_out )
{
  BITMAP source_info = { 0 };
  if( !::GetObject( source, sizeof( source_info ), &source_info ) )
    return Gdiplus::GenericError;

  Gdiplus::Status s;

  std::auto_ptr< Gdiplus::Bitmap > target( new Gdiplus::Bitmap( source_info.bmWidth, source_info.bmHeight, pixel_format ) );
  if( !target.get() )
    return Gdiplus::OutOfMemory;
  if( ( s = target->GetLastStatus() ) != Gdiplus::Ok )
    return s;

  Gdiplus::BitmapData target_info;
  Gdiplus::Rect rect( 0, 0, source_info.bmWidth, source_info.bmHeight );

  s = target->LockBits( &rect, Gdiplus::ImageLockModeWrite, pixel_format, &target_info );
  if( s != Gdiplus::Ok )
    return s;

  if( target_info.Stride != source_info.bmWidthBytes )
    return Gdiplus::InvalidParameter; // pixel_format is wrong!

  CopyMemory( target_info.Scan0, source_info.bmBits, source_info.bmWidthBytes * source_info.bmHeight );

  s = target->UnlockBits( &target_info );
  if( s != Gdiplus::Ok )
    return s;

  *result_out = target.release();

  return Gdiplus::Ok;
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top