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 !

BITMAP EN GRAYSCALE (WIN32)


Information sur la source

Catégorie :API Classé sous : image, dégradé, noir, blanc, grayscale Niveau : Débutant Date de création : 09/07/2005 Date de mise à jour : 11/07/2005 16:21:30 Vu / téléchargé: 3 345 / 255

Note :
9 / 10 - par 2 personnes
9,00 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

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

Description

Cliquez pour voir la capture en taille normale
Applique un effet GrayScale (niveaux de gris) sur un bitmap.

Comment procède-t-on?
On doit d’abord récupérer les 3 composantes du pixel (Blue, Green, Red). Puis on doit effectuer une moyenne des composantes.
On pourrait faire 1/3*R + 1/3*G + 1/3*B, ce qui implique que le rouge, le vert et le bleu apparaissent avec la même intensité, ce qui est incorrect.
En effet cette équation représente l’intensité du pixel et reflète mal la perception que l’homme a du rouge, du vert et du bleu.
Ainsi il existe un standard de conversion plus exact, à savoir : 0.299*R + 0.587*G + 0.114*B (méthode basée sur la luminance du modèle YUV, comme pour les téles N&B).
On répète ainsi cette étape pour chaque pixel, et on obtient alors un résultat assez probant.

Voir la capture d'écran pour un exemple avec mon chat :)
Codé en C/WIN32, compilé sous VS.NET 2003, testé sous XP.
 

Source

  • void DrawGrayScale()
  • {
  • int i;
  • BYTE r, g, b, y;
  • for(i = 0; i < cxDib * cyDib; i++) {
  • b = pbitsbmp[i * 3]; // Blue
  • g = pbitsbmp[i * 3 + 1]; // Green
  • r = pbitsbmp[i * 3 + 2]; // Red
  • y = (306 * r + 601 * g + 117 * b) >> 10; // 0.299 * r + 0.587 * g + 0.114 * b
  • pbitsbmp[i * 3] = y;
  • pbitsbmp[i * 3 + 1] = y;
  • pbitsbmp[i * 3 + 2] = y;
  • }
  • }
void DrawGrayScale()
{
  int i;
  BYTE r, g, b, y;
  for(i = 0; i < cxDib * cyDib; i++) {
    b = pbitsbmp[i * 3]; // Blue
    g = pbitsbmp[i * 3 + 1]; // Green
    r = pbitsbmp[i * 3 + 2]; // Red
    y = (306 * r + 601 * g + 117 * b) >> 10; // 0.299 * r + 0.587 * g + 0.114 * b
    pbitsbmp[i * 3] = y;
    pbitsbmp[i * 3 + 1] = y;
    pbitsbmp[i * 3 + 2] = y;		
  }
}

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 !
  •   Release
    • GrayScale.exe.bakTélécharger ce fichier [Réservé aux membres club]5 120 octets
  • GrayScale.apsTélécharger ce fichier [Réservé aux membres club]17 868 octets
  • GrayScale.cppTélécharger ce fichier [Réservé aux membres club]Voir ce fichier5 175 octets
  • GrayScale.ncbTélécharger ce fichier [Réservé aux membres club]35 840 octets
  • GrayScale.rcTélécharger ce fichier [Réservé aux membres club]Voir ce fichier1 989 octets
  • GrayScale.slnTélécharger ce fichier [Réservé aux membres club]Voir ce fichier907 octets
  • GrayScale.suoTélécharger ce fichier [Réservé aux membres club]9 216 octets
  • GrayScale.vcprojTélécharger ce fichier [Réservé aux membres club]3 977 octets
  • resource.hTélécharger ce fichier [Réservé aux membres club]Voir ce fichier626 octets

Télécharger le zip

Historique

09 juillet 2005 19:37:42 :
Ajout de quelques explications.
11 juillet 2005 16:11:05 :
Méthode de conversion plus rapide (division par puissance de 2). Ajout vérification si bitmap est 24 bits.
11 juillet 2005 16:21:30 :
Correction orthographique.

Commentaires et avis

signaler à un administrateur
Commentaire de vecchio56 le 09/07/2005 17:34:05 administrateur CS

