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 !

GET ET SETDIBITS


Information sur la source

Catégorie :Graphique Classé sous : setdibits, getdibits Niveau : Débutant Date de création : 26/07/2006 Date de mise à jour : 28/04/2007 21:27:31 Vu / téléchargé: 5 222 / 481

Note :
Aucune note

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


Description

Cliquez pour voir la capture en taille normale
Pour question sur le forum. Cette source charge un Bitmap sur la fenêtre (l'image n'est pas redimentionné si elle est trop grande), en cliquant sur modifier, elle récupère les données de l'image dans un buffer grâce à GetDIBits, modifie les couleurs et réaffiche à l'écran l'image modifié grâce à SetDIBits.
 

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

26 juillet 2006 02:49:42 :
Optimisation de dernière minute
26 juillet 2006 04:10:41 :
Corrections
26 juillet 2006 16:39:35 :
Preview
26 juillet 2006 18:18:43 :
Corrections
26 juillet 2006 18:33:38 :
Améliorations
27 juillet 2006 20:05:11 :
Corrections
23 septembre 2006 17:55:55 :
Modifications mineures
28 avril 2007 21:27:31 :
Optimisations majeurs

Commentaires et avis

signaler à un administrateur
Commentaire de vecchio56 le 26/07/2006 14:40:38 administrateur CS

T'es sur de ton coup? Je vois pas de mofication de l'image

signaler à un administrateur
Commentaire de SAKingdom le 26/07/2006 15:33:07

for(y = bi.bmiHeader.biHeight-1; y >= 0; y--)
{
for(x = bi.bmiHeader.biWidth-1; x >= 0; x--)
  {
   // Calcule de la position dans le buffer
   int pos = (bi.bmiHeader.biHeight-y-1)*ByteWidth+x+x*2;

   lpBits[pos]++; // Bleu
   lpBits[pos+1]++; // Vert
   lpBits[pos+2]++; // Rouge
  }
}

Changement de la couleur de chaque pixel à partir du buffer.

signaler à un administrateur
Commentaire de vecchio56 le 26/07/2006 16:10:48 administrateur CS

Oui dans le code je l'ai vu, mais quand je teste l'exécutable, l'image n'est pas modifiée

signaler à un administrateur
Commentaire de SAKingdom le 26/07/2006 16:14:18

C'est bizzard. Moi tout les bmp que j'ai tester ce modifiais quand je cliquais sur modifier. A tu essayé en recompilant le code?

signaler à un administrateur
Commentaire de vecchio56 le 26/07/2006 16:19:26 administrateur CS

C'est fou le nombre de gens qui ne savent pas écrire bizarre :)
Ben non j'ai pas recompilé, c'est quand même censé marcher directement avec l'exécutable

signaler à un administrateur
Commentaire de SAKingdom le 26/07/2006 16:25:42

Ben là. Excuse pour les fautes. Je vien d'apprendre qu'un membre de ma famille est mort alors ça me débousole un peu. Sinon, je ne comprend vraiment pas. Tout fonctionne ici. Même si je télécharge l'exe, il fonctionne qu'en même.

signaler à un administrateur
Commentaire de SAKingdom le 26/07/2006 16:33:15

C'est pas une blague que t'es entrait de me faire là ;)?
Sinon, décrit moi ce que tu fait. Il ne se passe vraiment rien quand tu clique sur modifier?

signaler à un administrateur
Commentaire de vecchio56 le 26/07/2006 16:45:57 administrateur CS

J'ouvre mspaint, je gribouille un peu
J'enregistre l'image au format bmp 24 bits
Je lance ton programme
J'ouvre l'image que je viens d'enregistrer
J'appuie sur Modifier comme un forcené, mais rien ne se passe (on voit bien l'image mais elle ne change pas)
Désolé mais ce n'est pas une blague

signaler à un administrateur
Commentaire de racpp le 26/07/2006 16:48:16 administrateur CS

Salut,
Je viens de tester l'exe et pas de modification de l'image chez moi non plus.

signaler à un administrateur
Commentaire de SAKingdom le 26/07/2006 17:11:45

Je vien de tester sur mon autre ordinateur et en effet, ça ne fonctionne pas non plus. C'est trop bizzard. Pourquoi tout fonctionne sur mon ordi mais pas sur les votres

signaler à un administrateur
Commentaire de SAKingdom le 26/07/2006 17:22:00

Ête vous capable de voir ce qui ne fonctionne pas dans le code? Moi j'ai bo chercher, je ne suis pas famillié avec les dialog

P.S. J'ai utiliser ton éditeur vecchio. Ce pourrait-il que ce soit le dialog le problème?

signaler à un administrateur
Commentaire de vecchio56 le 26/07/2006 17:26:02 administrateur CS

Ah oui j'avais pas vu, merci!
Ben non logiquement ca peut pas venir de ca. Je vais voir si je trouve d'ou ca vient

