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 :

DIB à partir d'un DDB et tableaux de pixels


Sujet :

MFC

  1. #1
    Rédacteur
    Avatar de nico-pyright(c)
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    6 414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 6 414
    Par défaut DIB à partir d'un DDB et tableaux de pixels
    Bonjour à tous,

    dans la FAQ, http://c.developpez.com/faq/vc/?page=GDI#DIBFromDDB , Mattaz décrit une méthode pour convertir un DDB (Device Dependant Bitmap) en DIB (Device Independant Bitmap).

    J'aimerai savoir comment récuperer un pointeur vers le tableau de pixels, à partir du HANDLE vers le DIB que l'on récupère en sortie de fonction.


    Merci de votre aide

    Nico

  2. #2
    Membre chevronné
    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
    Par défaut
    En premier apriori je te dirais GetDIBBits et de caster ton HANDLE en HBITMAP et en passant NULL au param HDC, mais je vais essayer...

  3. #3
    Rédacteur
    Avatar de nico-pyright(c)
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    6 414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 6 414
    Par défaut
    msdn me dit que le
    hbmp
    [in] Handle to the bitmap. This must be a compatible bitmap (DDB).
    (j'ai essayé quand meme, je suis pas comme ca ), ca ne marche pas

  4. #4
    Membre chevronné
    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
    Par défaut
    je m'en doutais mais bon...

  5. #5
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Edit: (j'ai dit une connerie)
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  6. #6
    Membre chevronné
    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
    Par défaut
    En fait le HANDLE Retourné contient un en-tête et les Bits, donc en castant ton HANDLE comme suis :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    LPBITMAPINFOHEADER lpbi =(LPBITMAPINFOHEADER)hDIB;
    tu peut ensuite calculer l'adresse de départs des bits de l'image :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     void *Bits = hDIB + sizeof(LPBITMAPINFOHEADER) + lpbi->biSize;
    Par contre comme Windows stocke les Bitmap à l'envers, Bits pointera sur la dernière ligne de l'image...

  7. #7
    Rédacteur
    Avatar de nico-pyright(c)
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    6 414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 6 414
    Par défaut
    Bon, quand je fais un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void *Bits = (LPDWORD)hDIB + sizeof(LPBITMAPINFOHEADER) + lpbi->biSize;
    Je lui vois que des 0 dans ma fenetre d'adress .
    Et ne parlons pas de l'accès à un element (x,y)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    LPDWORD lpByte = (LPDWORD)Bits + width * y + x;
    DWORD color = *lpByte;
    Noir noir toujours noir

    Pourtant, j'ai pas de noir à l'écran

  8. #8
    Membre chevronné
    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
    Par défaut
    Pour écrire le HANDLE sur le Disque j'utilise cette fonction reagarde si ça marche :


    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
    /*******************************************************************************/
    //LPTSTR szFile : DestFile
    //HANDLE hDIB  : Handle sur un DIB (convertis depuis un CBitmap par DDBToDIB)
    /*******************************************************************************/
    BOOL COutils::WriteDIB( LPTSTR szFile, HANDLE hDIB)
    	{
    	BITMAPFILEHEADER	hdr;
    	LPBITMAPINFOHEADER	lpbi;
     
    	if (!hDIB)
    		return FALSE;
     
    	CFile file;
    	if( !file.Open( szFile, CFile::modeWrite|CFile::modeCreate) )
    		return FALSE;
     
    	lpbi = (LPBITMAPINFOHEADER)hDIB;
     
    	int nColors = 1 << lpbi->biBitCount;
     
    	// Fill in the fields of the file header 
    	hdr.bfType		= ((WORD) ('M' << 8) | 'B');	// is always "BM"
    	hdr.bfSize		= GlobalSize (hDIB) + sizeof( hdr );
    	hdr.bfReserved1 	= 0;
    	hdr.bfReserved2 	= 0;
    	hdr.bfOffBits		= (DWORD) (sizeof( hdr ) + lpbi->biSize +	nColors * sizeof(RGBQUAD));
     
    	// Write the file header 
    	file.Write( &hdr, sizeof(hdr) );
     
    	// Write the DIB header and the bits 
    	file.Write( lpbi, GlobalSize(hDIB) );
     
    	file.Close();
     
    	return TRUE;
    	}

  9. #9
    Rédacteur
    Avatar de nico-pyright(c)
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    6 414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 6 414
    Par défaut
    Bon ... ca aussi ca me fait que du noir ... donc, c'est que le problème vient d'avant alors !

    J'obtiens le HBITMAP ainsi à partir du HDC

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    		int k = GetDeviceCaps(hdc,PDEVICESIZE);
    		int width = GetDeviceCaps(hdc, HORZRES);
    		int height = GetDeviceCaps(hdc, VERTRES);
    		HBITMAP hbmp = CreateCompatibleBitmap(hdc, width, height);
    j'ai bon ?

    et ensuite, je convertis en DIB

  10. #10
    Membre chevronné
    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
    Par défaut
    Regarde cette fonction, je l'utilise pour écrire le Contenu d'une Fenêtre(ça peut être une CView, ...) dans un fichier BMP.

    Moi j'utilise GetClientRect (de CWnd) pour récupérer les dimensions, cela-dit ce que tu utilise doit marcher...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
          int width = GetDeviceCaps(hdc, HORZRES);
          int height = GetDeviceCaps(hdc, VERTRES);

    Je ne sais pas ce que tu fait, mais pour récupérer les donnée de ton hdc dans ta bitmap hbmp , mais si tu ne fait pas de BitBlt en passant par un DC mémoire (CF code ci-dessous), c'est peut-être normal que ton image soit noire...


    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
    /*******************************************************************************/
    //WriteWindowToDIB
    //LPTSTR DestFile
    //Pointeur sur un CWnd
    /*******************************************************************************/
    BOOL COutils::WriteWindowToDIB( LPTSTR szFile, CWnd *pWnd )
    	{
    	CBitmap 	bitmap;
    	CWindowDC	dc(pWnd);
    	CDC 		memDC;
    	CRect		rect;
     
    	memDC.CreateCompatibleDC(&dc);
     
    	pWnd->GetWindowRect(rect);
     
    	bitmap.CreateCompatibleBitmap(&dc, rect.Width(),rect.Height() );
     
    	CBitmap* pOldBitmap = memDC.SelectObject(&bitmap);
    	memDC.BitBlt(0, 0, rect.Width(),rect.Height(), &dc, 0, 0, SRCCOPY);
     
    	// Create logical palette if device support a palette
    	CPalette pal;
    	if( dc.GetDeviceCaps(RASTERCAPS) & RC_PALETTE )
    	{
    		UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * 256);
    		LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize];
    		pLP->palVersion = 0x300;
     
    		pLP->palNumEntries = GetSystemPaletteEntries( dc, 0, 255, pLP->palPalEntry );
     
    		// Create the palette
    		pal.CreatePalette( pLP );
     
    		delete[] pLP;
    	}
     
    	memDC.SelectObject(pOldBitmap);
     
    	// Convert the bitmap to a DIB
    	HANDLE hDIB =COutils:: DDBToDIB( bitmap, BI_RGB, &pal );
     
    	if( hDIB == NULL )
    		return FALSE;
     
    	// Write it to file
    	COutils::WriteDIB( szFile, hDIB );
     
    	// Free the memory allocated by DDBToDIB for the DIB
    	GlobalFree( hDIB );
    	return TRUE;
    	}

  11. #11
    Rédacteur
    Avatar de nico-pyright(c)
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    6 414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 6 414
    Par défaut
    en fait, j'ai essayé plein de méthodes ...
    le bitblt, mais l'image était pas fidèle
    aussi CreateDibSection + Bitblt

    Enfin, bref, je verrais ca lundi, merci de ton aide matazz

  12. #12
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Euh.. tu es sûr pour le coup du cast de HBITMAP en BITMAPINFOHEADER * ? C'est sale...

    Sur n'importe quel DIB, un GetObject() suffit pour obtenir un pointeur vers les bits du bitmap...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  13. #13
    Rédacteur
    Avatar de nico-pyright(c)
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    6 414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 6 414
    Par défaut
    Bon, j'ai repris du début ... et bof bof, j'ai semble-t-il tout fait comme il faut, mais le résultat du bitmap est noir !


    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
     
       int width = GetDeviceCaps(hdc, HORZRES);
       int height = GetDeviceCaps(hdc, VERTRES);
       CBitmap    bitmap;
       CDC       memDC;
       CDC * dc = CDC::FromHandle(hdc); // comme j'ai déjà mon DC, j'utilise FromHandle
       memDC.CreateCompatibleDC(dc);
       bitmap.CreateCompatibleBitmap(dc, width, height);
       CBitmap* pOldBitmap = memDC.SelectObject(&bitmap);
       if (!memDC.BitBlt(0, 0, width,height, dc, 0, 0, SRCCOPY))
    	   MessageBox(NULL, "Erreur", "", 0);
     
       // Create logical palette if device support a palette
       // Là, en l'occurence, j'y passe pas, il supporte pas
       CPalette pal;
       if( dc->GetDeviceCaps(RASTERCAPS) & RC_PALETTE )
       {
          UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * 256);
          LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize];
          pLP->palVersion = 0x300;
          pLP->palNumEntries = GetSystemPaletteEntries( dc->m_hDC, 0, 255, pLP->palPalEntry );
          // Create the palette
          pal.CreatePalette( pLP );
          delete[] pLP;
       } 
       memDC.SelectObject(pOldBitmap);
       HANDLE hDIB = DDBToDIB( bitmap, BI_RGB, &pal);
       if( hDIB == NULL )
          return;
       WriteDIB( "monbmp.bmp", hDIB );
       GlobalFree( hDIB );
    J'ai raté un truc ? je me jete par la fenetre ?

  14. #14
    Membre chevronné
    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
    Par défaut
    Citation Envoyé par nico-pyright(c)
    ...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
     ...
       memDC.SelectObject(pOldBitmap);
       HANDLE hDIB = DDBToDIB( bitmap, BI_RGB, &pal);
       if( hDIB == NULL )
          return;
       WriteDIB( "monbmp.bmp", hDIB );
       GlobalFree( hDIB );
    ...
    Normalement ça devrait marcher, mais essaye de re-sélectionner l'ancienne Bitmap après ton DDBToDIB


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
     ...
     
       HANDLE hDIB = DDBToDIB( bitmap, BI_RGB, &pal);
       if( hDIB == NULL )
          return;
       WriteDIB( "monbmp.bmp", hDIB );
       GlobalFree( hDIB );
     memDC.SelectObject(pOldBitmap);

  15. #15
    Rédacteur
    Avatar de nico-pyright(c)
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    6 414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 6 414
    Par défaut
    non, ca ne change absolument rien.

    par contre, le code est bon, car si je crée mon DC
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
       CDC * dc = new CDC();
       dc->CreateDC("DISPLAY", NULL, NULL, NULL);
    à rectification de coordonnées près, et bien le résultat n'est pas du tout noir !

    Cela vient donc j'imagine de mon DC d'origine, pourtant, j'arrive à y dessiner dedans.

    Il est ok pour RC_DI_BITMAP et pour RC_BITBLT, sachant que j'ai oublié de préciser qu'il est de technology DT_RASPRINTER

    :

Discussions similaires

  1. [XL-2007] Envoyer un mail avec outlook à partir d'excel avec des tableaux dans le corps du mail
    Par BarneyYagami dans le forum Macros et VBA Excel
    Réponses: 5
    Dernier message: 15/11/2014, 16h48
  2. Réponses: 6
    Dernier message: 01/03/2006, 14h55
  3. Réponses: 21
    Dernier message: 05/02/2006, 17h37
  4. Tableaux 3*3 à partir d'un 9*9
    Par progfou dans le forum Algorithmes et structures de données
    Réponses: 8
    Dernier message: 02/01/2006, 18h13
  5. [Tableaux] Coloriser un tableau à partir de mon code
    Par pod1978 dans le forum Langage
    Réponses: 3
    Dernier message: 10/11/2005, 16h25

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