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 :

Sauvegarder un tableau 2D en BMP


Sujet :

MFC

  1. #1
    Membre émérite Avatar de homeostasie
    Homme Profil pro
    Inscrit en
    Mai 2005
    Messages
    939
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 939
    Par défaut Sauvegarder un tableau 2D en BMP
    Bonjour,

    Je suis Nicolas, étudiant, dans le cadre d'un projet de traitement d'images je me dois de sauvegarder un tableau 2D en image bmp afin de pouvoir la visualiser. A noter, que j'utilise un tableau de 2D car je travaille en niveau de gris.

    Existe t'il une fonction sous visual c++ qui permette cela ou un moyen de le réaliser?

    Si vous pouvez m'apporter le code nécessaire, il en serait le bienvenue.

    Vous remercie d'avance.

    Nicolas

  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

  3. #3
    Membre émérite Avatar de homeostasie
    Homme Profil pro
    Inscrit en
    Mai 2005
    Messages
    939
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 939
    Par défaut
    Merci pour ces infos, j'ai jeté un coup d'oeil, je crains que ca ne convienne pas.
    A la base, j'ai un tableau 2D contenant la valeur des pixels de l'image. J'aimerais pouvoir enregistrer ce tableau au format BMP en spécifiant le chemin.
    Pensez vous que cela est possible? je me dis que oui.
    En tout cas, je vais me pencher sur le code des pages que vous m'avez fait part.

    Si d'autres personnes connaissent un moyen ou des astuces, elles sont toujours les bienveues.

    Bonne journée

    Nicolas

  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
    oui,
    mais il faudra passer au format BITMAP de Windows (tableau à 1 dimension)

    et après tu pourrat utiliser les liens du post précédent...

    regarde aussi ces posts :

    http://www.developpez.net/forums/vie...tmap+dimension
    http://www.developpez.net/forums/vie...ixel+dimension

  5. #5
    Membre émérite Avatar de homeostasie
    Homme Profil pro
    Inscrit en
    Mai 2005
    Messages
    939
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 939
    Par défaut
    Ben franchement merci pour ces liens. Je vais m'y pencher ce we car là, j'ai la tête qui va exploser...sourire
    En tout cas je pense que ca devrait bien m'aider. Si j'y arrive, je le spécifierais sur le forum.

    Bonne soirée

    Nicolas

  6. #6
    Membre émérite Avatar de homeostasie
    Homme Profil pro
    Inscrit en
    Mai 2005
    Messages
    939
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 939
    Par défaut
    Bonjour,

    Bien, je viens de regarder un code qui à la base permettrait de passer d'un tableau 2D de NG en format bitmap afin d'afficher cette image.
    Le code est le suivant :

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

    J'ai lu quelques explications concernant ce code mais un point clef m'echappe.
    Ou est ce qu'on passe notre tableau 2D comme paramètre?
    Je dirais que l'on doit passer le tableau 2D dans l'instance hdc mais je ne vois pas comment. Si je vois juste, comment fait on? J'avoue n'avoir pas de notion sur le handle, terme que j'ai pu rencontrer plusieurs fois dans mes recherches.

    Sinon, est il possible d'afficher ce tableau 2D par l'utilisation de la fonction setpixel? Enfin je pense que le code du desus semble bien plus performant.

    Merci de votre aide et de vos explications qui sont les bienvenues.

    Nicolas

  7. #7
    Membre émérite Avatar de homeostasie
    Homme Profil pro
    Inscrit en
    Mai 2005
    Messages
    939
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 939
    Par défaut
    en fait, pour vous m'expliquer aussi ce qu'est concretement un handle et toujours p/r à mon précédent message, comment fait on pour transmettre le tableau 2D?

    Merci

    Nicolas

  8. #8
    Membre émérite Avatar de homeostasie
    Homme Profil pro
    Inscrit en
    Mai 2005
    Messages
    939
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 939
    Par défaut
    Bonjour,

    Désolé d'insister, j'ai beau faire des recherches, c'est surement pas très compliqué mais je ne vois toujours pas ou est ce qu'on charge les pixels de l'image à afficher?
    Pour moi, GetPixels(hdc,j,i) permet justement de récupérer la valeur du pixel du tableau 2D avec i et j représentant respectivement la ligne e tla colonne. Par contre si c'est bien cela, comment fait on pour associer le tableau au hdc?
    Je suis un peu perdu on va dire...

    Merci

    Bonne journée

    Nicolas

  9. #9
    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
    Ce code transforme un CDC couleur(BITMAT Windows 1D) en CDC Noir et blanc.

    il faut que tu remplace
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    couleur = GetPixels(hdc,j,i);
    par :
    par contre si ton tableau est en niveau de gris, tu n'as pas besoin de cette formule :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    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));

  10. #10
    Membre émérite Avatar de homeostasie
    Homme Profil pro
    Inscrit en
    Mai 2005
    Messages
    939
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 939
    Par défaut
    Merci pour ces renseignements, je vais mettre cela au point. Par contre, en attendant d'avoir votre message, j'ai utilisé le fonction setpixel pour afficher mon tableau en niveau de gris. Comment se fait il que l'image apparait plutot en dégradé de rouge?
    Il doit surement y avoir une conversion à faire.
    Je vous tiens au courant pour la mise en place de l'autre méthode car avec setpixel, il est clair que l'on voit apparaître un temps de chargement des pixels.

    Merci

    Nicolas

  11. #11
    Membre émérite Avatar de homeostasie
    Homme Profil pro
    Inscrit en
    Mai 2005
    Messages
    939
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 939
    Par défaut
    Re bonjour,

    Donc je viens de faire les modif avec la fonction SetDibitstodevice. Tout d'abord ca fonctionne, j'obtiens bien mon image en niveau de gris mais un petit problème néanmois embetant, mon image est à l'envers p/r à l'originale?!
    Surement que la fonction part de la fin pour afficher l'image alors je cherche ou est ce qu'iul faut changer cela.
    A tout hasard, voici a nouveau le code :

    int i, j;
    CImage Image = pDoc->ReturnImage();

    int k = 0;
    int ht = Image.Lig(), wh = Image.Col();

    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++)
    {
    int lum = Image(i,j);
    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);

  12. #12
    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
    le bitmap windows sont stockée de bas en haut...
    Inverse ta boucle sur les Y

  13. #13
    Membre émérite Avatar de homeostasie
    Homme Profil pro
    Inscrit en
    Mai 2005
    Messages
    939
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 939
    Par défaut
    merci ca fonctionne, juste pour ceux que ca interesserait voici la modification de la ligne :

    for(i=bmi.bmiHeader.biHeight-1;i>=0;i--)

    En tout cas, thanks pour votre aide "matazz" et bonne journée.

    Nicolas

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

Discussions similaires

  1. Réponses: 8
    Dernier message: 13/05/2009, 11h00
  2. sauvegarder un tableau dans un fichier
    Par jonezy0621 dans le forum Débuter
    Réponses: 9
    Dernier message: 14/03/2009, 01h37
  3. Sauvegarder un tableau
    Par El-Diablo- dans le forum C++Builder
    Réponses: 5
    Dernier message: 12/10/2007, 11h25
  4. Réponses: 11
    Dernier message: 18/04/2007, 17h39
  5. Comment sauvegarder un tableau
    Par Aurore_atmo dans le forum MATLAB
    Réponses: 5
    Dernier message: 13/07/2006, 11h17

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