begin process at 2008 07 06 01:31:34
1 205 425 membres
7 nouveaux aujourd'hui
14 119 membres club

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é: 2 854 / 244

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

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;		
  }
}
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

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.
  • 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

Pub



Appels d'offres

Plugin Dialer outlook
Budget : 2 000€
Travail graphique- ill...
Budget : 1 000€
creation de marque et ...
Budget : 1 000€

CalendriCode

Juillet 2008
LMMJVSD
 123456
78910111213
14151617181920
21222324252627
28293031   

Téléchargements

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

Boutique

Boutique de goodies CodeS-SourceS