GetPixel的速度太慢了,请问如何用GetDIBits解决这个问题?(300)

  • 主题发起人 主题发起人 maxnow
  • 开始时间 开始时间
M

maxnow

Unregistered / Unconfirmed
GUEST, unregistred user!
声明:不想用TBitmap,务必用GetDIBits解决,怎么搞?一下这段代码是我自己写的,对屏幕的每个点进行扫描。速度非常慢!!即使把ListBox1.items.add(inttostr(Pix));注释掉,也要1分半钟左右,才能扫描完。本人机器酷睿双核,4G内存,配置算是很不错了,还这么慢,怎么办?procedure TForm1.Button1Click(Sender: TObject);var X, Y: integer; iX, iY: integer; pix: DWORD; DC: HDC;begin DC := GetDC(0); X := GetSystemMetrics(SM_CXSCREEN); //得到屏幕的宽度 Y := GetSystemMetrics(SM_CYSCREEN); //得到屏幕的高度 for iY := 4 to Y do //高度 for iX := 1 to X do //宽度 begin Pix := Windows.GetPixel(DC, iX, iY); ListBox1.items.add(inttostr(Pix)); //输入每个像素点的颜色值 end; Windows.ReleaseDC(0, DC);end;///////////////////////// 这里是重点了 /////////////////////////查了资料后,才知道可以用GetDIBits这个API,但是用起来好复杂,找到了C代码后,将它翻译成了Delphi代码,却不知道怎么将lpBuf里面的每个像素点输出了。研究了整整2天,能查到的资料也非常少,跪求高手解决,300相送。procedure TForm1.Button6Click(Sender: TObject);const HEAP_ZERO_MEMORY = $8;var b: BITMAPINFO; bb: bitmap; lpBuf: array of byte; _hbitmap, hold: hbitmap; _hdc, _hcdc: hdc; hp: thandle; dwx, dwy: dword;begin dwX := GetSystemMetrics(SM_CXSCREEN); dwY := GetSystemMetrics(SM_CYSCREEN); _hDC := GetDC(0); _hcDC := CreateCompatibleDC(_hDC); _hBitmap := CreateCompatibleBitmap(_hDC, dwX, dwY); hOld := SelectObject(_hcDC, _hBitmap); BitBlt(_hcDC, 0, 0, dwX, dwY, _hDC, 0, 0, SRCCOPY); bb.bmWidth := dwX; bb.bmHeight := dwY; bb.bmPlanes := 1; bb.bmWidthBytes := bb.bmWidth * 3; bb.bmBitsPixel := 3; bb.bmType := 0; b.bmiHeader.biSize := sizeof(BITMAPINFOHEADER); b.bmiHeader.biWidth := dwX; b.bmiHeader.biHeight := dwY; b.bmiHeader.biPlanes := 1; b.bmiHeader.biBitCount := 24; b.bmiHeader.biCompression := BI_RGB; b.bmiHeader.biSizeImage := 0; b.bmiHeader.biXPelsPerMeter := 0; b.bmiHeader.biYPelsPerMeter := 0; b.bmiHeader.biClrUsed := 0; b.bmiHeader.biClrImportant := 0; b.bmiColors[0].rgbBlue := 8; b.bmiColors[0].rgbGreen := 8; b.bmiColors[0].rgbRed := 8; b.bmiColors[0].rgbReserved := 0; hp := GetProcessHeap; lpBuf := HeapAlloc(hp, HEAP_ZERO_MEMORY, bb.bmHeight * bb.bmWidth * 4); GetDIBits(_hcDC, _hBitmap, 0, dwY, lpBuf, b, DIB_RGB_COLORS); for x := 1 to dwX do //////////// 这里到底应该怎么输入每个像素点的颜色值啊??? for y := 1 to dwY do /// 难道是我的代码没翻译好????????? ListBox1.Items.Add(lpBuf[x, y]); //输入每个像素点的颜色 ReleaseDC(0, _hDC); DeleteDC(_hcDC); DeleteObject(_hBitmap); DeleteObject(hOld); HeapFree(hp, 0, lpBuf);end;///////////////////////// 这里是重点了 /////////////////////////查了资料后,才知道可以用GetDIBits这个API,但是用起来好复杂,找到了C代码后,将它翻译成了Delphi代码,却不知道怎么将lpBuf里面的每个像素点输出了。研究了整整2天,能查到的资料也非常少,跪求高手解决。声明:不想用TBitmap,务必用GetDIBits解决,怎么搞?
 
例子的思想是将屏幕复制到一个与设备无关的位图中,扫描位图得到每个像素点颜色,该位图格式由结构b定义,每个像素占用4个字节0 R 1 G 2 B 3保留,lpBuf是字节指针:像素点地址计算dwX*4*(y-1)+(x-1)*4;lpBuf是DWORD指针:像素点地址计算dwX*(y-1)+x-1。指针指向的地址内就是像素点的颜色。
 
scanline是最快的。
 
人家只相信API
 
迷信是没有好处的
 
帮UP。。。good luck
 
加定义:var m_pInt:PInteger;循环前赋值:m_pInt:= lpBuf;循环:begin ListBox1.Items.Add(IntToStr(m_pInt^)); inc(m_pInt);end;指针访问边界的检测由你自己搞定。
 
后退
顶部