Handler for image object in GetPixel() API - function?

Dendro

Active Member
Joined
Jul 3, 2014
Messages
336
Hi,

I have searched but got stuck on correctly declaring and using the API function getpixel() in vba, hence i making a thread on this subject. I'm aware relevant post exist, but i failed to implement their solution.

What I would like to do:
get the color of certain pixel of an image pasted in excel and assign it to a variable.

What I'm asking you:


1. What is the correct way of declaring a function without it giving the error: "comments are only allowed after End Sub, End Function and End Property". I'm using the following line which i found in other threads:

Code:
Declare Function GetPixel Lib "gdi32" Alias GetPixel(ByVal hdc As Long, ByVal x As Long, ByVal y As Long) As Long

2. Could you comment on why all those parameters are there (why Byval, why do they create an Alias if it's the same name?)

3. hdc is the variable containing the handler for the image object. In the threads i found they use the following code to get the pixel at the pointer along with some other API, but I don't think I would need this one:

Code:
Private Declare Function GetWindowDC Lib "user32" (ByVal hwnd As Long) As Long

What image handler should i use (and why)?


(4. GetPixel returns 3 values as RGB, how would I be able to calculate with this, do i need to make 3 variables?)

It's quite technical, but i hope someone could help me with this. Thank you for your effort!

Dendro
 
Are you using the code in post#4 ? Reason I ask is because the code creates a bitmap of the shape in memory and gets the pixels from there regardless of where the shape\image is located on the screen(s).
 
Upvote 0

Excel Facts

Spell Check in Excel
Press F7 to start spell check in Excel. Be careful, by default, Excel does not check Capitalized Werds (whoops)
Are you using the code in post#4 ? Reason I ask is because the code creates a bitmap of the shape in memory and gets the pixels from there regardless of where the shape\image is located on the screen(s).
Yes, I am using that code.
I've tried to input a few XY coordinates into the test sub using guesswork, but pretty much any values I input outputs the 16777215 colour value (i.e. white).
I think the issue is as follows: when I use the POINTAPI to get a pixel coordinates, it gives me this relative to the top-left pixel of my entire screen. However the test sub code only considers pixels from the top-left pixel of the shape (wherever the shape is on the screen). So if I have pixel coordinates of (for example) 764, 243, this will have a different meaning for the code which will count 764 pixels from the top-left of the shape and not the screen - so its likely it could be outside of the shape range, or if inside then a different pixel to what I had intended.
I hope I'm making sense...I guess my question is how do I, in the first place, get XY coordinates of the shape rather than the screen?
 
Upvote 0
Just to add a better example to my previous post, if I'm looking to get the colour of pixel 400,400 relative to the shape, but the shape itself is positioned at 100,100 relative to the screen, then when I use the below code to get the pixel's coordinates it will give me 500,500 (as it outputs the XY coordinates relative to the screen). So when I feed this into the test sub, it outputs the colour of a different pixel relative to the shape (500,500) than what I had in mind (400,400).
VBA Code:
Dim Pnt As POINTAPI
GetCursorPos Pnt
Xcoordinate = Pnt.X
Ycoordinate = Pnt.Y
 
Upvote 0
That's because you are passing the screen coordinates returned by the GetCursorPos API.

If you are looking to get the colour of pixel 400,400 relative to the shape then the code should be something along these lines :
VBA Code:
Sub Test()

    Dim lPixelColor As Long
    Dim tPt As POINTAPI
    Dim tPicSize As Size
    Dim shp As Shape
   
    Set shp = Sheets("Sheet1").Shapes.AddPicture(ImageURL, msoFalse, msoTrue, clLeft, clTop, 343, 343)

    tPt.x = 400
    tPt.y = 400

    lPixelColor = GetPixelColorFromExcelShape(shp, tPt, tPicSize)

    Select Case True
        Case tPicSize.Width = 0
            MsgBox "Unable to create picture"
        Case lPixelColor = -1
            MsgBox "Vriables outside range" & vbCr & 0 & "<= X <=" & tPicSize.Width & vbCr & 0 & "<= Y <=" & tPicSize.Height
        Case Else
            MsgBox "The color at Point : " & tPt.x & " - " & tPt.y & "  is : " & vbCr & vbCr & lPixelColor
    End Select
   
End Sub
 
Upvote 0
That's because you are passing the screen coordinates returned by the GetCursorPos API.

If you are looking to get the colour of pixel 400,400 relative to the shape then the code should be something along these lines :
VBA Code:
Sub Test()

    Dim lPixelColor As Long
    Dim tPt As POINTAPI
    Dim tPicSize As Size
    Dim shp As Shape
  
    Set shp = Sheets("Sheet1").Shapes.AddPicture(ImageURL, msoFalse, msoTrue, clLeft, clTop, 343, 343)

    tPt.x = 400
    tPt.y = 400

    lPixelColor = GetPixelColorFromExcelShape(shp, tPt, tPicSize)

    Select Case True
        Case tPicSize.Width = 0
            MsgBox "Unable to create picture"
        Case lPixelColor = -1
            MsgBox "Vriables outside range" & vbCr & 0 & "<= X <=" & tPicSize.Width & vbCr & 0 & "<= Y <=" & tPicSize.Height
        Case Else
            MsgBox "The color at Point : " & tPt.x & " - " & tPt.y & "  is : " & vbCr & vbCr & lPixelColor
    End Select
  
End Sub
Thanks @Jaafar Tribak. I don't think I was clear enough in my last message, so apologies for that.
What I meant is how do I get the pixel coordinates of a point on the shape/image, to then be able to feed that into this code to output the colour of that pixel?
The 400,400 example was just a number plucked from thin air. Until now I've used the GetCursorPos API to choose a pixel on the screen that I then wish to get the colour of. However as screen pixels use a different XY axis (being the edges of the screen) to points on a shape (the axis being the edge of the shape), I am not sure how to get the right XY coordinates to input into the sub routine.
I hope that's clearer...
 
Upvote 0
Back in post#8 you mentioned that the user creates a boundary and then I loop through the screen pixels to see whether or not they fall within this boundary - How does the user create that boundary ?
 
Upvote 0
Back in post#8 you mentioned that the user creates a boundary and then I loop through the screen pixels to see whether or not they fall within this boundary - How does the user create that boundary ?
Using the following function:
VBA Code:
Dim Pnt As POINTAPI
GetCursorPos Pnt
X = Pnt.x
Y = Pnt.y
Here's a real example (I wish I could add a workbook to this post as an attachment!)...I've got an image aligned to cell H2, and the top third of the image is blue sky. Using the above function to select a blue pixel in the top left of the image gives me Pnt.X of 389 and Pnt.Y of 252. If I input this into the test routine, I get a colour of Decimal(2893870) - which is a very dark grey, and most definitely not part of the sky.
 
Last edited:
Upvote 0
Using the following function:
VBA Code:
Dim Pnt As POINTAPI
GetCursorPos Pnt
X = Pnt.x
Y = Pnt.y
I've

So, from that, can I conclude that the user is pointing with the cursor over an area of the shape before running the rest of the code ?
 
Upvote 0
Sorry but i am just trying to visualize how the user is actually getting the X and Y coordinates using the GetCursorPos API.
Is that inside a loop or a timer routine ?
 
Upvote 0

Forum statistics

Threads
1,223,275
Messages
6,171,122
Members
452,381
Latest member
Nova88

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top