cs_Omeya
Messages postés28Date d'inscriptiondimanche 4 mai 2003StatutMembreDernière intervention10 août 2006
-
24 juil. 2006 à 00:03
cs_Omeya
Messages postés28Date d'inscriptiondimanche 4 mai 2003StatutMembreDernière intervention10 août 2006
-
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 );
}
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.
vecchio56
Messages postés6535Date d'inscriptionlundi 16 décembre 2002StatutMembreDernière intervention22 août 201013 24 juil. 2006 à 00:57
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
cs_Omeya
Messages postés28Date d'inscriptiondimanche 4 mai 2003StatutMembreDernière intervention10 août 2006 24 juil. 2006 à 01:18
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).
Vous n’avez pas trouvé la réponse que vous recherchez ?
SnOOpss
Messages postés571Date d'inscriptionsamedi 3 avril 2004StatutMembreDernière intervention 5 décembre 2013 24 juil. 2006 à 07:10
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.
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
SAKingdom
Messages postés3212Date d'inscriptionlundi 7 novembre 2005StatutMembreDernière intervention16 février 200915 25 juil. 2006 à 17:25
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
vecchio56
Messages postés6535Date d'inscriptionlundi 16 décembre 2002StatutMembreDernière intervention22 août 201013 25 juil. 2006 à 17:38
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
SAKingdom
Messages postés3212Date d'inscriptionlundi 7 novembre 2005StatutMembreDernière intervention16 février 200915 25 juil. 2006 à 17:47
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
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).
cs_Omeya
Messages postés28Date d'inscriptiondimanche 4 mai 2003StatutMembreDernière intervention10 août 2006 25 juil. 2006 à 23:54
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.
cs_Omeya
Messages postés28Date d'inscriptiondimanche 4 mai 2003StatutMembreDernière intervention10 août 2006 26 juil. 2006 à 01:06
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
cs_Omeya
Messages postés28Date d'inscriptiondimanche 4 mai 2003StatutMembreDernière intervention10 août 2006 26 juil. 2006 à 21:35
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