Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum. Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

[WIN32]RÉCUPÉRER LA COULEUR D'UN PIXEL À L'ÉCRAN


Information sur la source

Catégorie :Graphique Classé sous : pixel, écran, couleur Niveau : Débutant Date de création : 13/11/2007 Date de mise à jour : 21/11/2007 13:00:54 Vu / téléchargé: 5 211 / 200

Note :
Aucune note

Commentaire sur cette source (11)
Ajouter un commentaire et/ou une note

Description

Cliquez pour voir la capture en taille normale
Ce source récupère la couleur du pixel qui se trouve sous la souris.

La couleur est affiché en décimal R, G, B et en hexa.

Le fond de la form prend la même couleur que celle du pixel.

Pour ceux qui voudraient juste utiliser ce programme sans avoir besoin de compiler, il suffit de renommer le fichier du zip .exec en .exe.
 

Source

  • #include "windows.h"
  • HINSTANCE _hThisInstance; // Handle du module
  • HWND _hWnd; // Handle de la fenêtre
  • HWND _hTextBox; // Handle de la textbox
  • LPSTR _lpAppName = "GetPixelColor"; // Nom de l'appli
  • //
  • // Affiche le message d'erreur associé à la dernière
  • // erreur Win32 et ferme l'appli.
  • //
  • void ShowLastError()
  • {
  • DWORD nLastError;
  • LPSTR lpMessageBuffer;
  • // Récupération du numéro de l'erreur
  • nLastError = GetLastError();
  • // Formatage du message
  • FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, nLastError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMessageBuffer, 0, NULL);
  • // Affichage du message et fin de l'appli
  • MessageBox(NULL, lpMessageBuffer, "ERROR", MB_OK | MB_ICONERROR);
  • //ExitProcess(nLastError);
  • }
  • //
  • // Traitement des messages.
  • //
  • LRESULT CALLBACK WindowProcedure(HWND hWnd, UINT nMessage, WPARAM wParam, LPARAM lParam)
  • {
  • static HBRUSH hBackBrush; // Brush de dessin de l'arrière plan de la fenêtre
  • static POINT cursor; // Position de la souris
  • static COLORREF nColor; // Couleur du pixel sous la souris
  • static RECT back; // Rectangle de la zone cliente/fenêtre
  • static char lpText[50]; // Affichage de la couleur en hexa et rgb
  • static INT32 nHexa; // La couleur swapée pour afficher un hexa comme on l'attend
  • static HDC hScreenDC; // HDC de l'écran
  • switch (nMessage)
  • {
  • case WM_TIMER:
  • // On met à jour seulement si on est hors de notre fenêtre
  • GetCursorPos(&cursor);
  • GetWindowRect(_hWnd, &back);
  • // Pas besoin de ReleasDC pour ce GetDC : CS_OWNDC dans le style de la classe
  • if (! PtInRect(&back, cursor)) SendMessage(_hWnd, WM_ERASEBKGND, (WPARAM)GetDC(_hWnd), 0);
  • break;
  • case WM_ERASEBKGND:
  • // Récupération des coordonnées de la souris
  • GetCursorPos(&cursor);
  • // Récupération de la couleure du pixel sous la souris
  • hScreenDC = GetDC(0);
  • nColor = GetPixel(hScreenDC, cursor.x, cursor.y);
  • nHexa = ReleaseDC(0, hScreenDC);
  • // Création du brush de dessin de l'arrière plan de la form
  • hBackBrush = CreateSolidBrush(nColor);
  • // Dessin de la fenêtre
  • GetClientRect(_hWnd, &back);
  • FillRect((HDC)wParam, &back, hBackBrush);
  • DeleteObject(hBackBrush);
  • // On remet les octets dans le "bon" sens
  • nHexa = ((nColor & 0xFF) << 16) | (nColor & 0xFF00) | ((nColor & 0xFF0000) >> 16);
  • // Affichage de la couleur en hexa
  • // Le dièze, c'est juste qu'en HTML on en met un.
  • // %X, ça convertit l'entier en hexa (En majuscule)
  • // %6X, ça complète la conversion avec des espaces pour que la chaîne fasse 6 caractères
  • // %06X, ça demande des 0 à la place des espaces pour arriver à 6 caractères
  • wsprintf(lpText, "#%06X (R = %d, G = %d, B = %d)", nHexa, nColor & 0xFF, (nColor & 0xFF00) >> 8, (nColor & 0xFF0000) >> 16);
  • SetWindowText(_hTextBox, lpText);
  • RedrawWindow(_hTextBox, NULL, NULL, RDW_INVALIDATE);
  • return 1;
  • case WM_DESTROY:
  • // On signale que le thread va s'arrêter
  • PostQuitMessage(0);
  • break;
  • default:
  • // Application du traitement par défaut
  • return DefWindowProc(hWnd, nMessage, wParam, lParam);
  • }
  • return 0;
  • }
  • //
  • // Initialise la fenêtre principale de l'appli.
  • //
  • void InitWindow()
  • {
  • WNDCLASSEX wincl; // Classe de la fenêtre utilisée
  • // Création de la classe de fenêtre
  • wincl.cbSize = sizeof(WNDCLASSEX);
  • wincl.style = CS_OWNDC;
  • wincl.lpfnWndProc = WindowProcedure;
  • wincl.cbClsExtra = 0;
  • wincl.cbWndExtra = 0;
  • wincl.hInstance = _hThisInstance;
  • wincl.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  • wincl.hCursor = LoadCursor(NULL, IDC_ARROW);
  • wincl.hbrBackground = NULL;
  • wincl.lpszMenuName = 0;
  • wincl.lpszClassName = _lpAppName;
  • wincl.hIconSm = NULL;
  • // Enregistrement de la classe
  • if (!RegisterClassEx(&wincl)) ShowLastError();
  • // Création de la fenêtre
  • _hWnd = CreateWindowEx(0, _lpAppName, _lpAppName, WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, 300, 100, HWND_DESKTOP, NULL, _hThisInstance, NULL);
  • _hTextBox = CreateWindowEx(0, "EDIT", "color", ES_READONLY | WS_VISIBLE | WS_CHILD | WS_BORDER, 0, 0, 294, 20, _hWnd, NULL, _hThisInstance, NULL);
  • }
  • #pragma comment(linker, "/entry:main")
  • INT32 _cdecl main()
  • {
  • MSG messages; // Réception des messages envoyés à l'application
  • // Récupération du handle du module
  • _hThisInstance = GetModuleHandle(NULL);
  • InitWindow();
  • if (!SetTimer(_hWnd, 1, 100, NULL)) ShowLastError();
  • // Boucle de traitement des messages
  • while (GetMessage(&messages, NULL, 0, 0))
  • {
  • // Traduit certains messages
  • TranslateMessage(&messages);
  • // Distribution des messages aux fenêtres
  • DispatchMessage(&messages);
  • }
  • KillTimer(_hWnd, 1);
  • // Code d'erreur en sortie
  • return messages.wParam;
  • }
