Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Getting pixelcolor with GetBitmapBits or GetDIBits


  • Please log in to reply
1 reply to this topic
AHKisNice
  • Members
  • 35 posts
  • Last active: May 22 2010 01:57 PM
  • Joined: 11 Jan 2008
Hello. Could anyone please help me adjust my code so that I can use GetBitmapBits or GetDIBits to get the color of a pixel? e.g. 150 150. Thank you.
ifwinnotexist Untitled - Notepad
run notepad
winwait Untitled - Notepad
winactivate Untitled - Notepad
id := winexist("Untitled - Notepad")
gotten_dc:=       dllcall("GetDC",                    uint,id)
created_dc:=      dllcall("CreateCompatibleDC",       uint,gotten_dc)
wingetpos,,,w,h,% "ahk_id" id
created_bitmap:=  dllcall("CreateCompatibleBitmap",   uint,gotten_dc,   int,w,   int,h)
dllcall("SelectObject",  uint,created_dc,   uint,created_bitmap)
dllcall("PrintWindow",  uint,id,   uint,created_dc,    uint,0)
  setformat integer,hex
  DllCall("GetBitmapBits",      UInt,created_bitmap,       UInt,VarSetCapacity(bits,w*h*4,0),     UInt,&bits)  
  numget_pixel   := NumGet(bits,0) ;so how do I get the pixel at 150,150?
  getpixel_pixel := dllcall("GetPixel",   uint,created_dc,  int,150,    int,150) 
TOOLTIP %  getpixel_pixel "`n"numget_pixel            ,150,150 "n" ;compare pixels gotten by different methods to check theyre the same
dllcall("DeleteObject",  uint,created_bitmap)
dllcall("ReleaseDC",     uint,id,   uint,gotten_dc)
dllcall("DeleteDC",      uint,created_dc)


Jamie
  • Members
  • 129 posts
  • Last active: Dec 02 2012 04:59 AM
  • Joined: 26 Mar 2010
Use GetDIBits. First make a bitmapinfo structure:
MakeBitmapInfoHeader(ByRef bi, width, height, bpp) {
  VarSetCapacity(bi, 40, 0)
  NumPut(40, bi)     ; size of the structure
  NumPut(width, bi, 4)  ; image width
  NumPut(height, bi, 8)  ; image height, positive means lines go bottom to top
  NumPut(1, bi, 12, "UShort")   ; planes, has to be 1
  NumPut(bpp, bi, 14, "UShort") ; bits per pixel
  NumPut(0, bi, 16)  ; zero means compression is BI_RGB, or uncompressed
}
And also allocate a buffer to hold the DIB:
AllocateDIBBuf(ByRef buf, width, height, bpp) {
  bytesperpix := bpp//8
  linebytes := (width*bytesperpix + 3)//4 * 4 ; round up to the next multiple of 4 bytes
  VarSetCapacity(buf, linebytes*height)
  return linebytes*height
}
Then, after you copy the data to the DIB buffer, this is how to extract a pixel from a DIB:
DIBGetPixel(ByRef dibbuf, dibwidth, dibheight, dibbpp, x, y, ByRef r, ByRef g, ByRef b) {
  bytesperpix := dibbpp//8
  linebytes := (dibwidth*bytesperpix + 3)//4 * 4 ; round up to the next multiple of 4 bytes
  b := NumGet(dibbuf, (dibheight-1-y)*linebytes+x*bytesperpix, "UChar")
  g := NumGet(dibbuf, (dibheight-1-y)*linebytes+x*bytesperpix+1, "UChar")
  r := NumGet(dibbuf, (dibheight-1-y)*linebytes+x*bytesperpix+2, "UChar")
}

Putting it all together, you would have this:
MakeBitmapInfoHeader(ByRef bi, width, height, bpp) {
  VarSetCapacity(bi, 40, 0)
  NumPut(40, bi)     ; size of the structure
  NumPut(width, bi, 4)  ; image width
  NumPut(height, bi, 8)  ; image height, positive means lines go bottom to top
  NumPut(1, bi, 12, "UShort")   ; planes, has to be 1
  NumPut(bpp, bi, 14, "UShort") ; bits per pixel
  NumPut(0, bi, 16)  ; zero means compression is BI_RGB, or uncompressed
}

AllocateDIBBuf(ByRef buf, width, height, bpp) {
  bytesperpix := bpp//8
  linebytes := (width*bytesperpix + 3)//4 * 4 ; round up to the next multiple of 4 bytes
  VarSetCapacity(buf, linebytes*height)
  return linebytes*height
}

DIBGetPixel(ByRef dibbuf, dibwidth, dibheight, dibbpp, x, y, ByRef r, ByRef g, ByRef b) {
  bytesperpix := dibbpp//8
  linebytes := (dibwidth*bytesperpix + 3)//4 * 4 ; round up to the next multiple of 4 bytes
  b := NumGet(dibbuf, (dibheight-1-y)*linebytes+x*bytesperpix, "UChar")
  g := NumGet(dibbuf, (dibheight-1-y)*linebytes+x*bytesperpix+1, "UChar")
  r := NumGet(dibbuf, (dibheight-1-y)*linebytes+x*bytesperpix+2, "UChar")
}

ifwinnotexist Untitled - Notepad
run notepad
winwait Untitled - Notepad
winactivate Untitled - Notepad
id := winexist("Untitled - Notepad")
gotten_dc:=       dllcall("GetDC",                    uint,id)
created_dc:=      dllcall("CreateCompatibleDC",       uint,gotten_dc)
wingetpos,,,w,h,% "ahk_id" id
created_bitmap:=  dllcall("CreateCompatibleBitmap",   uint,gotten_dc,   int,w,   int,h)
dllcall("SelectObject",  uint,created_dc,   uint,created_bitmap)
dllcall("PrintWindow",  uint,id,   uint,created_dc,    uint,0)

MakeBitmapInfoHeader(bmi, w, h, 24)
AllocateDIBBuf(dibbuf, w, h, 24)
DllCall("GetDIBits", "UInt", gotten_dc, "UInt", created_bitmap, "UInt", 0, "UInt", h, "UInt", &dibbuf, "UInt", &bmi, "UInt", 0)
DIBGetPixel(dibbuf, w, h, 24, 150, 150, r, g, b)

getpixel_pixel := dllcall("GetPixel",   uint,created_dc,  int,150,    int,150)
gpb := getpixel_pixel >> 16
gpg := (getpixel_pixel >> 8) & 255
gpr := getpixel_pixel & 255

MsgBox, Pixel at 150`, 150 is %r% %g% %b% vs %gpr% %gpg% %gpb%

dllcall("DeleteObject",  uint,created_bitmap)
dllcall("ReleaseDC",     uint,id,   uint,gotten_dc)
dllcall("DeleteDC",      uint,created_dc)