Jump to content

Recommended Posts

Posted

Ok guys i have been trying to load an image into hBitmap and read all the pixels (colors) into an array so i have developed something which is incomplete because i havent find a chance to figure out something... Any help would be appreciated... Change the code below so that i can read the images from a file not (desktop coordinates) into an array...

here is my code which reads pixels (very fast) from a Context Device which belongs to desktop coords (not image coords)

#include <WinAPI.au3>
#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <String.au3>
#include <misc.au3>
#include <ScreenCapture.au3>
#include <Array.au3>


HotKeySet("`", "GetPixels")
HotKeySet("{ESC}", "terminate")
HotKeySet("1", "ShowNewImage")

; Device contexts
Dim $hDC, $hCDC
Dim $aDIB, $hGraphic, $hBitmap
Dim $aiColorMatrix[1][1]

; single char size in pixels
Const $iX = 0
Const $iY = 0
Const $iWidth = 30
Const $iHeight = 30

Const $DEFAULT_TRESHOLD = 1
Const $iBitCount = 24
;Having selected the area of screen to duplicate, this function reads all the pixels within
; the rectangle. It put all the pixel in an array that don't match the color of the top left
; corner pixel. It assigns x, y values to each pixel. These values are relative to the centre
; pixel of the rectangle.
Func GetPixels()
    Local $row, $incremArray

    $tBMI = DllStructCreate($tagBITMAPINFO)
    DllStructSetData($tBMI, "Size", DllStructGetSize($tBMI) - 4)
    DllStructSetData($tBMI, "Width", $iWidth)
    DllStructSetData($tBMI, "Height", -$iHeight)
    DllStructSetData($tBMI, "Planes", 1)
    DllStructSetData($tBMI, "BitCount", $iBitCount)
    $hDC = _WinAPI_GetDC(0)
    $hCDC = _WinAPI_CreateCompatibleDC($hDC)
    
   ; Siao's bodacious creation
    $aDIB = DllCall('gdi32.dll', 'ptr', 'CreateDIBSection', _
            'ptr', 0, _
            'ptr', DllStructGetPtr($tBMI), _
            'uint', 1, _
            'ptr*', 0, _
            'ptr', 0, _
            'uint', 0)
    _WinAPI_SelectObject($hCDC, $aDIB[0])
    _WinAPI_BitBlt($hCDC, 0, 0, $iWidth, $iHeight, $hDC, $iX, $iY, $SRCCOPY)
    
;_ScreenCapture_Capture("deneme.jpg",$iX,$iY, $iX + $iWidth, $iY + $iHeight, False)
    $tBits = DllStructCreate('byte[' & $iWidth * $iHeight * $iBitCount / 8 & ']', $aDIB[4])
    $sHex = Hex(DllStructGetData($tBits, 1), 6)
   ;ConsoleWrite($sHex & @CRLF)
    $row = StringSplit(StringRegExpReplace($sHex, '(.){6}', '$0Chr(0)',0),'Chr(0)',1)
    ConsoleWrite("done getting array" & @CRLF)
;_ArrayDisplay($row)
    
    ReDim $aiColorMatrix[$iWidth][$iHeight]
    
    $pCtr = 0
    For $wCtr = 0 To $iWidth - 1
        For $hCtr = 0 To $iHeight - 1
            $pCtr = $pCtr + 1
            $aiColorMatrix[$wCtr][$hCtr] = $row[$pCtr]
        Next
    Next
    _ArrayDisplay($aiColorMatrix)
EndFunc  ;==>GetPixels

Func SetPixel($hDC, $iX, $iY, $iColor, $hDll = "gdi32.dll")
    $iColor = DllCall($hDll, "int", "SetPixel", "int", $hDC, "int", $iX, "int", $iY, "int", $iColor)
    If $iColor[0] = -1 Then Return SetError(1, 0, -1)
    Return $iColor[0]
EndFunc  ;==>_PixelGetColor_GetPixelRaw

Func ShowNewImage()
    $iTreshold = 1
    ConsoleWrite("Writing pixels" & @CRLF)
    
    For $i = 0 To $iWidth - 1
        For $j = 0 To $iHeight - 1
            SetPixel($hDC, $i,$j, $aiColorMatrix[$j][$i])
            #cs
            If $aiColorMatrix[$i][$j] < $iTreshold Then 
                SetPixel($hCDC, $i,$j, 0xFFFFFF)
            Else
                SetPixel($hCDC, $i,$j, 0x000000)
            EndIf
            #ce
            
        Next
    Next
    ConsoleWrite("Creating GUI to display image" & @CRLF)
    $hGUI = GUICreate("", $iWidth + 1, $iHeight + 1,$iX, $iY,$WS_POPUP)
    
    GUISetState()

   ; Initialize GDI+ library
    _GDIPlus_Startup ()

   ; Draw bitmap to GUI
    $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP ($aDIB[0])
    $hGraphic = _GDIPlus_GraphicsCreateFromHWND ($hGUI)
    
    _GDIPlus_GraphicsDrawImage ($hGraphic, $hBitmap, 0, 0)


   ; Loop until user exits
    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE
    
    Finalize()
    
    GUIDelete($hGUI)
    
EndFunc

Func Finalize()
; Clean up resources
    _GDIPlus_GraphicsDispose ($hGraphic)
    _GDIPlus_ImageDispose ($hBitmap)
    _WinAPI_DeleteObject($aDIB[0])
    _WinAPI_DeleteDC($hCDC)
    _WinAPI_ReleaseDC(0, $hDC)
   ; Shut down GDI+ library
    _GDIPlus_ShutDown ()
EndFunc

Func terminate()
    Exit
EndFunc

While (1)
    Sleep(10)
WEnd

Your mission (Summary) : Change the code so that it reads pixels from an image rather than the screen coordinates (cdc)

Posted

Here is old original code from Larry (he deleted his posts):

getpixel_from_external_bmp.au3

$szPicFile = ".\larry.bmp"
$x = 62
$y = 82

Const $GWL_HINSTANCE = -6
Const $IMAGE_BITMAP = 0
Const $LR_LOADFROMFILE = 0x0010 

Dim $hInst, $hBmp, $hMemDC, $hwnd

Opt("WinWaitDelay",1)
AutoItWinSetTitle("qqqqqq")
$hwnd = WinGetHandle("qqqqqq")

$hInst = DllCall("user32.dll","int","GetWindowLong","hWnd",$hwnd, "int",$GWL_HINSTANCE) 
$hInst = $hInst[0]

$hBmp = DllCall("user32.dll","hwnd","LoadImage","hwnd",$hInst,"str",$szPicFile,"int",$IMAGE_BITMAP, _
        "int",0,"int",0,"int",$LR_LOADFROMFILE)
$hBmp = $hBmp[0]

$hMemDC = DllCall("gdi32.dll", "int", "CreateCompatibleDC", "int", 0)
$hMemDC = $hMemDC[0]

DllCall("gdi32.dll", "hwnd", "SelectObject", "int", $hMemDC, "hwnd", $hBmp)

$ret = DLLCall("gdi32.dll","int","GetPixel","int",$hMemDC,"int",$x,"int",$y)
$ret = Hex( $ret[0], 6)
$ret = StringRight($ret,2) & StringMid($ret,3,2) & StringLeft($ret,2)

DllCall("gdi32.dll", "int", "DeleteDC", "hwnd", $hMemDC)
DllCall("gdi32.dll", "int", "DeleteObject", "hwnd", $hBmp)

MsgBox(4096,"",$ret)

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...