#include "windows.h"

HINSTANCE _hThisInstance;              // Handle du module
HWND _hWnd;                            // Handle de la fenêtre
HWND _hTextBox;                        // Handle de la textbox
LPSTR _lpAppName = "GetPixelColor";    // Nom de l'appli

//
// Affiche le message d'erreur associé à la dernière
// erreur Win32 et ferme l'appli.
//
void ShowLastError()
{
  DWORD nLastError;
  LPSTR lpMessageBuffer;

  // Récupération du numéro de l'erreur
  nLastError = GetLastError();

  // Formatage du message
  FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, nLastError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMessageBuffer, 0, NULL);

  // Affichage du message et fin de l'appli
  MessageBox(NULL, lpMessageBuffer, "ERROR", MB_OK | MB_ICONERROR);
  //ExitProcess(nLastError);
}

//
// Traitement des messages.
//
LRESULT CALLBACK WindowProcedure(HWND hWnd, UINT nMessage, WPARAM wParam, LPARAM lParam)
{
  static HBRUSH hBackBrush;     // Brush de dessin de l'arrière plan de la fenêtre
  static POINT cursor;          // Position de la souris
  static COLORREF nColor;       // Couleur du pixel sous la souris
  static RECT back;             // Rectangle de la zone cliente/fenêtre
  static char lpText[50];       // Affichage de la couleur en hexa et rgb
  static INT32 nHexa;           // La couleur swapée pour afficher un hexa comme on l'attend
  static HDC hScreenDC;         // HDC de l'écran
  
  switch (nMessage)
  {
    case WM_TIMER:
      // On met à jour seulement si on est hors de notre fenêtre
      GetCursorPos(&cursor);
      GetWindowRect(_hWnd, &back);
      
      // Pas besoin de ReleasDC pour ce GetDC : CS_OWNDC dans le style de la classe
      if (! PtInRect(&back, cursor)) SendMessage(_hWnd, WM_ERASEBKGND, (WPARAM)GetDC(_hWnd), 0);
      break;
    case WM_ERASEBKGND:
      // Récupération des coordonnées de la souris
      GetCursorPos(&cursor);
      
      // Récupération de la couleure du pixel sous la souris
      hScreenDC = GetDC(0);
      nColor = GetPixel(hScreenDC, cursor.x, cursor.y);
      nHexa = ReleaseDC(0, hScreenDC);

      // Création du brush de dessin de l'arrière plan de la form
      hBackBrush = CreateSolidBrush(nColor);
      
      // Dessin de la fenêtre
      GetClientRect(_hWnd, &back);
      FillRect((HDC)wParam, &back, hBackBrush);
      DeleteObject(hBackBrush);

      // On remet les octets dans le "bon" sens
      nHexa = ((nColor & 0xFF) << 16) | (nColor & 0xFF00) | ((nColor & 0xFF0000) >> 16);
      
      // Affichage de la couleur en hexa
      // Le dièze, c'est juste qu'en HTML on en met un.
      // %X, ça convertit l'entier en hexa (En majuscule)
      // %6X, ça complète la conversion avec des espaces pour que la chaîne fasse 6 caractères
      // %06X, ça demande des 0 à la place des espaces pour arriver à 6 caractères
      wsprintf(lpText, "#%06X (R = %d, G = %d, B = %d)", nHexa, nColor & 0xFF, (nColor & 0xFF00) >> 8, (nColor & 0xFF0000) >> 16);
      SetWindowText(_hTextBox, lpText);
      RedrawWindow(_hTextBox, NULL, NULL, RDW_INVALIDATE);
      return 1;
    case WM_DESTROY:
      // On signale que le thread va s'arrêter
      PostQuitMessage(0);
      break;
    default:
      // Application du traitement par défaut
      return DefWindowProc(hWnd, nMessage, wParam, lParam);
  }
  return 0;
}

