0
我有一個需要在桌面(或窗體)上顯示的字節數組。我正在使用WinApi,不確定如何一次設置所有像素。字節數組在我的記憶中,並且需要儘快顯示(僅使用WinApi)。WinApi - 字節數組到灰度8位位圖(+性能)
我使用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);
感謝您試圖幫助解決這兩個問題。但更改參數後,應用程序崩潰,我無法捕捉異常。請參閱更新。 – Bitterblue 2013-02-26 08:11:28
我嘗試過使用SetDIBits的聲明,並將BITMAPINFO中的SizeConst設置爲256.它可以工作。還有其他一些錯誤。對CreateCompatibleBitmap的調用應使用桌面DC,否則您將獲得單色位圖(因爲新DC中的默認位圖是單色的)。您不應該在SelectObject的返回值上調用DeleteObject(當您完成後,您應該選擇原始對象回到DC中,並刪除新對象)。 – arx 2013-02-26 14:02:34