y = (BYTE)((299 * r + 587 * g + 114 * b) / 1000);
Comment tu as trouvé ca? En tous ca c'est sur que 3 multiplications et une division dans une grosse boucle comme ca, ca prend du temps. Est-ce que ca change beaucoup si on fait un truc comme ca?
y = (BYTE)((307 * r + 595 * g + 122 * b) / 1024);
(j'ai pas gardé la proportionnalité, mais a mon avis ca vaut le coup de diviser par une puissance de 2)

signaler à un administrateur
Commentaire de Urgo le 09/07/2005 19:29:14

Tu trouveras certaines explications sur ces valeurs ici :
http://www.commentcamarche.net/video/couleur.php3#YUV

Ici la division par 1000 n'utilise pas l'instruction 'div' (en ASM) car VS 2003 est déjà assez "intelligent", donc ça va déjà plus vite.

Par contre je ne sais pas si la division par une puissance de 2 serait beaucoup plus rapide. Il faudrait faire des tests, mais ce soir je n'aurai sans doute pas le temps, donc si tu es partant fais-toi plaisir :)


signaler à un administrateur
Commentaire de vecchio56 le 09/07/2005 20:00:06 administrateur CS

Bien sur, une division par 1024 se fait en 1 cycle, par décalage de 10 à droite
C'est vrai pour la division par 1000, vs doit multiplier par l'inverse

signaler à un administrateur
Commentaire de remi1203 le 11/07/2005 03:12:03

Salut

A mon avis la division par une puissance de deux est plus rapide, mais seulement si on utilise l'operateur >>.
Sinon (j'ai pas regardé le code) ca marcherait pas de faire y = (BYTE)(0.299 * r + 0.587 * g + 0.114 * b) ?
Paske la plus besoin de faire une division, ya plus ke des multiplications et c'est beaucoup plus rapide...

signaler à un administrateur
Commentaire de BruNews le 11/07/2005 09:32:52 administrateur CS

Assurément non, le passage en FPU est couteux.

signaler à un administrateur
Commentaire de remi1203 le 11/07/2005 15:18:03

ok BruNews j'avais pas fais gaffe - comme j'ai dit j'ai pas regardé le code - mais si on est deja sur le FPU c'est toujours plus rapide de faire * 0.5 que / 2.

a mon avis si on veut pas utiliser les floats le plus rapide c'est :
y = (BYTE)((306 * r + 601 * g + 117 * b) >> 10)
(les coefficients sont calculés avec un simple poduit en croix sinon l'image n&b risque d'etre plus foncée que l'originale)

signaler à un administrateur
Commentaire de Urgo le 11/07/2005 16:25:01

Bon, voilà la mise à jour a été faite.
Je remercie vecchio56 pour sa remarque, le code est désormais corrigé.

Remi, en virant le cast inutile et les parenthèses à gogo c'est encore plus joli ;)

signaler à un administrateur
Commentaire de boumarsel le 17/07/2005 14:01:51

299 * r + 587 * g + 114 * b / 1000 = 307 * r + 595 * g + 122 * b) / 1024 ?? :))

a/b = a+c/b+c
c'est une nouvelle lois mathematique ça?
et ce que tu as proposé pire encore..en tout cas essai de faire des tests.
++

signaler à un administrateur
Commentaire de boumarsel le 17/07/2005 14:05:39

la seule solution c'est de multiplier les coefficients par 1.024 (1024/1000) pour avoir une division par 1024. et tu te trouveras avec un calcul plus penalisant en rapidité.
(j'ai pas telechargé la source...j'espere que l'auteur n'a pas fait une mise à jour pour mettre ce que tu lui as proposé)

signaler à un administrateur
Commentaire de vecchio56 le 17/07/2005 14:29:17 administrateur CS

C'est juste une approximation bien sur, les différences sont sans doutes invisibles

signaler à un administrateur
Commentaire de vecchio56 le 17/07/2005 14:32:51 administrateur CS

299*1.024=306
587*1.024=601
114*1.024=117

C'est ce qu'a fait urgo et ca ne change quasiment rien (l'équation de départ est aussi sans doute deja une approximation)

signaler à un administrateur
Commentaire de Urgo le 17/07/2005 16:47:04

Que dire... bourmarsel télécharge la source et constate les faits par toi-même.

signaler à un administrateur
Commentaire de vecchio56 le 17/07/2005 17:26:55 administrateur CS

Même pas besoin, il y a le code en preview

Ajouter un commentaire

Discussions en rapport avec ce code source dans le forum

C : conversion d'image cvouleur en noir et blanc [ par nemege ] salut,j'aimerais savoir comment faire en C pour convertir une image couleur en noir et blanc ???merci . Recherche format d'image le plus simple !! [ par ymerej ] Bonjour,je souhaite connaitre quel est le format d'image le plus simple a lire car en fait je veu récupérer une image en noir et blanc de 128 x 64 et conversion couleur noir & blanc [ par scudi ] Bonjour! j aimerai savoir comment faire pour changer une image en couleur en noir et blanc. Je sait qu il faut changer la palette de l image (je trait repérage du centre de taches [ par sofbboy ] Bonjour à tous!!!J'ai une image bicouleur (noir et blanc, issue d'un seuillage). Sur laquelle se trouve des especes de taches circulaires. En fait les Fondu noir et blanc [ par clem0338 ] Bonjour, J'aimerais savoir si quelqu'un connait une technique pour faire un fondu en noir et blanc de l'&#233;cran ( comme la boite de fermeture de w Matrice associé à une image [ par njo80 ] J'ai un problème assez simple à comprendre mais difficille à faire.Ce n'et pas vraiment en C. Bien que cela me permettra de détecter les collisions su aide sur image [ par shubenka ] sous visual c++g une image bmp d'un schema (electronique) mais quand je l'affiche sur une dialog le blanc qui'l y a autour reste j'aimerais que se bla ecrire noir sur blanc dans la console [ par Spiffou ] bonjour &#224; tous, je voudrais ecrire dans la console en noir sur fond blanc au lieu de blanc sur fond noir... cad que quand je fait un printf("xx" TRAITEMENT IMAGE .RAW [ par vadeon ] Bonjour je suis sur un syst&#232;me ou je prend une image d'une camera et celle ci est du format .raw et je me dois d'utilis&#233; l'application Rawd Ouverture de fichiers images [ par elo29 ] Bonjour, Je travaille sur un projet dans lequel je dois capturer une vidéo, en extraire les images et appliquer un traitement à chacune d'entre elles


Nos sponsors

Sondage...

CalendriCode

Juillet 2009
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
2728293031  

Consulter la suite du CalendriCode

Téléchargements

Logiciels à télécharger sur le même thème :

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 : 0,484 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é.