//
// Initialise la fenêtre principale de l'appli.
//
void InitWindow()
{
  WNDCLASSEX wincl;       // Classe de la fenêtre utilisée

  // Création de la classe de fenêtre
  wincl.cbSize = sizeof(WNDCLASSEX);
  wincl.style = CS_OWNDC;
  wincl.lpfnWndProc = WindowProcedure;
  wincl.cbClsExtra = 0;
  wincl.cbWndExtra = 0;
  wincl.hInstance = _hThisInstance;
  wincl.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  wincl.hCursor = LoadCursor(NULL, IDC_ARROW);
  wincl.hbrBackground = NULL;
  wincl.lpszMenuName = 0;
  wincl.lpszClassName = _lpAppName;
  wincl.hIconSm = NULL;

  // Enregistrement de la classe
  if (!RegisterClassEx(&wincl)) ShowLastError();

  // Création de la fenêtre
  _hWnd = CreateWindowEx(0, _lpAppName, _lpAppName, WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, 300, 100, HWND_DESKTOP, NULL, _hThisInstance, NULL);
  _hTextBox = CreateWindowEx(0, "EDIT", "color", ES_READONLY | WS_VISIBLE | WS_CHILD | WS_BORDER, 0, 0, 294, 20, _hWnd, NULL, _hThisInstance, NULL);
}

