There is a near exact question here Read pixel colors of an image
The Op actually asks the same question as I'm asking for. But accepts an answer that is nearly there but not quite.. The code below (taken from that thread) does everything I need bar the pixel by pixel bit. If you click on an image it will give you the colour at the click site. As I want to scan the whole picture I though I'd just do an X Y scan and put the sequential X and Y's in instead of the returned X and Y of the GetCursorPos call. But how to get left position and width (for example) in pixels to start the scan? What would I put in my for next loop to address each pixel ?
So to clarify my question. How to change the code below to scan every pixel of the image not just the clicked cursor position. Thanks
#If VBA7 Then
Private Declare PtrSafe Function GetPixel Lib "gdi32" (ByVal hdc As LongPtr, ByVal x As Long, ByVal y As Long) As Long
Private Declare PtrSafe Function GetCursorPos Lib "user32" (ByRef lpPoint As POINT) As LongPtr
Private Declare PtrSafe Function GetWindowDC Lib "user32" (ByVal hwnd As LongPtr) As LongPtr
#Else
Private Declare Function GetPixel Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long) As Long
Private Declare Function GetCursorPos Lib "user32" (ByRef lpPoint As POINT) As Long
Private Declare Function GetWindowDC Lib "user32" (ByVal hwnd As Long) As Long
#End If
Private Type POINT
x As Long
y As Long
End Type
Sub Picture1_Click()
Dim pLocation As POINT
Dim lColour As Long
Dim lDC As Variant
lDC = GetWindowDC(0)
Call GetCursorPos(pLocation)
lColour = GetPixel(lDC, pLocation.x, pLocation.y)
Range("a1").Interior.Color = lColour
End Sub
Option Explicit
Private Declare Function GetDC Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function ReleaseDC Lib "user32" (ByVal hwnd As Long, ByVal hdc As Long) As Long
Private Declare Function GetDeviceCaps Lib "gdi32" (ByVal hdc As Long, ByVal nIndex As Long) As Long
Private Declare Function GetCurrentThreadId Lib "kernel32" () As Long
Private Declare Function GetPixel Lib "gdi32" (ByVal hdc As Long, ByVal X As Long, ByVal Y As Long) As Long
Private Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
Private Type POINTAPI
X As Long
Y As Long
End Type
Dim IDC As Long
Private Function ScreenDPI(bVert As Boolean) As Long
'*** Get screen DPI ***
Static lDPI&(1), lDC&
If lDPI(0) = 0 Then
lDC = GetDC(0)
lDPI(0) = GetDeviceCaps(lDC, 88&) 'horz
lDPI(1) = GetDeviceCaps(lDC, 90&) 'vert
lDC = ReleaseDC(0, lDC)
End If
ScreenDPI = lDPI(Abs(bVert))
End Function
Private Function PTtoPX(Points As Single, bVert As Boolean) As Long
'*** Swap Points to pixels ****
PTtoPX = Points * ScreenDPI(bVert) / 72
End Function
Sub GetImageRect(ByRef RC As RECT)
Dim RNG As Range
Set RNG = Sheet1.Range("A1")
'**** using the spread sheet cell A1 as a reference ***
'** find the details of th eimage and convert to pixels ***
Dim wnd As Window
Set wnd = RNG.Parent.Parent.Windows(1)
With Sheet1.Image1
RC.Left = PTtoPX(.Left * wnd.Zoom / 100, 0) + wnd.PointsToScreenPixelsX(0)
RC.Top = PTtoPX(.Top * wnd.Zoom / 100, 1) + wnd.PointsToScreenPixelsY(0)
RC.Right = PTtoPX(.Width * wnd.Zoom / 100, 0) + RC.Left
RC.Bottom = PTtoPX(.Height * wnd.Zoom / 100, 1) + RC.Top
End With
End Sub
Sub XYScanOfImage()
'*** put an active X image on sheet1 call it image1 and run this routine **
'** to get the colour information for each pixel *****
Dim RC As RECT
Dim ScanX As Single
Dim ScanY As Single
Dim ImX As Single
Dim ImY As Single
Dim PixCol As Single
Call GetImageRect(RC)
ImX = RC.Left
ImY = RC.Top
IDC = GetDC(0)
'*** scan image left to right top to bottom ****
For ScanX = RC.Left To RC.Right
For ScanY = RC.Top To RC.Bottom
PixCol = GetPixel(IDC, ScanX, ScanY)
'**** PUT CODE IN HERE TO PROCESS THE PIXEL COLOUR ****
Next
Next
IDC = ReleaseDC(0, IDC)
End Sub
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With