GetPixel [Résolu]

kimwu 40 Messages postés dimanche 23 novembre 2003Date d'inscription 25 juin 2011 Dernière intervention - 14 nov. 2006 à 06:40 - Dernière réponse : kimwu 40 Messages postés dimanche 23 novembre 2003Date d'inscription 25 juin 2011 Dernière intervention
- 16 nov. 2006 à 06:31
Bonjour,

1/ Je cherche à évaluer la couleur d'un pixel de l'écran (de la même manière que les "pipettes" d'un programme de dessin)

Savez-vous quelle est la meilleure manière d'y arriver ?

Je ne sais pas si l'api getpixel du gdi32 permet cela sur l'écran.
En .net, la fonctiongetpixel ne fonctionne que sur une image.

2/ J'ai tout de même essayé l'api, et je l'ai fais sur un image pour être sûr.
Surprise, en l'utilisant je recois l'erreur suivante :

"A call to PInvoke function 'essai get pixel!WindowsApplication1.Form1::GetPixel' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature."

J'utilise le strict minimum ! , voici le code :



Public



Declare



Function
GetPixel

Lib



"gdi32"
(

ByVal
hDC

As



Long
,

ByVal
x

As



Long
,

ByVal
y

As



Long
)

As



Long



PrivateSub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) HandlesMyBase.Load




      Dim




l1
As


Long

= 10



      Dim



l2
As


Long

= 10








      Dim




lcouleur
As


Long

= GetPixel(PictureBox1.Handle, l1, l2)
      Console.WriteLine(lcouleur.ToString)

End

Sub

Quelqu'un aurait une idée ?

1/ Comment trouver la couleur d'un pixel de l'écran (et non d'une image)
2/ juste par curiausitée, quelle est cette erreur de l'api je suis perplexe.

Merci d'avance !
Afficher la suite 

Votre réponse

7 réponses

Meilleure réponse
kimwu 40 Messages postés dimanche 23 novembre 2003Date d'inscription 25 juin 2011 Dernière intervention - 16 nov. 2006 à 06:31
3
Merci
Alors voici le code que j'ai choisi. Avec les Api il est plus rapide que le code .net
C'est le code que j'avais trouvé, mais amélioré grace à votre aide :)


<DllImport("user32.dll")> Private Shared Function GetDC(ByVal hdc As IntPtr) As IntPtr
End Function

<DllImport("gdi32.dll")> Private Shared Function GetPixel(ByVal hdc As IntPtr, ByVal x As Integer, ByVal y As Integer) As Integer
End Function

<DllImport("user32.dll")> Private Shared Function ReleaseDC(ByVal hWnd As IntPtr, ByVal hDC As IntPtr) As Boolean
End Function

Private Function GetPixelColor(ByVal x As Integer, ByVal y As Integer) As Color
Dim hdcScreen As IntPtr = GetDC(ListView1.Handle)
Dim colorRef As Integer = GetPixel(hdcScreen, x, y)
ReleaseDC(ListView1.Handle, hdcScreen)
Return Color.FromArgb(colorRef And &HFF, (colorRef And &HFF00) >> 8, (colorRef And &HFF0000) >> 16)
End Function

En tout cas, merci beaucoup.
Peut-être que cela pourra servir à quelqu'un d'autre, car ce code final fonctionne vraiment bien :)

Merci kimwu 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 93 internautes ce mois-ci

Commenter la réponse de kimwu
kimwu 40 Messages postés dimanche 23 novembre 2003Date d'inscription 25 juin 2011 Dernière intervention - 14 nov. 2006 à 06:44
0
Merci
Désolé je ne sais pas pourquoi il y a eu des retour à la ligne. Alors voilà :

Public Declare Function GetPixel Lib "gdi32" (ByVal hDC As Long, ByVal x As Long, ByVal y As Long) As Long
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

Dim l1 As Long = 10.0
Dim l2 As Long = 10.0

Dim lcouleur As Long = GetPixel(PictureBox1.Handle, l1, l2)
Console.WriteLine(lcouleur.ToString)

End Sub
Commenter la réponse de kimwu
Renfield 17308 Messages postés mercredi 2 janvier 2002Date d'inscription 22 août 2018 Dernière intervention - 14 nov. 2006 à 08:24
0
Merci
Changes tes Long en des Int32

pas sur, de plus que ton
PictureBox1.Handle renvoies bien un hDC

Renfield
Admin CodeS-SourceS- MVP Visual Basic
Commenter la réponse de Renfield
Charles Racaud 3181 Messages postés dimanche 15 février 2004Date d'inscription 9 avril 2017 Dernière intervention - 14 nov. 2006 à 14:30
0
Merci
Salut,