#pragma comment(linker, "/entry:main")
INT32 _cdecl main()
{
  MSG messages;           // Réception des messages envoyés à l'application

  // Récupération du handle du module
  _hThisInstance = GetModuleHandle(NULL);

  InitWindow();
  if (!SetTimer(_hWnd, 1, 100, NULL)) ShowLastError();

  // Boucle de traitement des messages
  while (GetMessage(&messages, NULL, 0, 0))
  {
    // Traduit certains messages
    TranslateMessage(&messages);

    // Distribution des messages aux fenêtres
    DispatchMessage(&messages);
  }
  KillTimer(_hWnd, 1);

  // Code d'erreur en sortie
  return messages.wParam;
}

Fichier Zip

Pour les "Membres Club", vous pouvez télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip

Historique

15 novembre 2007 10:01:36 :
Modifes suggérées par les premiers posts.
15 novembre 2007 10:05:12 :
Bout de code en trop.
21 novembre 2007 10:02:30 :
Confusion entre le style de classe et le style de fenêtre.
21 novembre 2007 10:05:58 :
Argh !
21 novembre 2007 13:00:54 :
La dernière MAJ... avant la suivante.

Commentaires et avis

signaler à un administrateur
Commentaire de mogwai93 le 13/11/2007 19:01:00

pourquoi créer une deuxieme variable "_hWnd" ?
alors que _hWnd est égale à hWnd

et pour information, DevCpp (mingW) n'est pas "content" des 2 variables :
HANDLE hDC;
HANDLE _hThisInstance;

il préfère :
HDC hDC;
HINSTANCE _ThisInstance;


signaler à un administrateur
Commentaire de BruNews le 13/11/2007 19:17:16 administrateur CS

Jolie source.

Le bloc 'bon ordre' est aussi inutile que zoli, il faut dans tous les cas 2 shifts ensuite.
Me semble qu'il faut ReleaseDC pour GetDC(0).

signaler à un administrateur
Commentaire de SAKingdom le 13/11/2007 21:29:39

De l'assembler en plein milieu d'une fonction... ça n'empêcherait pas son optimisation ça ?

(C'est toi, brunews, qui m'avais fais la remarque je crois)

signaler à un administrateur
Commentaire de BruNews le 13/11/2007 21:45:16 administrateur CS

ça c'est tout à fait certain.

signaler à un administrateur
Commentaire de racpp le 14/11/2007 00:55:17 administrateur CS

Salut,
L'idée de source est bonne mais il parait que tu n'as pas pris le temps de la finaliser. En plus de ce qui a été dit voici quelques remarques:
1- Le message WM_ERASEBKGND fournit le HDC de la fenêtre dans wParam donc aucun besoin d'utiliser GetDC(). Cette fonction est même appelée inutilement trois fois de suite dans ton code.
2- La fonction OnCreate() est vide.
3- Il est préférable de déclarer les variables locales de WindowProcedure en static. Cela évitera l'usage de la pile à chaque appel de la procédure.

signaler à un administrateur
Commentaire de rt15 le 14/11/2007 11:11:44

Merci pour ces remarques !

MOGWAI93 -> _hWnd est utilisée un peu de partout (Dans le SetTimer).
OK pour les types pas assez rigoureux.

BruNews -> Bon bon, je vire le bloc. Pour le ReleaseDC, ça dépend si le DC est common, class ou private... Je vais fouiller un peu la question.

RACPP -> 1, 2 OK. Pour le 3, j'ai un peu plus de mal. Cette fonction peut plus ou moins s'appeler récursivement (Avec le SendMessage par exemple...) Donc si c'est statique, il peut y avoir des effets de bords pas cools.

signaler à un administrateur
Commentaire de rt15 le 15/11/2007 10:03:51

Bah je suis pas arriver à savoir s'il fallait un ReleaseDC. Je voulais faire un truc dans ce genre là :

GetWindowLong(?, GWL_STYLE) & CS_OWNDC

Mais je vois pas quoi mettre comme Handle de fenêtre (0 marche pas, et je sais pas si GetDesktopWindow est le bon) :

Donc autant en utiliser un dans le doute : la doc à l'air de dire que faire un ReleaseDC sur un DC privé ne pause pas de problème.

En plus, le ReleaseDC renvoie 1, indiquant que la fonction s'est bien passée.

signaler à un administrateur
Commentaire de BruNews le 15/11/2007 10:18:38 administrateur CS

