Getpixel et Setpixel trop lents! :( [Résolu]

cs_Omeya 28 Messages postés dimanche 4 mai 2003Date d'inscription 10 août 2006 Dernière intervention - 24 juil. 2006 à 00:03 - Dernière réponse : cs_Omeya 28 Messages postés dimanche 4 mai 2003Date d'inscription 10 août 2006 Dernière intervention
- 26 juil. 2006 à 21:35
Bonsoir à tous,
Depuis quelques temps, j'essaye de réaliser un capteur d'écran en temps réel et les seuls instructions que je sais vraiment utiliser sont Getpixel et Setpixel... seulement ils sont décidément beaucoup trop lent pour faire quoi que ce soit de viable.
Savez-vous comment je pourrai faire pour remplacer ces deux instructions par un code beaucoup plus rapide, s'il vous plaît?

//Voici un bout de mon code volontairement tronqué
//(certaines variables sont globales donc non définies ici)
void capture()
{
    int hauteur, longueur;
    hauteur = 200;
    longueur = 250;
    int i, j;
    COLORREF Essaicaptureligne[50000];
    GetCursorPos(&pt);

    dc = GetDC( NULL );
    Rectangle(Essaicaptureligne, pt.x-125, pt.y-100, longueur, hauteur);
    ReleaseDC( NULL, dc );

    dc = ::GetDC(GetDlgItem(Mainbox, IDC_SCREEN));
    for (i = 0; i < hauteur; i++)
    {
        for (j = 0; j < longueur; j++) SetPixel(dc, j, i, Essaicaptureligne[j+(i*longueur)]);
    }
    ReleaseDC( GetDlgItem(Mainbox, IDC_SCREEN), dc );
}

COLORREF Pixel(int x, int y)
{
    COLORREF cr = 0;    if( NULL !dc ) cr GetPixel( dc, x, y );
    return cr;
}

void Rectangle(COLORREF *sourceligne, int x, int y, int longueur, int hauteur)
{
    for (int i=0; i<hauteur;i++)
    {
        for (int j=0; j<longueur; j++)
        {
            *sourceligne = Pixel(x+j, y+i);
            sourceligne++;
        }
    }
}
/////////////////////////////////////////

Vous pouvez constater que je tente de mettre les informations obtenues via Getpixel dans un tableau à 2 dimentions pour pouvoir les manipuler. Et là, en l'occurence, je m'en sers pour les afficher dans une picturebox grâce à Setpixel.

Merci par avance pour vos éclaircissements :)
Afficher la suite 

Votre réponse

16 réponses

Meilleure réponse
SAKingdom 3213 Messages postés lundi 7 novembre 2005Date d'inscription 16 février 2009 Dernière intervention - 26 juil. 2006 à 19:37
3
Merci
Tien. J'ai fais une petite source exemple qui utilise GetDIBits et SetDIBits pour modifier une image via son buffer de couleur.

http://www.cppfrance.com/codes/GET-SETDIBITS_38788.aspx

C++ (@++)
___________________________________________
Les plus grands esprits trouvent toujours une solution

http://programmationdebat.discutforum.com

Merci SAKingdom 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 88 internautes ce mois-ci

Commenter la réponse de SAKingdom
cs_Omeya 28 Messages postés dimanche 4 mai 2003Date d'inscription 10 août 2006 Dernière intervention - 24 juil. 2006 à 00:07
0
Merci
Pour l'environnement, j'utilise Visual Studio 6 (C++) sous Windows XP SP2.
Commenter la réponse de cs_Omeya
vecchio56 6539 Messages postés lundi 16 décembre 2002Date d'inscription 22 août 2010 Dernière intervention - 24 juil. 2006 à 00:57
0
Merci
Oui il y a plus rapide: obtenir un pointeur sur une zone mémoire qui contients les pixels
GetDIBits te permet de récupérer cette zone (et remplace donc les GetPixel), puis tu alloues une deuxième zone mémoire de la même taille, sur laquelle tu va travailler. A la fin tu utilises SetDIBits ou SetDIBitsToDevice pour actualiser d'un coup ton HDC
Tu peux aussi expliquer ce que tu veux faire (j'ai un peu de mal a comprendre le code), peut être qu'il y a une facon plus simple de faire

_____________________________________
Un éditeur de ressources gratuit pour Windows
Commenter la réponse de vecchio56
cs_Omeya 28 Messages postés dimanche 4 mai 2003Date d'inscription 10 août 2006 Dernière intervention - 24 juil. 2006 à 01:18
0
Merci
Ce que je voudrai faire, en réalité, c'est obtenir un aperçu en temps réel (dans une picturebox) du carré qui se trouve autour de ma souris (un carré de taille 200x200 pixels, par exemple, au centre duquel se trouve donc ma souris).

Le HDC pris en compte est celui de l'écran, d'où le GetDC( NULL ).
Si j'ai choisis GetPixel/SetPixel en instruction, c'est parceque j'avais juste besoin d'une zone bien précise de l'écran (relative à la position de la souris), or je ne sais pas le faire avec GetDIBits et encore moins avec SetDIBits ou SetDIBitsToDevice.
Si tu pouvais me donner un exemple concret sur l'utilisation de GetDIBits, SetDIBits et/ou SetDIBitsToDevice, je t'en serai reconnaissant. J'ai tenté pendant 3 ou 4 jours d'utiliser ces instructions sans succès (aucun affichage) même avec la MSDN (que je trouve vraiment mal foutue côté exemples concrets).
Commenter la réponse de cs_Omeya
SnOOpss 571 Messages postés samedi 3 avril 2004Date d'inscription 5 décembre 2013 Dernière intervention - 24 juil. 2006 à 07:10
0
Merci
La lenteur de getpixel et Setpixel sont tres connues.
>> http://www.cppfrance.com/infomsg_Lenteur2_618463.aspx gros post de quelqu'un qui a eu le mem probleme que toi avec un example de code mais je crois meme que l'auteur en a fait une source.
Commenter la réponse de SnOOpss
vecchio56 6539 Messages postés lundi 16 décembre 2002Date d'inscription 22 août 2010 Dernière intervention - 24 juil. 2006 à 09:14
0
Merci
En l'occurence, je crois que la fonction BitBlt devrait suffire, et cette fonction est plus facile d'utilisation que SetDIBits

_____________________________________
Un éditeur de ressources gratuit pour Windows
Commenter la réponse de vecchio56
SAKingdom 3213 Messages postés lundi 7 novembre 2005Date d'inscription 16 février 2009 Dernière intervention - 24 juil. 2006 à 20:33
0
Merci
http://www.cppfrance.com/infomsg_Lenteur2_618463.aspx

Ouais mais regarde les dernières pages. Tout ce qui précède est digne d'un pur débutant :)

Ensuite, la source en question est ici:
http://www.cppfrance.com/listeauteur2.aspx?ID=617077
L'utilisation du buffer pour SetDIBitsToDevice y est expliqué.

BitBlt. Ok mais ce n'est que pour copier un DC mémoire vers le DC principal non? Son DC mémoire devra utiliser quelque chose pour déssiner dedans. Si il utilise SetPixel, ce sera toujours aussi long. Aussi d'après le code actuel, tu n'utilise pas de DC mémoire. Ça doit cintiller affreusement non?

C++ (@++)
___________________________________________
Les plus grands esprits trouvent toujours un solution

http://programmationdebat.discutforum.com
Commenter la réponse de SAKingdom
SAKingdom 3213 Messages postés lundi 7 novembre 2005Date d'inscription 16 février 2009 Dernière intervention - 24 juil. 2006 à 20:37
0
Merci
Woups. Mon lien vers la source mène vers ma liste de code.
Voici le vrai lien:
EXEMPLE D'UTILISATION DE SETDIBITSTODEVICE

C++ (@++)
___________________________________________
Les plus grands esprits trouvent toujours un solution

http://programmationdebat.discutforum.com
Commenter la réponse de SAKingdom
vecchio56 6539 Messages postés lundi 16 décembre 2002Date d'inscription 22 août 2010 Dernière intervention - 25 juil. 2006 à 05:08
0
Merci
On peut utiliser BitBlt avec le même DC source et destination (à des endroits différents bien entendu)

_____________________________________
Un éditeur de ressources gratuit pour Windows
Commenter la réponse de vecchio56
SAKingdom 3213 Messages postés lundi 7 novembre 2005Date d'inscription 16 février 2009 Dernière intervention - 25 juil. 2006 à 17:25
0
Merci
Oui mais, si il continue à utiliser SetPixel, ce sera toujours aussi long. D'après ce qu'il dit, c'est la lenteur son problème. Je ne vois pas comment BitBlt pourrait régler cela si il continue d'utiliser SetPixel. Pourrais tu m'éclairer un peu s'il te plait?

C++ (@++)
___________________________________________
Les plus grands esprits trouvent toujours un solution

http://programmationdebat.discutforum.com
Commenter la réponse de SAKingdom
vecchio56 6539 Messages postés lundi 16 décembre 2002Date d'inscription 22 août 2010 Dernière intervention - 25 juil. 2006 à 17:38
0
Merci
Mais justement BitBlt est a utiliser en remplacement à SetPixel. D'après ce que j'ai compris, il veut copier une partie de l'écran à un autre endroit, donc BitBlt

_____________________________________
Un éditeur de ressources gratuit pour Windows
Commenter la réponse de vecchio56
SAKingdom 3213 Messages postés lundi 7 novembre 2005Date d'inscription 16 février 2009 Dernière intervention - 25 juil. 2006 à 17:47
0
Merci
Ok je comprend. Mais cependant, il disait qu'il voulait manipuler les données receuillies dans un tableau à double dimention. Si c'est pour un simple copie, ça passe mais si il veut, par exemple, modifier une couleur X pour la remplacer par la couleur Y, il n'a pas le choix que de récupérer toute les données.

C++ (@++)
___________________________________________
Les plus grands esprits trouvent toujours un solution

http://programmationdebat.discutforum.com
Commenter la réponse de SAKingdom
cs_Omeya 28 Messages postés dimanche 4 mai 2003Date d'inscription 10 août 2006 Dernière intervention - 25 juil. 2006 à 23:45
0
Merci
@ [auteurdetail.aspx?ID=19734 vecchio56] :
///////////////////////////////////////
void capture()
{
    Point pt;
    GetCursorPos(&pt);
    int hauteur (200), longueur (250);

    HDC dcecran = GetDC( NULL );

    dce = GetDC(GetDlgItem(Mainbox, IDC_ECRAN));
    BitBlt(dce, 0, 0, longueur, hauteur, dcecran, pt.x-(longueur/2), pt.y-(hauteur/2), SRCCOPY);
    ReleaseDC( GetDlgItem(Mainbox, IDC_ECRAN), dce );
    
    ReleaseDC( NULL, dcecran );
}
///////////////////////////////////////

Comme tu peux le constater, mon problème n'est pas la simple recopie de l'écran vers une picturebox mais bel et bien le traitement des pixels entre les 2.
En gros, j'aimerai pouvoir travailler sur les pixels venant de l'écran avant d'afficher le résultat dans la picturebox.

Parfois je me demande pourquoi SetPixel et GetPixel ont été créés si c'est pour les mettre systématiquement à la pouvelle vu leur extrême lenteur (et encore, je suis gentil).
Commenter la réponse de cs_Omeya
cs_Omeya 28 Messages postés dimanche 4 mai 2003Date d'inscription 10 août 2006 Dernière intervention - 25 juil. 2006 à 23:54
0
Merci
J'ai oublié de vous dire que mon exemple ci-dessus ne sert strictement à rien si c'est simplement pour faire de la recopie.
J'ai besoin de traiter les données entre la capture de l'écran et l'affichage dans la picturebox (par exemple pour inverser les couleur, jouer sur les nuances, inverser l'image elle-même ou tout simplement afficher les couleurs RGB au format texte dans une autre fenetre, etc).

En tout cas, merci pour vos réponses, même si ça n'a rien donné pour le moment.
Là j'en suis à m'arracher les cheveux pour tenter de manipuler les HBITMAP dans ce but, sans aucun succès.
Commenter la réponse de cs_Omeya
cs_Omeya 28 Messages postés dimanche 4 mai 2003Date d'inscription 10 août 2006 Dernière intervention - 26 juil. 2006 à 01:06
0
Merci
Juste une dernière précision sur le type du tableau que je cherche à remplir.
C'est un tableau à 1 dimension du genre :
COLORREF tableau [longueur*hauteur]

Si je trouve une solution à mon problème d'ici 2 ou 3 jours (je doute du délai), je vous tiendrai au courant
Commenter la réponse de cs_Omeya
cs_Omeya 28 Messages postés dimanche 4 mai 2003Date d'inscription 10 août 2006 Dernière intervention - 26 juil. 2006 à 21:35
0
Merci
Merci pour le mal que vous vous donnez!

Pour ma part, j'ai entièrement résolu mon problème ce matin.
J'arrive à enregistrer la totalité de l'écran (1280*1024) dans un buffer, à en extrairer la totalité des pixels dans un tableau à 1 dimension de type COLORREF. Et, enfin, j'arrive à afficher dans une picturebox les pixels modifiés du tableau COLORREF (afin d'avoir un apperçu de mon travail)

Je vous avoue que, parfois, la programmation n'est pas du tout une partie de plaisir

Je vais continuer la discution sur l'autre topic que [auteurdetail.aspx?ID=617077 SAKingdom] à créé ;)
(http://www.cppfrance.com/codes/GET-SETDIBITS_38788.aspx)
Commenter la réponse de cs_Omeya

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.