IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Windows Discussion :

fonctionement de GetDIBits


Sujet :

Windows

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2008
    Messages
    308
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Février 2008
    Messages : 308
    Par défaut fonctionement de GetDIBits
    Salut à tous,

    Je suis à la recherche du moyen de lire la couleur des pixels de l'écran, simplement les lire, pas besoin de les modifier ni d'en faire une image.
    Après quelques recherches, j'ai d'abord trouvé la solution du getPixel(); facile a mettre en œuvre mais beaucoup trop lente!
    J'ai donc chercher une autre méthode, et j'ai trouvé GetDIBits();

    Et c'est la que je ne comprend plus rien... faut avouer que la syntaxe msdn n'est pas toujours très claire quand on est pas habitué (en plus l'exemple qu'ils donnent est fait pour capturer une image, pas pour la lire), j'aurais donc besoin d'un petit coup de pouce de quelqu'un ayant déjà utilisé GetDIBits.

    Pour lire connaitre le COLORREF ou code hexa (ou autre) d'un pixel, suis-je obligé de créer une nouvelle zone mémoire, ne peut on pas lire directement le contenu de l'écran sans le copier?
    comment récupérer les informations?
    comment lire ces informations?

  2. #2
    Expert confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 530
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 530
    Par défaut
    Le problème de GetPixel est justement qu'il cherche à ne lire et convertir qu'un pixel au format COLORREF.
    Il faut bien être conscient que la mémoire vidéo, même si elle peut être mappée en mémoire est sur un périphérique distant, la carte graphique.
    Le mapping en mémoire n'est qu'une astuce pour demander à la carte graphique de nous retourner les valeurs de SA mémoire.

    GetDIBits, lui ne cherche pas a lire une zone mémoire mais à faire un snapshot. Cela permet d'utiliser l'architecture de bus des PC (PCI ou autre) optimisé pour envoyer des FLOTS de données par rafale.
    La conversion en COLORREF sur un ensemble de pixel est très facilement parallélisable via MMX, SSE2 etc., c'est même l'une des tâche principale du GDI.

    Si vous voulez vraiment lire directement dans la mémoire vidéo, la vraie, il vous suffit de faire un driver en mode kernel, de dialoguer avec le contrôleur du bus PCI pour avoir le droit de monter le potentiel électrique sur les fils du bus et que la carte graphique les lisent. En triturant ces potentiels, vous pouvez envoyer des commandes à la carte vidéo (je suis pas sûr que tous les constructeurs publient leur jeu de commande ). De récupérer le résultat de la commande. S'il a une option DMA, on peut toujours le piloté pour avoir plusieurs données récupéré en mémoire sur une commande. Avec un peu de chance, le format de la valeur n'est pas assez abscond pour interdire une conversion en RGB de base.
    Tout ça pour ce faire poutrer en performance par un simple GetDIBits qui récupère en rafale toute une zone mémoire en utilisant les fonctionnalités optimisées du driver graphique du fabriquant de la carte et les routines de conversion du GDI.

    Donc GetDIBits est là solution, à moins de revoir toute l'architecture hardware et software d'un PC.

    Une fois maitrisés les concepts utilisés par GetDIBits, vous verrez que c'est en fait très naturelle pour une personne connaissant le fonctionnement d'une machine.

    La difficulté n'est pas dans GetDIBits, mais dans vos méconnaissances. Qu'est-ce que vous ne maîtriser pas dans GetDIBits?

  3. #3
    Membre éclairé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2008
    Messages
    308
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Février 2008
    Messages : 308
    Par défaut
    okay, ma méconnaissance c'est surtout que je n'ai jamais fait de prog windows (ou presque).

    Si vous voulez bien on vas partir de la syntaxe définie par la msdn pour que j'essaye de comprendre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    int GetDIBits(
      __in     HDC hdc,
      __in     HBITMAP hbmp,
      __in     UINT uStartScan,
      __in     UINT cScanLines,
      __out    LPVOID lpvBits,
      __inout  LPBITMAPINFO lpbi,
      __in     UINT uUsage
    );
    vous me corrigez si je me trompe

    les paramètres :

    - hdc, c'est le HDC(identifiant?) de la fenêtre/application qui fait la demande? comment l'obtenir?

    - hbmp, c'est un HBITMAP, pour l'avoir, je récupere le HDC de l'écran, puis j'utilise CreateCompatibleBitmap??
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    //largeur de l'écran
    int resolution_x = GetSystemMetrics(SM_CXSCREEN);
    //hauteur de l'écran
    int resolution_y = GetSystemMetrics(SM_CYSCREEN);
    //le HDC de l'ecran
    HDC hScreenDC = GetDC(NULL);
    //le HBITMAP de l'image de l'écran?
    HBITMAP hBitmap = CreateCompatibleBitmap(hScreenDC, resolution_x, resolution_y);
    - uStartScan et cScanLines, la ligne de début et le nombre de ligne, GetDIBits ne fonctionne qu'avec des lignes? donc pour un écran de 800 par 600, uStartScan=0 et cScanLines=600 ( pour tout l'écran ) ???

    - lpvBits, l'adresse a laquelle seront les informations, tous les pixels de l'écran??

    - lpbi, "A pointer to a BITMAPINFO structure that specifies the desired format for the DIB data" mouai, mais à quoi ça sert concretement? comment s'en servir?

    - uUsage, permet de spécifier le format voulu, je passe DIB_RGB_COLORS pour avoir le format RGB

    la valeur de retour, c'est le nombre de lignes copiées, donc 600 si tout marche bien avec uStartScan=0 et cScanLines=600.

    Voilà pour l'utilisation de la fonction, mais qu'en est il de l'utilisation du résultat? j'imagine qu'il faut se servir de lpbi??

  4. #4
    Membre éclairé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2008
    Messages
    308
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Février 2008
    Messages : 308
    Par défaut
    Bon, j'ai essayé 2 - 3 trucks, mais ça marche pas, voici le code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
        //largeur de l'écran
        int resolution_x = GetSystemMetrics(SM_CXSCREEN);
        //hauteur de l'écran
        int resolution_y = GetSystemMetrics(SM_CYSCREEN);
    
        //le HDC de l'ecran
        HDC hdcScreen = GetDC(NULL);
        //le HDC mémoire
        HDC hdcMemory = CreateCompatibleDC(hdcScreen);
        //le HBITMAP de l'image de l'écran
        HBITMAP hbmp = CreateCompatibleBitmap(hdcScreen, resolution_x, resolution_y);
    
        //la variable qui contient les informations
        LPVOID lpvBits;
        //la structure BITMAPINFO
        BITMAPINFO lpbi;
    
        //et...
        cout << GetDIBits(hdcMemory,hbmp,0,600,&lpvBits,&lpbi,DIB_RGB_COLORS) << endl;
    
        //on supprime le HBITMAP
        DeleteObject(hbmp);
        //on libere le HDC mémoire
        DeleteDC(hdcMemory);
        //on libere le HDC de l'ecran
        ReleaseDC(NULL, hdcScreen);
    GetDIBits renvoie 0, vous auriez une piste pour avancer?

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 8
    Dernier message: 12/02/2013, 01h08
  2. Fonction API
    Par margilb dans le forum C++Builder
    Réponses: 2
    Dernier message: 08/07/2002, 11h11
  3. Implémentation des fonctions mathématiques
    Par mat.M dans le forum Mathématiques
    Réponses: 9
    Dernier message: 17/06/2002, 16h19
  4. fonction printf
    Par ydeleage dans le forum C
    Réponses: 7
    Dernier message: 30/05/2002, 11h24
  5. FOnction api specifiant la position de la souris
    Par florent dans le forum C++Builder
    Réponses: 4
    Dernier message: 15/05/2002, 20h07

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo