IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

MFC Discussion :

[MFC]Afficher une image bmp niveau de gris SetDIBitsToDevice


Sujet :

MFC

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    19
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2005
    Messages : 19
    Points : 7
    Points
    7
    Par défaut [MFC]Afficher une image bmp niveau de gris SetDIBitsToDevice
    Bonsoir,

    Je possède un tableau avec des valeurs entre 0 et 255 qui représentent mon image en niveau de gris. Je voudrais l'afficher avec la méthode SetDIBitsToDevice. J'ai déjà utilisé la méthode setPixels() mais elle est trop lente pour l'affichage d'un flux de données. J'ai déjà fait de nombreuses recherches sur internet sans succès.

    Voivi où j'en suit dans mon code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
     
     
    ...
    	BITMAPINFOHEADER bmih;
    	bmih.biWidth = 256;
    	bmih.biHeight = 240;
    	bmih.biPlanes = 1;
    	bmih.biCompression = BI_RGB;
    	bmih.biSize = sizeof(BITMAPINFOHEADER); 
    	bmih.biBitCount = 8;
    	bmih.biClrUsed = 0;
    	bmih.biClrImportant = 0;
    	bmih.biXPelsPerMeter = 0;
    	bmih.biYPelsPerMeter = 0;
    	bmih.biSizeImage = 0;
     
    	BITMAPINFO bm_info;
    	bm_info.bmiHeader = bmih;
    	RGBQUAD *colormap;
    	colormap = new RGBQUAD[2];
    	int i;
     
    	bm_info.bmiColors[1] = *colormap;
     
    ...
    	BYTE * color;
     
    	color = new BYTE[61440];
     
    	// Ouverture du fichier en lecture
    	fbuffer = fopen("test_compression.txt", "r");
     
    	// Lecture du tableau proprement dit
    	for (i = 0; i < 61440; i++)
    	                fscanf(fbuffer, "%d", &color[i]);
     
    	// Fermeture du fichier
    		fclose(fbuffer);
     
    ...
    Jusqu'ici le résultat n'est pas terrible. Les pixel ne s'affiche pas en niveau de gris mais avec des couleur bizare. Que puis-je faire pour remédier à cela ?



    Merci.

  2. #2
    mat.M
    Invité(e)
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
      bmih.biBitCount = 8;
    *biBitCount ne semble pas bon pour une monochrome ;

    biBitCount
    Specifies the number of bits per pixel. The biBitCount member of the BITMAPINFOHEADER structure determines the number of bits that define each pixel and the maximum number of colors in the bitmap. This member must be one of the following values. Value Meaning
    0 Windows 98, Windows NT 5.0 and later: The number of bits per pixel is specified or is implied by the JPEG format.
    1 The bitmap is monochrome, and the bmiColors member contains two entries. Each bit in the bitmap array represents a pixel. If the bit is clear, the pixel is displayed with the color of the first entry in the bmiColors table; if the bit is set, the pixel has the color of the second entry in the table.

    *Il faut utiliser CreateDIBSection apparemment

    bmiColors
    The bmiColors member contains one of the following:
    An array of RGBQUAD. The elements of the array make up the color table.
    An array of 16-bit unsigned integers that specifies indexes into the currently realized logical palette. This use of bmiColors is allowed for functions that use DIBs. When bmiColors elements contain indexes to a realized logical palette, they must also call the following bitmap functions: CreateDIBitmap, CreateDIBPatternBrush, and CreateDIBSection. The iUsage parameter of CreateDIBSection must be set to DIB_PAL_COLORS.


    *as-tu fait cette manip ??
    An application should use the information stored in the biSize member to locate the color table in a BITMAPINFO structure, as follows:

    pColor = ((LPSTR)pBitmapInfo +
    (WORD)(pBitmapInfo->bmiHeader.biSize));

  3. #3
    mat.M
    Invité(e)
    Par défaut
    ce lien peut-être instructif

    http://www.codeproject.com/bitmap/gditutorial.asp

    8)

  4. #4
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    19
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2005
    Messages : 19
    Points : 7
    Points
    7
    Par défaut
    Je suis déjà aller voir sur ce lien mais je ne m'en sort plus. Je cherche depuis plus de 10h. Je pensait que bmih.biBitCount = 8; signifiait que le nombre de bits pour définir unpixel était de 256 soit 256 niveau de gris. Le monochrome c'est jsute noir ou blanc et pas de niveau de gris, non ?

    Peux tu m'aider stp pour utiliser CreateDIBSection et en quoi cela peut résoudre mon problème. C'est pas au niveau des palette mon problème ?

    Comment faire avec RGBQUAD., je ne pige pas ça du tout dans le BITMAPINFO...

    Merci bcp.

  5. #5
    Membre régulier
    Inscrit en
    Décembre 2003
    Messages
    99
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 99
    Points : 82
    Points
    82
    Par défaut
    Salut, essaye avec le code suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
     
    		unsigned int i = 0;
    		unsigned int j = 0;
    		unsigned int k = 0;
     
    		BITMAPINFO bmi;
     
    		memset(&bmi, 0, sizeof(bmi));
    		bmi.bmiHeader.biBitCount = 24;
    		bmi.bmiHeader.biClrImportant = 0;
    		bmi.bmiHeader.biCompression  = BI_RGB;
    		bmi.bmiHeader.biHeight   = ht;
    		bmi.bmiHeader.biPlanes = 1;
    		bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    		bmi.bmiHeader.biSizeImage = 0;
    		bmi.bmiHeader.biWidth = wh;
    		bmi.bmiHeader.biXPelsPerMeter = 0;
    		bmi.bmiHeader.biYPelsPerMeter = 0;
     
    		HDC hdc=::GetDC(m_hWnd);
     
    		unsigned char *bits=(unsigned char *) malloc ( ((long int) (( bmi.bmiHeader.biWidth*3 + bmi.bmiHeader.biWidth%4 ) * bmi.bmiHeader.biHeight   ))  * sizeof(unsigned char));
     
    		long int cnt=0;
     
    			for(i=0;i<bmi.bmiHeader.biHeight;i++)
    			{
    				for(j=0;j<bmi.bmiHeader.biWidth;j++)
    				{
    					couleur = GetPixels(hdc,j,i);
    					int r = (couleur>>16)&0x000000ff;
    					int v = (couleur>>8)&0x000000ff;
    					int b = couleur & 0x000000ff;
     
                   //conversion en niveau de gris
                   int lum = (int)(.299 * (double)(r) + .587 * (double)(v) + .114 * (double)(b));
     
    					bits[cnt+2] = lum;
    					bits[cnt+1] = lum;
    					bits[cnt]	= lum;
    					cnt+=3;
     
    				}
    				//Chaque ligne doit etre multiple de 4
    				for (j=0;j<bmi.bmiHeader.biWidth%4;j++)
    				{
    					bits[cnt] = 0;
    					cnt++;
    				}				
    			}
     
     
    			SetDIBitsToDevice(hdc,0,0,(DWORD)wh,(DWORD)ht,0,0,0,
    				(WORD)ht,bits,(LPBITMAPINFO)&bmi,DIB_RGB_COLORS);

  6. #6
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    19
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2005
    Messages : 19
    Points : 7
    Points
    7
    Par défaut
    Avant tout un super grand merci... Et oui ça marche ! Seulement l'image est fort sombre par rapport à un niveau de gris traditionnel.

    Voici le résultat :



    Alors que je m'attends à ceci :



    Peux tu m'expliquer comment modifier cela, en gros comment ça se passe dans le code que tu m'as passé pour la conversion en niveau de gris ?

    Peux tu m'expliquer ton code et chacune de ces étapes. Histoire que je sache comment ça marche et le refaire éventuellement par moi même ?


    Quelques petites questions me viennet à l'esprit :

    - bmi.bmiHeader.biBitCount = 24;, pourquoi coder chaque pixel sur 3 octets (rouge, vert, et bleu respectivement) alors que je veux du noir et blanc en niveau de gris sur 256 bits soit 8 bytes et pas 24 !

    - Quelle est la structure exacte de tableau de char bits ?

    - Que font les lignes int r = (couleur>>16)&0x000000ff;... ?

    - Comment choisir les coéfficient de lum ?

    - Enfin ,pourquoi chaque ligne doit être multiple de 4 ?

    Encore un super merci. Je n'hésiterai pas à te montrer le résultat de mon projet (contrôle d'un robot + acquisition vidéo). Super...

  7. #7
    Membre éclairé
    Avatar de matazz
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    471
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 471
    Points : 668
    Points
    668
    Par défaut
    Essaye cette formule :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int lum =  (((b)*117 + (g)*601 + (r)*306) >> 10);

  8. #8
    Membre régulier
    Inscrit en
    Décembre 2003
    Messages
    99
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 99
    Points : 82
    Points
    82
    Par défaut
    Salut,

    Tout d'abord l'ecran noir c'est pas normal. Sans la convertion en niveaux de gris ca t'affiche ton image ou pas ?

    bmi.bmiHeader.biBitCount = 24;, pourquoi coder chaque pixel sur 3 octets (rouge, vert, et bleu respectivement) alors que je veux du noir et blanc en niveau de gris sur 256 bits soit 8 bytes et pas 24 !
    Effectivement sa peut paraitre stupide mais c'est plus simple ainsi. Sinon tu est obligé de définire ta propre palette de couleur. Note de plus que le dernier parametres de la fonction SetDIBitsToDevice est "DIB_RGB_COLORS" ce qui correspond à la valeur de bmi.biColors...

    - Quelle est la structure exacte de tableau de char bits ?
    Soit l'image en RGB:

    255 128 133 115 166 155 100 111 121
    123 125 185 235 255 123 235 126 106
    145 165 187 233 104 106 100 156 13

    Alors bits =

    [187,165,145,106,104,233,13,156,100,0 , 185, 125,123,123,255,235,106,126,235,0,133,128,255,155,166,115,121,111,100,0]

    Je sais pas si c'est tres clair mais en gros le tableau a une dimension et est de type BGR.


    - Que font les lignes int r = (couleur>>16)&0x000000ff;... ?
    La fonction GetPixel te retourne la couleur d'un pixels sous forme d'entier. Ces lignes permetent simplement de recuperer les composantes RVB du pixels.

    En fait "int r = (couleur>>16)&0x000000ff;" est iquivalent à "int r = couleur/(2^16) mod 256". Cela va plus vite de faire des décalages et des operations binaire que des division ou des modulos.

    Comment choisir les coéfficient de lum ?
    En fait les coefs je les ai recuperé tels quels. Sinon une autre methode consiste à faire la moyenne des 3 composantes et l'assigner à chaque composante( Mais elle ne retranscrie pas bien la luminosite de l'image). Chez moi la méthode de la luminance marche tres bien.

    - Enfin ,pourquoi chaque ligne doit être multiple de 4 ?
    .

    C'est le format Bitmap qui impose ca ....

    Pour les commentaires du code il est plus simple que tu me demande directement ce que tu ne comprend pas ?

  9. #9
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    19
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2005
    Messages : 19
    Points : 7
    Points
    7
    Par défaut
    Un grand merci pour tout it works !

    Merci bcp.

    A plus.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 0
    Dernier message: 29/10/2008, 13h14
  2. Réponses: 1
    Dernier message: 08/03/2007, 15h39
  3. [MFC] afficher une image
    Par kabil.cpp dans le forum MFC
    Réponses: 3
    Dernier message: 24/04/2006, 09h35
  4. Réponses: 1
    Dernier message: 30/11/2005, 17h12
  5. Problème pour afficher une image bmp
    Par homeostasie dans le forum MFC
    Réponses: 6
    Dernier message: 08/05/2005, 18h36

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo