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

Windows Discussion :

Bitmap et HBITMAP


Sujet :

Windows

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Mars 2007
    Messages
    38
    Détails du profil
    Informations personnelles :
    Âge : 51

    Informations forums :
    Inscription : Mars 2007
    Messages : 38
    Par défaut Bitmap et HBITMAP
    Bonjour,

    Je travaille actuellement sur les bitmaps en C et API Windows.

    Je cherche à obtenir le tableau de pixels (RGB) à partir du handle (HBITMAP) et inversement.

    Mais mon code me génère des scans lines noires !!! Comment puis-je résoudre ce problème ?

    Voici mon code atuel :

    + Pour obtenir le tableau a partir du HBITMAP :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    start = 0;
    for (ligne = 0; ligne < height; ligne++)
    {
    retour = SetDIBits(hDC, hBitmap, ligne, 1, &lpBits[start], 
    (BITMAPINFO *)&pBitmap->Entete2, DIB_RGB_COLORS);
    start += width*sizeof(TCouleur)+alignement;
    }
    + Pour obtenir le HBITMAP a partir du tableau :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    start = 0;
    for (ligne = 0; ligne < height; ligne++)
    {
    GetDIBits(hDC, hBitmap, ligne, 1, &lpBits[start], 
    (BITMAPINFO *)&pBitmap->Entete2, DIB_RGB_COLORS);
     
    memcpy(&pBitmap->pixels[ligne*width], &lpBits[start], 
    width*sizeof(TCouleur));
     
    start += width*sizeof(TCouleur)+alignement;
    }
    Ou est mon erreur ? Je sèche depuis 2 jours !!!

    Merci d'avance de votre aide.
    Ywan

  2. #2
    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
    Déjà, c'est bizarre, il me semblait que GetDIBits() servait à extraire les pixels du HBITMAP, et SetDIBits() à les injecter...

    Et au passage, tu peux jeter un coup d'oeil à cet exemple de code :
    Storing an Image
    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.

  3. #3
    Membre averti
    Inscrit en
    Mars 2007
    Messages
    38
    Détails du profil
    Informations personnelles :
    Âge : 51

    Informations forums :
    Inscription : Mars 2007
    Messages : 38
    Par défaut
    Merci de m'avoir repondu ... c'est la premiere fopis que j'utilise un forum pour debugger un programme.

    J'ai regardé avec attention le code sue tu m'as conseillé pour stocker un bitmap. De mon côté mes algos pour créer mon tableau de bitmap sont okay car je peux les stocker dans un fichier .bmp sans problème, seulement je voudrais fournir une dll qui passe par des handle et non des fichiers aussi je cherche a transformer mon array en HBITMAP et effectivement j'ai utilisé SetDIBits et GetDIBits mais il m'insere des lignes noires RGB = (0,0,0).

    + Voici donc mon code pour chharger le bitmap a partir du handle :

    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
    55
    56
    57
    58
    59
    60
    61
    62
    63
    void LOAD_BITMAP_FROM_HANDLE (HBITMAP hBitmap, TBitmap * pBitmap)
    {
       BITMAP  bitmap;
     	HDC hDC;
       long int size, width, height, start;
       int ligne, reste, alignement;
       UCHAR * lpBits;
    
       GetObject(hBitmap, sizeof(BITMAP), (LPVOID)&bitmap);
    	width = bitmap.bmWidth;
       height = bitmap.bmHeight;
       size = width*height;
    
       reste = (width*sizeof(TCouleur))%4;
       if (reste > 0)
       {
          alignement = 4-reste;
       }
       else
       {
       	alignement = 0;
       }
    
       pBitmap->Entete1.bfType = 19778; 
       pBitmap->Entete1.bfSize = sizeof (BITMAPFILEHEADER) + sizeof (BITMAPINFOHEADER) + size*sizeof(TCouleur);
       pBitmap->Entete1.bfReserved1 = 0;     // Toujours zero pour les Bitmaps
       pBitmap->Entete1.bfReserved2 = 0;
       pBitmap->Entete1.bfOffBits = sizeof (BITMAPINFOHEADER) + sizeof(BITMAPFILEHEADER);
       pBitmap->Entete2.biSize = sizeof (BITMAPINFOHEADER);
       pBitmap->Entete2.biWidth = width;
       pBitmap->Entete2.biHeight = height;
       pBitmap->Entete2.biPlanes = 1;
       pBitmap->Entete2.biBitCount = 24;  //Codage sur 3 octets (24bits) de la couleur
       pBitmap->Entete2.biCompression = BI_RGB;
       pBitmap->Entete2.biSizeImage = (width*sizeof(TCouleur)+alignement)*height;
       pBitmap->Entete2.biXPelsPerMeter = 0;
       pBitmap->Entete2.biYPelsPerMeter = 0;
       pBitmap->Entete2.biClrUsed = 0;
       pBitmap->Entete2.biClrImportant = 0;
    
       pBitmap->pixels = (TCouleur *) malloc (size*sizeof(TCouleur));
    
       lpBits = (UCHAR *)malloc(height*(width*sizeof(TCouleur)+alignement)*sizeof(UCHAR));
    
    
       hDC = GetDC(NULL);
    
       start = 0;
       for (ligne = 0; ligne < height; ligne++)
       {
    		GetDIBits(hDC, hBitmap, ligne, 1, &lpBits[start], (BITMAPINFO *)&pBitmap->Entete2, DIB_RGB_COLORS);
    
          memcpy(&pBitmap->pixels[ligne*width], &lpBits[start], width*sizeof(TCouleur));
    
          start += width*sizeof(TCouleur)+alignement;
       }
    
    	ReleaseDC(NULL, hDC);
       DeleteDC(hDC);
    
       free(lpBits);
    
    }
    + et mon code pour creer le handle a partir du bitmap :

    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
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    HBITMAP CREATE_HANDLE_FROM_BITMAP(TBitmap * pBitmap)
    {
    	HBITMAP hBitmap;
       HDC hDC;
    
       long width, height, start, retour;
    
       int ligne, reste, alignement;
       static int ret;
       char car[4] = {0, 0, 0, 0};
       UCHAR * lpBits;
    
    	width = pBitmap->Entete2.biWidth;
       height = pBitmap->Entete2.biHeight;
    
       reste = (width*sizeof(TCouleur))%4;
       if (reste > 0)
       {
          alignement = 4-reste;
       }
       else
       {
       	alignement = 0;
       }
    
       lpBits = (UCHAR *)malloc(height*(width*sizeof(TCouleur)+alignement)*sizeof(UCHAR));
    
       start = 0;
       for (ligne = 0; ligne < height; ligne++)
       {
    		memcpy(&lpBits[start], &pBitmap->pixels[ligne*width], width*sizeof(TCouleur));
          memcpy(&lpBits[start+width*sizeof(TCouleur)], car, alignement*sizeof(UCHAR));
          start += width*sizeof(TCouleur)+alignement;
       }
    
       hDC = GetDC(NULL);
       hBitmap = CreateCompatibleBitmap(hDC, width, height);
    
       start = 0;
       for (ligne = 0; ligne < height; ligne++)
       {
    		retour = SetDIBits(hDC, hBitmap, ligne, 1, &lpBits[start], (BITMAPINFO *)&pBitmap->Entete2, DIB_RGB_COLORS);
          /*
          if (retour == 0)
          {
             LPVOID lpMsgBuf;
    
             FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
                           NULL,
                           GetLastError(),
                           MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
                           (LPTSTR) &lpMsgBuf,
                           0,
                           NULL);
    
             MessageBox( NULL, (char *)lpMsgBuf, "GetLastError", MB_OK|MB_ICONINFORMATION );
             LocalFree( lpMsgBuf );
          }
          */
          start += width*sizeof(TCouleur)+alignement;
       }
    
       ReleaseDC(NULL,hDC);
       DeleteDC (hDC);
    
       //free(lpBits);
    
    	return hBitmap;
    }
    Merci d'avance de passer un peu de temps sur mon program,
    Ywan.

  4. #4
    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

    Pourquoi utiliser un BITMAPFILEHEADER ? Je ne vois pas où tu as besoin d'un fichier.bmp...

    PS: TBitmap, c'est un truc de Borland, ou une classe à toi ? (quand je vois TCouleur, je me pose la question...
    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.

  5. #5
    Membre averti
    Inscrit en
    Mars 2007
    Messages
    38
    Détails du profil
    Informations personnelles :
    Âge : 51

    Informations forums :
    Inscription : Mars 2007
    Messages : 38
    Par défaut
    TBitmap et TCouleur sont des structures perso ... mais elles respectent le standard bmp :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    typedef struct SCouleur
    {
     unsigned char Rouge,Vert,Bleu;
    } TCouleur;
    
    typedef struct SBitmap
    {
    	BITMAPFILEHEADER Entete1;
    	BITMAPINFOHEADER Entete2;
    	TCouleur * pixels;
    } TBitmap;
    aussi Entete2 est du type BITMAPINFO (Microsoft).

    Ywan

  6. #6
    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
    C'est le standard bmp seulement pour 24 ou 32 bits.
    Et plutôt que TCouleur, tu devrais utiliser directement des structures RGBQUAD (bitmap 32 bits uniquement dans les deux cas).

    Mais tu ne devrais pas avoir besoin de BITMAPFILEHEADER pour un bitmap en mémoire. BITMAPFILEHEADER, comme son nom l'indique, c'est pour les fichiers.
    La fonction CreateDIBSection() n'a besoin que d'une BITMAPINFO pour fonctionner...
    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.

  7. #7
    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
    Je n'ai pas vraiment eu le temps d'examiner le code en détail, mais quelques remarques sur la forme:
    1. Le code ASCII des lettres B et M "en hexa", écris-le véritablement en hexa (0x4D42).
    2. Si les noms des fonctions ne sont pas imposés, plutôt que CREATE_, tu devrais les nommer comme des fonctions de conversion: BITMAP_XXX_FROM_YYY() avec XXX et YYY pouvant être HANDLE, FILE ou STRUCT...
    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.

  8. #8
    Membre averti
    Inscrit en
    Mars 2007
    Messages
    38
    Détails du profil
    Informations personnelles :
    Âge : 51

    Informations forums :
    Inscription : Mars 2007
    Messages : 38
    Par défaut
    Okay, merci encore.

    Ywan
    (http://ywan.lesoeur.free.fr)

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

Discussions similaires

  1. sauvegarder un HBITMAP ou BITMAP
    Par s0ak68 dans le forum Débuter
    Réponses: 0
    Dernier message: 31/03/2009, 20h34
  2. Bitmap en niveau de Gris / Dll -> HBitMap
    Par thonydesbois dans le forum VB 6 et antérieur
    Réponses: 10
    Dernier message: 20/07/2006, 15h34
  3. Pb Lecture de bitmap monochrome
    Par Loïc38 dans le forum C++Builder
    Réponses: 4
    Dernier message: 02/07/2002, 18h24
  4. Lecture d'une image bitmap
    Par Geronimo dans le forum x86 32-bits / 64-bits
    Réponses: 18
    Dernier message: 28/06/2002, 12h01
  5. Comment faire pour créer un bitmap
    Par GliGli dans le forum C++Builder
    Réponses: 2
    Dernier message: 24/04/2002, 15h41

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