signaler à un administrateur
Commentaire de vecchio56 le 26/07/2006 17:28:47 administrateur CS

L'appel de GetDIBits retourne 0 chez moi

signaler à un administrateur
Commentaire de vecchio56 le 26/07/2006 17:39:25 administrateur CS

Ca marche si on force bmp.bmBitsPixel à 24 juste après GetObject(hBmp, sizeof(bmp), &bmp);

signaler à un administrateur
Commentaire de SAKingdom le 26/07/2006 17:55:50

Ok je comprend. C'est le calcule de la taille du buffer le problème. D'accord. Je modifie le code pour le forcer à prendre du 24 bits.

signaler à un administrateur
Commentaire de SAKingdom le 26/07/2006 18:07:46

Bingo. J'ai tout compris. En fait, étant donné que je récupère les données du DC mémoire, ce DC mémoire prend le nombre de couleurs de l'écran. Donc bmp.bmBitsPixel renvoie le nombre de couleur présent dans le DC mémoire qui est égual au nombre de couleur de votre système. Vue que je suis en 16 bits ici, moi ça fonctionnait mais il modifiait uniquement le bleu et le vert. Bon je modifie le code et je fais quelque test de sécurité et je vous renvoie ça.

Merci vecchio, c'est grâce à toi que j'ai allumé.

signaler à un administrateur
Commentaire de SAKingdom le 26/07/2006 18:19:10

Ok c'est fait. L'exe est-il fonctionnel à présent?

signaler à un administrateur
Commentaire de vecchio56 le 26/07/2006 18:25:28 administrateur CS

Oui je pense que c'est bon

signaler à un administrateur
Commentaire de gamemonde le 27/07/2006 02:04:40

oui maintenant ca marche tres bonne source ca va en aider beaucoup moi-de-meme qui defois me pert dans cette fonction

signaler à un administrateur
Commentaire de eRoZion le 27/07/2006 05:48:59

Salut,
merci pour la source.   :)

Ca fonctionne chez moi (nouvelle version de l'exe qui fonctioone chez tout le monde à prioris, pas testé la précédente).

Sinon pour l'ortho de "bizzard", je pense tout simplement que c'est le syndrome de la génération blizzard. :D

A+


eRoZion

signaler à un administrateur
Commentaire de steve_clamage le 29/07/2006 22:16:28

Pourquoi parcourir l'image de cette façon ? C'est peut lisible et au final c'est moins efficace ??

signaler à un administrateur
Commentaire de SAKingdom le 29/07/2006 22:20:44

Peux tu expliquer ce que tu veux dire s'il te plait?

signaler à un administrateur
Commentaire de steve_clamage le 29/07/2006 22:46:19

Pourquoi ne pas parcourir l'image comme ca tout simplement ?

for(y = 0; y < bi.bmiHeader.biHeight; y++)
{
for(x = 0; x < bi.bmiHeader.biWidth; x++)
  {
   // Calcule de la position dans le buffer
   const int pos = (y * bi.bmiHeader.biWidth) + x*3;

   lpBits[pos]++; // Bleu
   lpBits[pos+1]++; // Vert
   lpBits[pos+2]++; // Rouge
  }
}

signaler à un administrateur
Commentaire de vecchio56 le 29/07/2006 22:59:49 administrateur CS

Normalement on ne devrait pas avoir a calculer de position a chaque tour de boucle. Il suffit de passer toute la zone mémoire séquentiellement

signaler à un administrateur
Commentaire de SAKingdom le 29/07/2006 23:01:52

Soustraire vers 0 est toujours plus rapide que d'additionner de 0:
for (y = 0; y < bi.bmiHeader.biHeight; y++)
xor ebx, ebx ;;; y = 0
lblFOR:
;;; divers codes
inc ebx
cmp ebx, bi.bmiHeader.biHeight <- ICI cette comparaison prend du temps processeur et peut être évité
jb lblFOR

for (y = bi.bmiHeader.biHeight - 1; y >= 0; y--)
mov ebx, bi.bmiHeader.biHeight - 1
lblFOR:
;;; divers codes
dec ebx
jns lblFOR

Normalement oui vecchio mais comme pour mon autre source, ceci a aussi pour but de montrer comment calculer la position x et y dans le buffer.

signaler à un administrateur
Commentaire de SAKingdom le 29/07/2006 23:11:22

Ah et pour le x+x*2 à la place de x*3 c'est que x*3 va générer un imul très coûteux en temps processeur. x+x*2 va générer un lea, beaucoup moin long à executer et tout aussi efficasse.

P.S. Merci à BruNews, c'est lui qui m'a apprit tout ça :)

signaler à un administrateur
Commentaire de steve_clamage le 29/07/2006 23:12:06

Tu enlèves une comparaison mais ton calcul de pos est plus complexe, surtout que comme l'a dit vecchio56 ca peut se parcourir en une seule boucle.

