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参数中有两个错误:

  • lpvBits- 这是图像数据,但您正在传递调色板数据。你应该传递你的bytes数组。
  • lpBmi- 这没关系 -BITMAPINFO结构同时包含BITMAPINFOHEADER和调色板,因此您不需要单独传递调色板。我对您其他问题的回答描述了如何声明结构。
  • fuColorUse- 这描述了调色板的格式。您正在使用 RGB 调色板,因此您应该通过DIB_RGB_COLORS.
于 2013-02-25T20:49:16.443 回答