C# ASP.NET Core 3.1 でデバイスに依存しないビットマップ (DIB) ポインターをビットマップとして正しく取得するにはどうすればよいですか?
問題: Dib ポインターからビットマップを保存しようとすると、System.AccessViolationException: 'Attempted to read or write protected memory. これは多くの場合、他の記憶が失われたことを示しています」
次のコンストラクター Bitmap(Int32, Int32, Int32, PixelFormat, IntPtr)を、最後のパラメーターが DIB ポインターを使用できるという前提で使用しています。
using System.Drawing.Common.dll
Bitmap(Int32, Int32, Int32, PixelFormat, IntPtr)
次の構文を使用します。
public class Example
{
[DllImport("kernel32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
public static extern IntPtr GlobalLock(int handle);
//https://stackoverflow.com/questions/2185944/why-must-stride-in-the-system-drawing-bitmap-constructor-be-a-multiple-of-4
public void GetStride(int width, PixelFormat format, ref int stride, ref int bytesPerPixel)
{
int bitsPerPixel = System.Drawing.Image.GetPixelFormatSize(format);
bytesPerPixel = (bitsPerPixel + 7) / 8;
stride = 4 * ((width * bytesPerPixel + 3) / 4);
}
public Bitmap ConvertDibToBitmap(IntPtr dib)
{
IntPtr dibPtr = GlobalLock(dib);
BITMAPINFOHEADER bmi = (BITMAPINFOHEADER)Marshal.PtrToStructure(dibPtr, typeof(BITMAPINFOHEADER));
/*
biBitCount: 24
biClrImportant: 0
biClrUsed: 0
biCompression: 0
biHeight: 2219
biPlanes: 1
biSize: 40
biSizeImage: 12058624
biWidth: 1704
biXPelsPerMeter: 7874
biYPelsPerMeter: 7874
*/
//We're able to initalize the object here:
Bitmap img = new Bitmap(bmi.biWidth, bmi.biHeight, stride, PixelFormat.Format32bppArgb, dibPtr);
img.Save("OutputTest.bmp");
/*This line throws the exception "System.AccessViolationException: 'Attempted to read or write protected memory. This is often an indication that other memory"*/
}
}
問題は、ストライドおよび/またはピクセル形式の計算にあると想定しています。BITMAPINFOHEADERからPixelFormatを判別する方法がわかりません