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 :

Récupération des pixels d'une fenêtre cachée


Sujet :

Windows

  1. #1
    Nouveau Candidat au Club
    Inscrit en
    Novembre 2008
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 7
    Points : 1
    Points
    1
    Par défaut Récupération des pixels d'une fenêtre cachée
    Bonjour,

    Je vous expose mon problème :

    - J'utilise la fonction glReadPixels sur une fenêtre invisible. Cela me retourne bien les données...mais problème connu...cette fonction est bien trop lente.

    - J'essaie donc de récupérer les données de la fenêtre d'une manière plus rapide. J'ai besoin d'avoir la valeur RGBA de chaque pixel de la fenêtre pour faire des traitements dessus par la suite.

    - J'ai déjà tenté de créer une texture OPENGL et de récupérer les données comme cela mais les valeurs de hauteur et de largeur de ma texture doivent être des puissances de deux et je ne connais pas par avance la taille de ma fenêtre.

    - Je me suis donc tourné vers l'API windows et getDIBits. getDIBits n'est pas censé me retourner les valeurs de ALPHA mais un getDIBits + un glReadPixels de la valeur ALPHA reste plus rapide qu'un glReadPixels sur les données RGBA.
    J'ai donc tenté le code suivant que j'ai trouvé en fouillant la toile :

    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
    28
    29
    30
    31
    32
    33
    34
    35
    36
    	HDC hDCMem = CreateCompatibleDC(s->native.window.hDC);
    	HBITMAP hBmp = NULL;
    	HGDIOBJ hOld;
    	HDC hDC;
    	LRESULT res;
    
            RECT rect;
    	int temp,i,j;
    	unsigned long * temp_pix = pixels;
    		
    	BITMAPINFO bitmap_info;
    
           bitmap_info.bmiHeader.biSize	= sizeof(BITMAPINFOHEADER);
    	bitmap_info.bmiHeader.biWidth			= width;
    	bitmap_info.bmiHeader.biHeight			= -(signed)height;
    	bitmap_info.bmiHeader.biPlanes			= 1;
    	bitmap_info.bmiHeader.biBitCount		= 32;
    	bitmap_info.bmiHeader.biCompression		= BI_BITFIELDS;
    	bitmap_info.bmiHeader.biXPelsPerMeter	= 0;
    	bitmap_info.bmiHeader.biYPelsPerMeter	= 0;
    	bitmap_info.bmiHeader.biClrUsed			= 0;
    	bitmap_info.bmiHeader.biClrImportant	= 0;
           GetWindowRect(s->native.window.hWND, & rect);
    
            hBmp = CreateCompatibleBitmap(hDCMem,width,height);
            hOld = SelectObject(hDCMem, hBmp);
    		
    	GetDIBits(hDCMem,hBmp,0,height,NULL,&bitmap_info,DIB_RGB_COLORS);
    
        res = SendMessage(s->native.window.hWND, WM_PRINT, (WPARAM) hDCMem, PRF_CHILDREN | PRF_CLIENT);
    
    	res = GetDIBits(hDCMem,hBmp,0,height,pixels,&bitmap_info,DIB_RGB_COLORS);
    
        SelectObject(hDCMem, hOld);
        DeleteObject(hDCMem);
    Mais je n'obtiens aucune donnée...

    Quelqu'un aurait-il une petite idée de comment récupérer les données d'une fenêtre cachée?

    Merci par avance.

  2. #2
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    Ca n'a aucun sens étant donné qu'on ne récupère pas les pixels d'une fenêtre mais les pixels d'un DC (celui d'une fenêtre par exemple ...). Si la fenêtre est cachée (n'occupe aucune partie de l'écran), son DC est "vide" ...

  3. #3
    Expert éminent
    Avatar de smyley
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    6 270
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 6 270
    Points : 8 344
    Points
    8 344
    Par défaut
    Et en utilisant directement PrintWindow ça te donnes quoi ?

  4. #4
    Nouveau Candidat au Club
    Inscrit en
    Novembre 2008
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 7
    Points : 1
    Points
    1
    Par défaut
    PrintWindow ne fonctionne pas non plus...déjà essayé...merci quand même...

    Je cherche toujours...à récupérer les données de mon DC...

  5. #5
    Expert éminent
    Avatar de smyley
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    6 270
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 6 270
    Points : 8 344
    Points
    8 344

  6. #6
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Ça dépend si la fenêtre supporte WM_PRINT/WM_PRINTCLIENT ou non.
    Une fenêtre "de base" doit juste supporter WM_PRINTCLIENT, qui est appelé automatiquement par le traitement par défaut de WM_PRINT.
    Par contre, si la fenêtre dessine son propre cadre, cela doit devenir plus compliqué...

    Par ailleurs, certains contrôles de Windows (notamment les Tab Controls) supportent de recevoir un HDC dans le paramètre WPARAM de WM_PAINT, ce qui en fait un équivalent à WM_PRINTCLIENT.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  7. #7
    Nouveau Candidat au Club
    Inscrit en
    Novembre 2008
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 7
    Points : 1
    Points
    1
    Par défaut
    En fait j'ai déjà tenté d'utiliser PrintWindow mais mon compilateur n'en veut pas même en ayant inclu windows.h et linké avec user32.lib...

    Du coup, j'ai tenté avec SendMessage et l'argument WM_PRINT...le send message me renvoyait 1 (avec WM_PRINTCLIENT 0) mais toujours rien dans mon buffer de données...

  8. #8
    Nouveau Candidat au Club
    Inscrit en
    Novembre 2008
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 7
    Points : 1
    Points
    1
    Par défaut
    J'ai réussi à utiliser le PrintWindow avec un GetProcAddress sur user32.dll ... mais cela ne m'a pas permis d'avoir les bons pixels après le GetDIBits...

  9. #9
    Expert éminent
    Avatar de smyley
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    6 270
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 6 270
    Points : 8 344
    Points
    8 344
    Par défaut
    Citation Envoyé par youhoucmoa Voir le message
    mais cela ne m'a pas permis d'avoir les bons pixels après le GetDIBits
    tu obtiens quoi pour l'instant ?

  10. #10
    Nouveau Candidat au Club
    Inscrit en
    Novembre 2008
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 7
    Points : 1
    Points
    1
    Par défaut
    Des pixels noirs...donc rien...
    J'ai réussi aussi à avoir que des pixels gris...avec le PrintWindow...
    Et quand je demande la partie "non cliente" avec le "SendMessage" j'ai le bord de la fenêtre...mais pas de données correctes à l'intérieur de la fenêtre...

    J'ai quelque chose comme ça maintenant...

    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
    28
    29
    30
    31
    32
    33
    		
    handle = GetModuleHandle("user32.dll");
    if ( handle == 0 )
       handle = LoadLibrary("User32.dll");
    if (handle)
       pPrintWindow = (tPrintWindow)GetProcAddress(handle,"PrintWindow");
    
    
    lpBits = (BYTE*)malloc(s->width*s->height*4*sizeof(BYTE));
    bitmap_info.bmiHeader.biSize     = sizeof(BITMAPINFOHEADER);
    bitmap_info.bmiHeader.biWidth                   = s->width;
    bitmap_info.bmiHeader.biHeight                  = s->height;
    bitmap_info.bmiHeader.biPlanes                  = 1;
    bitmap_info.bmiHeader.biBitCount                = 32;
    bitmap_info.bmiHeader.biCompression             = BI_BITFIELDS;
    bitmap_info.bmiHeader.biXPelsPerMeter   = 0;
    bitmap_info.bmiHeader.biYPelsPerMeter   = 0;
    bitmap_info.bmiHeader.biClrUsed                 = 0;
    bitmap_info.bmiHeader.biClrImportant    = 0;
    
    hBmp = CreateCompatibleBitmap(s->native.window.hDC,s->width,s->height);
    hOld = SelectObject(hDCMem, hBmp);
    
    res = GetDIBits(hDCMem,hBmp,0,s->height,NULL,&bitmap_info,DIB_RGB_COLORS);
    
    if( pPrintWindow)
       res = pPrintWindow(s->native.window.hWND,hDCMem,0);
    
    res = GetDIBits(hDCMem,hBmp,0,s->height,lpBits,&bitmap_info,DIB_RGB_COLORS);
    
    SelectObject(s->native.window.hDC, hOld);
    DeleteObject(hDCMem);

  11. #11
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Traduction: La fenêtre en question n'implémente pas WM_PRINT. Dommage pour toi...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  12. #12
    Nouveau Candidat au Club
    Inscrit en
    Novembre 2008
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 7
    Points : 1
    Points
    1
    Par défaut
    Hum hum...c'est un peu bizarre tout ça étant donné que le code de retour de mon SendMessage(WM_PRINT) et de mon PrintWindow est TRUE...si j'ai bien lu la doc
    Return Values

    If the function succeeds, it returns a nonzero value.

    If the function fails, it returns zero.
    ...la fonction est censée avoir réussi...Me trompe-je?

  13. #13
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Sauf que la fenêtre ne semble pas avoir trente-six moyens d'informer qu'elle supporte ou non WM_PRINT, car la doc ne spécifie pas quelle doit être la valeur de retour du message en cas de réussite...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  14. #14
    Nouveau Candidat au Club
    Inscrit en
    Novembre 2008
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 7
    Points : 1
    Points
    1
    Par défaut
    C'est pas faux...

    Puis en même temps c'est pas facile de bosser avec des vieux outils...VS6 c'est un peu dépassé...mais quand on n'a pas le choix...

    Je pense donc que je n'ai pas beaucoup de choix à part garder mon glReadPixels...

    Merci pour avoir faire fait un peu chauffer vos méninges!!

Discussions similaires

  1. [Débutant] Récupération des données d'une colonne cachée d'un gridview
    Par Spray dans le forum ASP.NET
    Réponses: 1
    Dernier message: 01/12/2011, 11h12
  2. [Débutant] Récupération des valeurs d'une fenêtre text
    Par aissa2010 dans le forum Interfaces Graphiques
    Réponses: 16
    Dernier message: 31/07/2010, 16h41
  3. Récupération des paramètres d'une requête
    Par TomPad dans le forum Access
    Réponses: 10
    Dernier message: 16/06/2005, 15h11
  4. Récupération des paramètres avec une procedure stockée
    Par samlerouge dans le forum Bases de données
    Réponses: 2
    Dernier message: 31/03/2004, 22h00
  5. Réponses: 2
    Dernier message: 30/05/2002, 10h19

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