ネイティブWindows関数からHBITMAPオブジェクト/ハンドルを取得したとします。 Bitmap.FromHbitmap(nativeHBitmap)を使用して管理されたビットマップに変換できますが、ネイティブイメージに透過情報(アルファチャンネル)がある場合は、この変換によって失われます。アルファチャンネル/透過性を維持しながらC#でネイティブのHBitmapを使用
この問題に関しては、スタックオーバーフローに関するいくつかの質問があります。この質問の最初の回答(How to draw ARGB bitmap using GDI+?)の情報を使用して、私が試したコードを書いたところ、それが動作します。
Bitmap managedBitmap = new Bitmap(bitmapStruct.bmWidth, bitmapStruct.bmHeight,
bitmapStruct.bmWidth * 4, PixelFormat.Format32bppArgb, bitmapStruct.bmBits);
とおり
それは基本的に、その後ネイティブHBITMAP幅、高さ及びのGetObject用いた画素データの位置を指すポインタとBITMAP構造を取得し、管理ビットマップコンストラクタを呼び出します私は間違っていると私を訂正してください。ネイティブのHBitmapから管理されたビットマップに実際のピクセルデータをコピーするのではなく、管理されたビットマップをネイティブHBitmapのピクセルデータにポイントするだけです。
そして、特に大きいビットマップの場合、不要なメモリコピーを避けるために、別のGraphics(DC)または別のビットマップにビットマップを描画しません。
このビットマップは、ピクチャボックスコントロールまたはフォームBackgroundImageプロパティに割り当てることができます。そして、ビットマップが正しく表示され、透明性を使用して動作します。
ビットマップを使用しなくなったとき、BackgroundImageプロパティがビットマップを指していないことを確認し、管理ビットマップとネイティブHBitmapの両方を破棄します。
質問:この推論とコードが正しいかどうか教えてください。予期せぬ動作やエラーが発生しないように願っています。そして、私はすべての記憶とオブジェクトを正しく解放してくれることを願っています。
private void Example()
{
IntPtr nativeHBitmap = IntPtr.Zero;
/* Get the native HBitmap object from a Windows function here */
// Create the BITMAP structure and get info from our nativeHBitmap
NativeMethods.BITMAP bitmapStruct = new NativeMethods.BITMAP();
NativeMethods.GetObjectBitmap(nativeHBitmap, Marshal.SizeOf(bitmapStruct), ref bitmapStruct);
// Create the managed bitmap using the pointer to the pixel data of the native HBitmap
Bitmap managedBitmap = new Bitmap(
bitmapStruct.bmWidth, bitmapStruct.bmHeight, bitmapStruct.bmWidth * 4, PixelFormat.Format32bppArgb, bitmapStruct.bmBits);
// Show the bitmap
this.BackgroundImage = managedBitmap;
/* Run the program, use the image */
MessageBox.Show("running...");
// When the image is no longer needed, dispose both the managed Bitmap object and the native HBitmap
this.BackgroundImage = null;
managedBitmap.Dispose();
NativeMethods.DeleteObject(nativeHBitmap);
}
internal static class NativeMethods
{
[StructLayout(LayoutKind.Sequential)]
public struct BITMAP
{
public int bmType;
public int bmWidth;
public int bmHeight;
public int bmWidthBytes;
public ushort bmPlanes;
public ushort bmBitsPixel;
public IntPtr bmBits;
}
[DllImport("gdi32", CharSet = CharSet.Auto, EntryPoint = "GetObject")]
public static extern int GetObjectBitmap(IntPtr hObject, int nCount, ref BITMAP lpObject);
[DllImport("gdi32.dll")]
internal static extern bool DeleteObject(IntPtr hObject);
}
"このコードを確認してください、それは自分のコンピュータで動作します..."のようなものは、本当に質問やトピックタイトルに属していません。 –
あなたは正しいです、私はタイトルを変更しました。それは質問ですが、それにもコードがあります。 – AnAurelian