Il le faut, ça libère au moins une place dans la table des handle.

signaler à un administrateur
Commentaire de racpp le 20/11/2007 01:37:56 administrateur CS

ATTENTION:
Le style CS_OWNDC ne doit pas être utilisé avec CreateWindow(). Il doit être plutôt affecté au membre style de la classe WNDCLASS ou WNDCLASSEX. Il s'agit d'un style de classe de fenêtre et non pas un style de fenêtre.

Une variable locale déclarée en static est allouée dans la mémoire globale de l'exécutable, donc accessible à tout moment. Une fonction CALLBACK appelée de manière répétitive doit limiter l'usage de la pile pour gagner un peu en vitesse. Dans ton code, cela ne poserait aucun problème.

signaler à un administrateur
Commentaire de racpp le 20/11/2007 13:15:47 administrateur CS

WNDCLASS et WNDCLASSEX sont des structures et non pas des classes comme j'ai dit plus haut sans faire attention.

signaler à un administrateur
Commentaire de rt15 le 21/11/2007 10:06:50

Hop, MAJ. Bah encore merci d'avoir vérifier : je vous donne du boulot dites-donc ! Pour la peine, j'ai mis les variables de la callback en static.

Ajouter un commentaire

Discussions en rapport avec ce code source dans le forum

Récupérer la couleur d'un pixel à la position x,y de l'écran [ par atao ] quelqu' un sait il comment peut on récupérer la couleur d'un pixel à la position x,y de l'écranmerciatao. couleur de pixel (DX) [ par JediMaster ] comment peut t'on récupérer la couleur d'un pixel et la changer sur une surface directdraw ?ca m'aiderait trop merci tableaux & collisions [ par JediMaster ] j'utilile directdraw avec la technique du blitting (les pixels d'une certaine couleur sont pas collé sur la surface et donc cela crée la tranparence)j connaitre la couleur d un pixel sous windows [ par vychnou ] Bonjour a tous!Mon probleme:j ai besoin de connaitre la couleur d un pixel particulier(par exemple celui pointé par la souris ou bien un pixel dont on SetPixel et GetPixel [ par Adeon ] Salut je n'arrive pas a me servir de SetPixel() et GetPixel() en API. Je sais que ca existe mais j'ai des erreurs tout le temps quand je m'en ser. QQ test_la couleur d un pixel .... ca existe sous c_allegro ??? [ par dcousseau ] qql connai t il une commande sous c_allegro qui permette de tester la couleur d'un pixel a l'écran?merci d'avancecouscous Couleur d'un Pixel [ par Me109 ] Bonjour je voudrais savoir comment peut on changer la couleur d'un pixelmerci Le mépris de ceux qui ne savent pas n'est pas une preuve de savoir Allegro: Connaitre les valeurs r,g,b d'un pixel [ par Kleidp ] Salut,voici mon problème:Je suis en mode truecolor 32 bit avec Allegro, et j'aimerais connaitre les valeurs r,g,b d'un pixel de mon image.J'ai essayé Couleurs avec X11 [ par toto000 ] Bonjour,je suis novice en programmation graphique sous X11 et j'aimerai savoir comment afficher un pixel coloré.Je sais qu'il existe une fonction putp Recuperer la couleur d un pixel [ par Ptlpn ] Bonjour,Jutilise la librairie Glut, te je voulais en fait recuperer la couleur d un pixel donn&#233;. En fait, je souhaite faire une palette de couleu


Nos sponsors

Sondage...

CalendriCode

Décembre 2008
LMMJVSD
1234567
891011121314
15161718192021
22232425262728
293031    

Consulter la suite du CalendriCode

Téléchargements

Logiciels à télécharger sur le même thème :



Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel BAÏSE, Merci à Vincent pour ses précieux conseils
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés
Temps d'éxécution de la page : 0,156 sec

Google Coop CodeS-SourceS Google Coop CodeS-SourceS


Certaines images présentes sur le site (notament certains avatars) sont issues des collections IconShock, donc si vous souhaitez utiliser ces icons vous devez les acheter, ne les copiez pas et ne utilisez pas dans vos sites et applications sans les avoir commandé.