0

デスクトップ(またはフォーム)に表示する必要のあるバイト配列があります。そのためにWinApiを使用していますが、すべてのピクセルを一度に設定する方法がわかりません。バイト配列は私のメモリにあり、(WinApiだけで)できるだけ早く表示する必要があります。

私はC#を使用していますが、単純な擬似コードで問題ありません。

// create bitmap
byte[] bytes = ...;// contains pixel data, 1 byte per pixel
HDC desktopDC = GetWindowDC(GetDesktopWindow());
HDC bitmapDC = CreateCompatibleDC(desktopDC);
HBITMAP bitmap = CreateCompatibleBitmap(bitmapDC, 320, 240);
DeleteObject(SelectObject(bitmapDC, bitmap));

BITMAPINFO info = new BITMAPINFO();
info.bmiColors = new tagRGBQUAD[256];
for (int i = 0; i < info.bmiColors.Length; i++)
{
    info.bmiColors[i].rgbRed = (byte)i;
    info.bmiColors[i].rgbGreen = (byte)i;
    info.bmiColors[i].rgbBlue = (byte)i;
    info.bmiColors[i].rgbReserved = 0;
}
info.bmiHeader = new BITMAPINFOHEADER();
info.bmiHeader.biSize = (uint) Marshal.SizeOf(info.bmiHeader);
info.bmiHeader.biWidth = 320;
info.bmiHeader.biHeight = 240;
info.bmiHeader.biPlanes = 1;
info.bmiHeader.biBitCount = 8;
info.bmiHeader.biCompression = BI_RGB;
info.bmiHeader.biSizeImage = 0;
info.bmiHeader.biClrUsed = 256;
info.bmiHeader.biClrImportant = 0;
// next line throws wrong parameter exception all the time
// SetDIBits(bitmapDC, bh, 0, 240, Marshal.UnsafeAddrOfPinnedArrayElement(info.bmiColors, 0), ref info, DIB_PAL_COLORS);

// how do i store all pixels into the bitmap at once ?
for (int i = 0; i < bytes.Length;i++)
    SetPixel(bitmapDC, i % 320, i / 320, random(0x1000000));

// draw the bitmap
BitBlt(desktopDC, 0, 0, 320, 240, bitmapDC, 0, 0, SRCCOPY);

各ピクセルを単独で設定しようとすると、SetPixel()グレー色のないモノクロ画像が白黒だけで表示されます。表示用のグレースケールビットマップを正しく作成するにはどうすればよいですか?そして、どうすればそれをすばやく行うことができますか?


更新: WinApiのプログラムの外部で呼び出しがエラーになります。例外をキャッチできません:

public const int DIB_RGB_COLORS = 0;
public const int DIB_PAL_COLORS = 1;

[DllImport("gdi32.dll")]
public static extern int SetDIBits(IntPtr hdc, IntPtr hbmp, uint uStartScan, uint cScanLines, byte[] lpvBits, [In] ref BITMAPINFO lpbmi, uint fuColorUse);

// parameters as above
SetDIBits(bitmapDC, bitmap, 0, 240, bytes, ref info, DIB_RGB_COLORS);
4

1 に答える 1

1

SetDIBitsパラメータのうち 2 つが間違っています。

  • lpvBits- これは画像データですが、パレット データを渡しています。bytes配列を渡す必要があります。
  • lpBmi- これで問題ありません -BITMAPINFO構造体にはBITMAPINFOHEADERと パレットの両方が含まれているため、パレットを個別に渡す必要はありません。あなたの他の質問に対する私の答えは、構造を宣言する方法を説明しています。
  • fuColorUse- パレットのフォーマットについて説明します。RGB パレットを使用しているので、パスする必要がありDIB_RGB_COLORSます。
于 2013-02-25T20:49:16.443 に答える