PictureBox1.Handle retourne l'hWnd du controle.

Avec le Framework :
http://www.codyx.org/snippet_capturer-couleur-pixel-controle-windows-form_11.aspx




__________________

Kenji
Commenter la réponse de Charles Racaud
kimwu 40 Messages postés dimanche 23 novembre 2003Date d'inscription 25 juin 2011 Dernière intervention - 15 nov. 2006 à 02:48
0
Merci
Charles Racaud > Merci pour le lien
J'avais déjà fait cette solution de moi-même mais l'avait abandonnée.. je croie que c'était un peu trop long pour ce que je veux faire.
Mais dans le doute je vais réessayer, je pense que je l'avais p-être mal codé..

Renfield > J'avais essayé en integer cela ne change rien. P-être à cause du hWnd au lieu du hDC ?
Je vais voir s'il n'y a pas une convertion.. :)


Enfin, je voulais vous montrer un autre essai :

(il faut mettre en ref interop.services)

<DllImport("gdi32.dll")> Private Shared Function CreateDC(ByVal lpszDriver As String, ByVal lpszDevice As String, ByVal lpszOutput As String, ByVal lpInitData As IntPtr) As IntPtr
End Function

<DllImport("gdi32.dll")> Private Shared Function DeleteDC(ByVal hdc As IntPtr) As Boolean
End Function

<DllImport("gdi32.dll")> Private Shared Function GetPixel(ByVal hdc As IntPtr, ByVal nXPos As Integer, ByVal nYPos As Integer) As Integer
End Function


Private Function GetPixelColor(ByVal x As Integer, ByVal y As Integer) As Color
Dim hdcScreen As IntPtr = CreateDC("Display", Nothing, Nothing, IntPtr.Zero)
Dim colorRef As Integer = GetPixel(hdcScreen, x, y)
DeleteDC(hdcScreen)
Return Color.FromArgb(colorRef And &HFF, (colorRef And &HFF00) >> 8, (colorRef And &HFF0000) >> 16)
End Function



Cela fonctionne, mais là j'ai l'écran en entier.

Alors voici ce que j'ai fais pour un seul controle :

<DllImport("user32.dll")> Private Shared Function GetDC(ByVal hdc As IntPtr) As IntPtr
End Function

<DllImport("gdi32.dll")> Private Shared Function DeleteDC(ByVal hdc As IntPtr) As Boolean
End Function

<DllImport("gdi32.dll")> Private Shared Function GetPixel(ByVal hdc As IntPtr, ByVal nXPos As Integer, ByVal nYPos As Integer) As Integer
End Function

Private Function GetPixelColor(ByVal x As Integer, ByVal y As Integer) As Color
Dim hdcScreen As IntPtr = GetDC(ListView1.Handle)
Dim colorRef As Integer = GetPixel(hdcScreen, x, y)
DeleteDC(hdcScreen)
Return Color.FromArgb(colorRef And &HFF, (colorRef And &HFF00) >> 8, (colorRef And &HFF0000) >> 16)
End Function



Cela fonctionne bien aussi. J'ai essayé sur un listview en détail avec une couleur différente par item. Pour chaque lignes en prenant les bounds, cette fonction renvoyait la bonne couleur en Rgb.


Vous pensez quoi de ce code ?
La première version je l'ai trouvée sur un forum msdn. C'est une personne de la team microsoft qui donait cet exemple.

Mais je sais pas si ce que j'ai fais (avec le GetDC) est correct. Je ne connais pas encore beaucoup dans les Device Contexte ..
Commenter la réponse de kimwu
Renfield 17308 Messages postés mercredi 2 janvier 2002Date d'inscription 22 août 2018 Dernière intervention - 15 nov. 2006 à 08:09
0
Merci
GetDC doit être balancé par un ReleaseDC... (et non pas DeleteDC)

le "pas sur, de plus que ton
PictureBox1.Handle renvoies bien un hDC
"

était ironique ^^ il faut bien évidemment utiliser un hDC...
les deux (hWnd et hDC) n'indexent pas la même chose du tout...

Renfield
Admin CodeS-SourceS- MVP Visual Basic
Commenter la réponse de Renfield
kimwu 40 Messages postés dimanche 23 novembre 2003Date d'inscription 25 juin 2011 Dernière intervention - 16 nov. 2006 à 04:43
0
Merci
Ooops oui je vais mettre un releaseDC à la place ^^
Commenter la réponse de kimwu

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.