Tu devrais faire des tests car tu gagnes presque rien (un cmp contre un jns), ca peut meme empecher le compilateur de faire de vrai optimisations (comme une vectorisation). En générale on optimise ce qui prend du temps, pas le code d'une boucle !

signaler à un administrateur
Commentaire de SAKingdom le 29/07/2006 23:21:44

Je crois que tu as raison. J'ai fait des listings et à première vue, le calcule bouffe beaucoup de temps processeur.

signaler à un administrateur
Commentaire de steve_clamage le 29/07/2006 23:25:17

"Ah et pour le x+x*2 à la place de x*3 c'est que x*3 va générer un imul très coûteux en temps processeur. x+x*2 va générer un lea, beaucoup moin long à executer et tout aussi efficasse."

Le compilateur n'est pas con, si nous on peut le faire alors lui... . J'ai testé avec gcc (en -O3) et il me génère exactement la meme sortie pour x*3 et x*2 +x, avec le leal. Le but d'un compilateur c'est de ne plus avoir à penser en logique assembleur, sinon autant écrire directement en assembleur pour avoir un vrai controle sur le code. Il ne faut pas non plus oublier que le compilateur sais optimiser un code dans la mesure du possible, tant qu'il possède assez d'information pour etre sur de ne pas casser la sémantique du code.

signaler à un administrateur
Commentaire de Omeya le 02/08/2006 16:13:32

steve_clamage : "Tu enlèves une comparaison mais ton calcul de pos est plus complexe, surtout que comme l'a dit vecchio56 ca peut se parcourir en une seule boucle."

J'ai du mal à comprendre quand vous dites qu'il suffit de passer toute la zone mémoire séquentiellement.
Quel est le code en une seule boucle, svp?

signaler à un administrateur
Commentaire de Omeya le 02/08/2006 18:45:06

Je crois avoir trouvé... Je ne sais pas si c'est ça, mais "séquentiellement" signifie incrémenter ou décrémenter un pointeur sur le tableau LPBYTE. Dites-moi si j'ai faux.
En tout cas, j'ai testé la méthode séquentielle et ça marche.

signaler à un administrateur
Commentaire de SAKingdom le 02/08/2006 21:31:48

D'après ce que j'en sais, une lecture séquencielle signifie lire les valeurs dans l'ordre une à la suite de l'autre. C'est évident que cette méthode va beaucoup plus vite que de calculer à chaque tour de boucle la position x et y mais il devien impossible d'optenir une position bien précise en un calcule. Il est toujours intéressent de savoir comment aller à la position x et y de son image à partir du buffer. Ça permet de modifier bien spécifiquement son image.

signaler à un administrateur
Commentaire de vecchio56 le 02/08/2006 21:49:20 administrateur CS

Oui, mais ce n'est pas une raison pour le faire dans un boucle.
Je suis pss du tout ton raisonnement:
-d'une part tu converge vers 0 parce que c'est soit-disant plus rapide (une instruction en moins)
-d'autre part tu ralentis considérablement la boucle en faisant à chaque tour un calcul inutile

signaler à un administrateur
Commentaire de SAKingdom le 02/08/2006 22:13:53

Mais ce n'est qu'un simple exemple. Bien sûr que j'aurais pu modifier tel et tel pixel sans avoir recour à une boucle (ou une mais petite). Ce que je voulais faire, c'est une simple manipulation dans le buffer (ici changer les couleurs de chaque pixels) tout en montrant le calcule pour trouver une position x et y dans le buffer. Non ce n'est pas ce qu'il y a de plus optimisé mais je voulais montrer cette fonctionnalité le plus simplement possible.

signaler à un administrateur
Commentaire de steve_clamage le 02/08/2006 22:36:31

En tout cas je te conseil d'eviter les optimisations de ce genre, à savoir itérer à rebourd et faire x*2 + x au lieu de x*3, car au mieux le gain est presque invisible, au pir tu empeches le compilateur de faire de vrais optimisations et dans tout les cas ca rend le code moins lisible.

Ajouter un commentaire

Discussions en rapport avec ce code source dans le forum

Demande d'explications pour GetDIBits... [ par DJBACON_17 ] Est-ce quelqu'un pourrait m'expliquer comment , sous VC++6, je peux recuperer bits a bit le contenu du buffer que GetDIBits remplit svp?Merci d'avanc SetDIBits [ par dhylde ] &nbsp;Salut,J'ai juste une petite question, selon MSDN le param&#232;tre " CONST VOID *lpvBits, // array of bitmap bits" de&nbsp; SetDIBits De GetPixel à GetDiBits [ par foyfinou ] Bonjour,J'ai une fonction qui cherche des Pixelx d'une certaine couleur dans l'ecran courrant en utilisant GetPixel. Neanmoins, elle est trop lente et


Nos sponsors

Sondage...

CalendriCode

Juillet 2009
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
2728293031  

Consulter la suite du CalendriCode

Comparez les prix Nouvelle version

Photothèque Nouveau !



Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), 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 : 3,214 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é.