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

wxWidgets Discussion :

Créer une wxBitmap depuis des données


Sujet :

wxWidgets

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    268
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 268
    Points : 393
    Points
    393
    Par défaut Créer une wxBitmap depuis des données
    Bonjour,

    Ceci est mon 1er message sur le forum, donc je vais essayer de faire ça dans les règles.

    Comme l'indique le titre, je dispose d'un tableau d'entiers (contenant des valeurs des pixels). Je souhaite créer une wxBitmap depuis ce tableau, afin de l'inclure plus tard dans une liste (wxListCtrl).

    J'ai naturellement essayé la méthode :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    wxBitmap(const void* data, int type, int width, int height, int depth = -1)
    en remplaçant data par mon tableau. Toutefois il faut spécifier un type (d'ailleurs je ne vois pas l'utilité du type vu que l'on construit la bitmap depuis des données menfin...), j'ai donc mis wxBITMAP_TYPE_PNG après avoir charger le handler correspondant.

    voila le code qui me donne une erreur de type : wxDIB::Create() : invalid 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
    wxBitmap
    Frame::drawBitmap(Image* img, int max)
    {
    	int width = img->getWidth();
    	int height = img->getHeight();
    	int* data = new int[width*height];
     
    	for(int i = 0; i < width*height; i++)
    		data[i] = img->getData(i) * NDG / max;
     
    	wxBitmap bitmap(data, wxBITMAP_TYPE_PNG, width, height);
            bitmap.SetWidth(100);
    	bitmap.SetHeight(100);
    	return bitmap;
    }

    A noter que :
    - width et height sont bien récupérés.
    - data contient des données correctes
    - ne pas s'occuper de NDG et Image* ce sont des types définis par mes soins qui n'interviennent pas dans l'erreur générée
    - l'erreur semble provenir d'un appel a wxImage::ConvertToImage , surement à la suite du SetWidth() et SetHeight(), j'ai essayé de remplacer par un ConvertToImage suivi d'un scale, mais même erreur.


    Donc la question demeure : comment créer une wxBitmap depuis un tableau d'entiers ? Ce ne doit pas être la mort quand même...

    Merci de votre attention.

  2. #2
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Salut et bienvenu,
    Si on n'en croit la doc, tu devrais utiliser wxImage plutôt que wxBitmap.
    Ensuite, au lieu d'allouer ton tableau, tu peux utiliser wxImage::SetRGB pour positionner tes pixels :
    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
     
    wxBitmap
    Frame::drawBitmap(Image* img, int max)
    {
    	int width = img->getWidth();
    	int height = img->getHeight();
            wxImage image(width,height);
     
    	for(int i = 0; i < height; i++){
      	   for(int j = 0; j < width; i++){
    		 image.SetRGB(j,i,
                        RED(img->getData(i*width + j) * NDG / max),
                        GREEN(img->getData(i*width + j) * NDG / max),
                        BLUE(img->getData(i*width + j) * NDG / max)
            }
     
    	return wxBitmap(image);
    }
    RED/GREEN/BLUE convertisse ta donnée vers un unsigned char de la bonne valeur.

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    268
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 268
    Points : 393
    Points
    393
    Par défaut
    Merci pour cette méthode qui permet d'éviter une allocation mémoire.

    Toutefois les macros RED GREEN et BLUE ne sont pas reconnus chez moi, ou alors il faut que les définisse c'est ca ?

    Dans ce cas là, commet passer efficacement d'un int (32 bits) à un unsigned char .... je ne vois pas trop..?

    atm0.


    Edit : j'ai testé sans les "RED GREEN BLUE", plus d'erreur d'execution, par contre la conversion int -> unsigned char semble avoir fait des ravages (mes images sont dégueu). Je le répète, mes pixels (contenus dans ma structure Image) sont biens récupérés. Si jamais tu as une idée..

  4. #4
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par atm0sfe4r Voir le message
    Merci pour cette méthode qui permet d'éviter une allocation mémoire.

    Toutefois les macros RED GREEN et BLUE ne sont pas reconnus chez moi, ou alors il faut que les définisse c'est ca ?

    Dans ce cas là, commet passer efficacement d'un int (32 bits) à un unsigned char .... je ne vois pas trop..?
    Effectivement, RED, GREEN et BLUE c'est à toi de les définir.

    Citation Envoyé par atm0sfe4r Voir le message
    Edit : j'ai testé sans les "RED GREEN BLUE", plus d'erreur d'execution, par contre la conversion int -> unsigned char semble avoir fait des ravages (mes images sont dégueu). Je le répète, mes pixels (contenus dans ma structure Image) sont biens récupérés. Si jamais tu as une idée..
    Ben oui, car tu es probablement sur une plateforme x86 -> problème d'endian qui fait que toutes tes couleurs sont inversées

    Si ton truc est à peu près standard, les macros devraient ressembler à :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    #define RED(rgb)      (static_cast<unsigned char>(rgb))
    #define GREEN(rgb)      (static_cast<unsigned char>((rgb) >> 8))
    #define BLUE(rgb)      (static_cast<unsigned char>((rgb)>>16))
    // et si besoin alpha :
    #define ALPHA(rgb) (static_cast<unsigned char>((rgb)>>24))

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    268
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 268
    Points : 393
    Points
    393
    Par défaut
    Je viens de tester ces macros après avoir compris le décalage de bits, toutefois cela ne résout pas le problème de la perte de données, car en convertissant un int en unsigned char il ya perte de données on est d'accord ?

    Ou alors j'ai rien compris à l'opérateur >> ...

    Pour info je récupère des images possédant 4096 niveaux de gris ce qui explique la quantification par :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    img->getData(i*width + j) * NDG / max  /*NDG = 255*/
    Je le rappelle img->getData(i*width + j) contient des entiers 32 bits.

    Et je suis sous plateforme x64 il me semble ! (AMD athlon 64 dual-core 3800+ , WinXP media center sp3 pour entreprises).

    Merci.

  6. #6
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Globalement, l'idée est de récupérer les valeurs Rouge, Vert et Bleu de ton int du pixel et de le transformer dans le unsigned char qui va bien pour l'interface de wxImage.

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    268
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 268
    Points : 393
    Points
    393
    Par défaut
    Citation Envoyé par 3DArchi Voir le message
    Globalement, l'idée est de récupérer les valeurs Rouge, Vert et Bleu de ton int du pixel et de le transformer dans le unsigned char qui va bien pour l'interface de wxImage.
    On est d'accord, c'est bien ça l'idée, et de toute façon c'est la seule solution pour intégrer mes int dans la wxImage...

    Mais comment faire ça efficacement? Ce que je veut dire c'est qu'il y aura automatiquement perte de données lors du passage int -> unsigned char, et j'ai peur qu'il n'y ai aucun moyen d'éviter cette perte de données.
    Qu'en penses-tu? Je ne pense pas être le seul dans ce cas-là...

    Merci.

  8. #8
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par atm0sfe4r Voir le message
    Ce que je veut dire c'est qu'il y aura automatiquement perte de données lors du passage int -> unsigned char
    Normalement non, car tu positionnes 3 (en fait 4, car le dernier c'est l'alpha pour la transparence) unsigned char, un pour chaque canal de couleur (ça devrait largement suffire à gérer les 4096 niveaux de gris).

    Que contient img[i] ? Un index sur une palette de gris ? Un RGB ? En gros, que signifie un int dans img par rapport au pixel?

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    268
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 268
    Points : 393
    Points
    393
    Par défaut
    Citation Envoyé par 3DArchi Voir le message
    Que contient img[i] ? Un index sur une palette de gris ? Un RGB ? En gros, que signifie un int dans img par rapport au pixel?
    img[i] contient les niveaux de gris tels qu'ils sont présents dans les images que je charge (images DICOM). Ce sont donc des entiers.

  10. #10
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Je ne connais pas le format DICOM.
    Niveau de gris, ça ne veut rien dire. En gros, tu as deux façon de coder les couleurs d'un pixel dans une image : soit tu mets explicitement les valeurs de rouge vert et bleu pour un pixel, soit tu utilises une palette et chaque pixel contient un indice sur cette palette. La question qui se pose est :
    img[i] : représente un indice sur une palette ?
    img[i] : représente une couleur RGB ?
    img[i] : représente un seul canal de couleur ?

  11. #11
    Membre averti
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    268
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 268
    Points : 393
    Points
    393
    Par défaut
    Citation Envoyé par 3DArchi Voir le message
    Je ne connais pas le format DICOM.
    Niveau de gris, ça ne veut rien dire. En gros, tu as deux façon de coder les couleurs d'un pixel dans une image : soit tu mets explicitement les valeurs de rouge vert et bleu pour un pixel, soit tu utilises une palette et chaque pixel contient un indice sur cette palette. La question qui se pose est :
    img[i] : représente un indice sur une palette ?
    img[i] : représente une couleur RGB ?
    img[i] : représente un seul canal de couleur ?
    Un indice sur une palette. De toute manière, je passe le post en résolu puisque je récupère mal les pixels dès le départ (chargement d'une image DICOM).

    Merci pour ton aide, bon travail !

  12. #12
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    A ce moment, les macros RED/GREEN/BLUE ne sont pas à appliquer sur l'indice mais sur l'entrée de la palette.
    Bon courage.

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

Discussions similaires

  1. Réponses: 0
    Dernier message: 07/11/2013, 15h39
  2. [Débutant] Créer un graphique à partir des données d'une combobox
    Par Rockafeller dans le forum VB.NET
    Réponses: 0
    Dernier message: 20/10/2013, 00h22
  3. [Débutant] Impossible de créer une nouvelle base de donnée SQL Server depuis l'EDI de VS2010
    Par sylvebarbe78 dans le forum Visual Studio
    Réponses: 1
    Dernier message: 18/01/2013, 16h05
  4. [XL-2003] Créer une constante depuis des cellules
    Par MiXinG dans le forum Macros et VBA Excel
    Réponses: 8
    Dernier message: 18/05/2009, 10h54
  5. Réponses: 1
    Dernier message: 31/01/2008, 09h08

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