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

C++Builder Discussion :

problème avec procédure ayant TImage comme parametre


Sujet :

C++Builder

  1. #1
    Membre émérite Avatar de b_reda31
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2007
    Messages
    899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Algérie

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2007
    Messages : 899
    Par défaut problème avec procédure ayant TImage comme parametre
    Bonjour à vous tous,
    Je suis actuellement entrain de réaliser une petit logiciel sur le traitement d’image,Je ne travaille qu’avec des Image BMP 24 bits (pf24bit) et de niveau de gris.
    Afin de minimiser le nombre d’appels des méthodes ScanLine et Canvas->Pixels,J’ai choisi de charger l’image du TImage vers une matrice (Byte mat[3000][3000]), et après avoir effectuer les traitement sur la matrice transférer les données de la matrice vers un autre TImage,et pour cela j’ai crée deux procédures (Grace à Henderson) dont voici les prototypes :

    void ImageToMatrice(TImage *img,byte mat[3000][3000])

    void MatriceToImage(TImage *img,byte mat[3000][3000])



    La première procédure remplit la matrice à partir de l’image qu’a chargé l’utilisateur dans un TImage (Tout en la transformant en niveau de gris)

    La deuxième procédure transfert le contenu de la matrice vers un TImage .
    Voici leurs codes :

    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
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    void ImageToMatrice(TImage *img,byte mat[3000][3000])
    
    
    {
    
    
    class jPixel
    {
    public :
    Byte Blue;
    Byte Green;
    Byte Red;
    };
    Graphics::TBitmap *Bitmap = new Graphics::TBitmap;
    
    
    
    
    jPixel *Pixel;
    
    int grey, blue, red, green;
    
    Graphics::TBitmap *B = img->Picture->Bitmap;
    
    
        for(int y = 0; y < B->Height; y++)
            {
            Pixel = (jPixel*)B->ScanLine[y];
            for(int x = 0; x < B->Width; x++)
                {
    
                grey = (Pixel[x].Red+
                        Pixel[x].Green+
                        Pixel[x].Blue) /3;
    
                 mat[x][y]=grey;
    }
            }
        img->Repaint();
    
    }
    
    
    
    void MatriceToImage(TImage *img,byte mat[3000][3000])
    {
    
    
    
    class jPixel
    {
    public :
    Byte Blue;
    Byte Green;
    Byte Red;
    };
    Graphics::TBitmap *Bitmap = new Graphics::TBitmap;
    jPixel *Pixel;
    
    int grey, blue, red, green;
    Graphics::TBitmap *B ;
    
    B=img->Picture->Bitmap;
    
    
        for(int y = 0; y < B->Height; y++)
            {
            Pixel = (jPixel*)B->ScanLine[y];
            for(int x = 0; x < B->Width; x++)
                {
    
                Pixel[x].Red=mat[x][y];
                Pixel[x].Green=mat[x][y];
                Pixel[x].Blue=mat[x][y];
    
    
    
    
    
                 }
            }
    
    
    
    
        img->Repaint();
    
    
    }

    Maintenant afin de tester ces deux procédures,j’ai déposé dans ma forme deux TImage Image1,Image2 et un bouton.Image1 contient une BMP et Image2 est vide (Invisible à l’exécution) .
    A l’événement OnClick du bouton voici ce que j’ai mis :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    ImageToMatrice(Image1,matrice) ;
     
    //….
    //TRAITEMENT
    //…
     
    MatriceToImage(Image1,matrice) ;
    Là pas de soucis tout s’effectue très bien,Mais si je voulais garder l’image originale et afficher le résultat dans Image2 de cette manière :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
     
    ImageToMatrice(Image1,matrice) ;
     
    //….
    //TRAITEMENT
    //…
     
    MatriceToImage(Image2,matrice) ;

    Là rien ne s’affiche dans Image2 .Et c’est du faite qu’elle ne contienne pas de BMP initialement je pense

    Vous me diriez peut être que le problème sera résolu en ajoutant l’instruction

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Image2->Picture->Bitmap=Image1->Picture->Bitmap ;  
    Juste avant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MatriceToImage(Image2,matrice) ;  

    Et c’est le cas !mais je ne veux pas être contraint d’ajouter cette instruction à chaque fois car je voudrai faire appel à ces procédures depuis plusieurs projets.
    Quelqu’un aurai une idée ?

    Merci à vous de votre patience.
    N’hésiter pas à me demander quoi que ce soit si je n’ai pas été clair sur certains points.

    Cordialement.

  2. #2
    Membre éclairé Avatar de Baxter67
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    270
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 270
    Par défaut
    le autosize de ton image 2 est bien a true ?

  3. #3
    Membre émérite Avatar de b_reda31
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2007
    Messages
    899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Algérie

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2007
    Messages : 899
    Par défaut
    Citation Envoyé par Baxter67 Voir le message
    le autosize de ton image 2 est bien a true ?
    Je viens de le mettre à True et le problème persiste!



    Je vais essayer de résumer un peu mon problème:
    dans ma forme je dispose d'un TImage qui ne contient pas de BMP (IL EST VIDE)Donc invisible.
    Et je voudrai lorsque l'utilisateur presse sur un bouton le TImage se charge à partir d'une matrice (La procédure est dèja implémentée).
    Si le TImage contenait initialement un BMP la matrice s'affiche bien.Mais si le TImage est vide alors l appel de ma procédure ne fait rien!

  4. #4
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    1 407
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 407
    Par défaut
    Salut !

    Le bon code est :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Image2->Picture->Bitmap->Assign(Image1->Picture->Bitmap);
    Par contre... ton histoire de matrice... ???

    Ce ne serait pas plus simple de traiter de bitmap à bitmap au lieu de passer par cette matrice ?

    Que te manque t-il ? Un bitmap 8 bits référentiel à niveaux de gris pour représenter le résultat du traitement ?

    A plus !

  5. #5
    Membre émérite Avatar de b_reda31
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2007
    Messages
    899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Algérie

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2007
    Messages : 899
    Par défaut
    Citation Envoyé par henderson Voir le message
    Salut !

    Le bon code est :


    Image2->Picture->Bitmap->Assign(Image1->Picture->Bitmap);
    Je ne veux pas afficher Image1 dans Image2 mais plutôt la matrice dans Image2.
    Voici un petit schéma qui résume ce que je veux faire:

    Tous s’effectue très bien jusqu’à l’affichage de la matrice après traitement (Procédure MatriceToImage).Ici si j’affiche la matrice dans Image1 y a pas de soucis l’image traitée s’affiche bien. MAIS si je veux garder l’image originale dans Image1 et afficher l’image traitée dans Image2, là rien de s’affiche car Image2 est initialement vide !



    Envoyé par Henderson :
    Par contre... ton histoire de matrice... ???

    Ce ne serait pas plus simple de traiter de bitmap à bitmap au lieu de passer par cette matrice ?

    Pour le "traitement",Il m'est beaucoup plus facile de travailler avec une matrice au lieu d'utiliser les méthode Canvas->Pixels et ScanLine.


    Envoyé par Henderson :
    Que te manque t-il ? Un bitmap 8 bits référentiel à niveaux de gris pour représenter le résultat du traitement ?
    Je ne comprends pas cette question.
    Je travaille qu’avec des Image 24Bits de niveau de gris,et si éventuellement l’utilisateur charge une image RGB c’est la procédure ImageToMatrice qui convertira cette Image en niveau de gris.(Dans la matrice)

  6. #6
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    1 407
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 407
    Par défaut
    Salut !

    Si Image2 est vide il faut bien lui assigner un bitmap donc tant qu'à faire on lui assigne un bitmap existant, celui de Image1 (si c'est le même type de bitmap...)!

    Si je parts du principe que :
    - l'image initiale est en 24 bit couleurs
    - l'image initiale est convertie ... et sortie en niveaux de gris (8 bit)
    Je n'ai besoin que d'un bitmap 8 bits en sortie, parce que ça ne sert à rien de mémoriser 3 composantes identiques !
    Comme on est ici dans du référentiel de gris (0 = noir ... 255 = blanc) à cause du traitement, on a intéret à charger Image2 avec un bitmap à niveaux de gris.
    J'ai donné du code en ce sens :

    http://www.developpez.net/forums/sho...d.php?t=544165

    Il est possible de matricer les lignes du bitmap retournées par ScanLine.

    Voici un exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    class jPixel
    {
    public :
    Byte Blue;
    Byte Green;
    Byte Red;
    };
    En global :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    Byte **Dest_Matrice = NULL;
    jPixel **Srce_Matrice = NULL;
    Pour te faire plaisir, on va matricer les deux bitmaps, convertir en niveaux de gris et afficher...

    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
     
    void __fastcall TForm1::SpeedButton1Click(TObject *Sender)
    {
    Graphics::TBitmap *Srce = Image1->Picture->Bitmap;
    Graphics::TBitmap *Dest = Image2->Picture->Bitmap;
    int we = Srce->Width;
    int he = Srce->Height;
    Dest->Width = we;
    Dest->Height = he;
     
    //Matriçage du bitmap Srce
    if(Srce_Matrice != NULL) delete [] Srce_Matrice;
    Srce_Matrice = new jPixel*[he];
    for(int j = 0; j < he; j++) Srce_Matrice[j] = (jPixel*)Srce->ScanLine[j];
     
    //Matriçage du bitmap Dest
    if(Dest_Matrice != NULL) delete [] Dest_Matrice;
    Dest_Matrice = new Byte*[he];
    for(int j = 0; j < he; j++) Dest_Matrice[j] = (Byte*)Dest->ScanLine[j];
     
    /**************************************************************
    A ce stade, les adresses des lignes resteront valides tant que 
    l'on aura pas touché aux propriétés du bitmap qui viendraient 
    modifier ses dimensions (ca vaut aussi pour PixelFormat) !!! !!!
    ***************************************************************/
     
    //Conversion en niveau de gris de Image1 vers Image2
    //Et comme tu aimes bien les matrices...
     
    for(int y = 0; y < he; y++)
        {
        for(int x = 0; x < we; x++)
            {
            Dest_Matrice[y][x] = (Byte)((Srce_Matrice[y][x].Blue +
                                         Srce_Matrice[y][x].Green +
                                         Srce_Matrice[y][x].Red) / 3);
            }
        }
     
    //On peut, a la suite de ça, lisser... ou effectuer d'autres traitements...
     
    //Et on termine avec :
    Image2->Repaint();
    }
    Ne pas oublier de quitter l'application en faisant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
    {
    if(Dest_Matrice != NULL) delete [] Dest_Matrice;
    if(Srce_Matrice != NULL) delete [] Srce_Matrice;
    }
    A plus !

  7. #7
    Membre émérite Avatar de b_reda31
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2007
    Messages
    899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Algérie

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2007
    Messages : 899
    Par défaut
    Merci infiniment pour votre patience et votre aide Henderson.

    Envoyé par Henderson

    ...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    //Et comme tu aimes bien les matrices...
    ...

    A vrai dire,il n y a rien entre moi et les matrices je vous l'assure ...c'est juste que Canvas->Pixels est très longue à l'éxécution.Et je ne maitrise pas très bien ScanLine,la notion de pointeur ici me parait encore un peu vague...Mais j y vois de plus en plus clair grâce à vous.
    Merci encore.

  8. #8
    Membre émérite Avatar de b_reda31
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2007
    Messages
    899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Algérie

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2007
    Messages : 899
    Par défaut Modifier la taille de l'image
    Mon problème est résolu grâce à ce code:

    Envoyé par henderson
    Salut !

    Le bon code est :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Image2->Picture->Bitmap->Assign(Image1->Picture->Bitmap);

    Mais là un autre problème est survenu,Pour résumer un peu voila comment je procède:


    -Charger Image1 (TImage) dans une matrice.(Procédure ImageToMatrice)

    -Effectuer les traitements sur la matrice.

    -Afficher la matrice dans Image2(TImage) avec la procédure MatriceToImage.




    Et parmi les "traitements" y en a un qui consiste à modifier la taille de l'image.Hélas les proptiétés :

    Image2->Picture->Width
    Image2->Picture->Height


    ne sont pas accèssibles (on ne peut les modifier).

    Le problème survient donc lors de l'affichage dans Image2,le traitement s'effectue bien mais la taille de l'image reste inchangée !

  9. #9
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    1 407
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 407
    Par défaut
    Salut !

    Tout simplement parce qu'on a deux objets distincts avec leur propres dimensions :
    - celles du bitmap (dimensions réelles de l'image)
    - celles du TImage (dimensions de la lucarne dans laquelle se dessine son bitmap)

    Si on fixe Image2->AutoSize à true on oblige Image2 à aligner ses dimensions sur celles de son bitmap, celles qui en définitive sont induites par Assign (puisque l'on effectue une copie physique du bitmap).

    A plus !

  10. #10
    Membre émérite Avatar de b_reda31
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2007
    Messages
    899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Algérie

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2007
    Messages : 899
    Par défaut
    Donc il est impossible de charger une matrice dont la taille est "variable" dans un TImage?

  11. #11
    Membre émérite Avatar de b_reda31
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2007
    Messages
    899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Algérie

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2007
    Messages : 899
    Par défaut
    Citation Envoyé par henderson Voir le message
    Salut !

    Tout simplement parce qu'on a deux objets distincts avec leur propres dimensions :
    - celles du bitmap (dimensions réelles de l'image)
    - celles du TImage (dimensions de la lucarne dans laquelle se dessine son bitmap)



    A plus !
    Vous m'aviez donné la solution,j'avais juste mal compris.
    En plus de modifier la taille du Bitmap fallait modifier celle du TImage...


    Merci encore à vous Henderson !!

  12. #12
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    1 407
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 407
    Par défaut
    Salut !

    Si on fixe la propriété AutoSize de Image2 à true, dans ce cas Image2 ajustera autommatiquement ses propres dimensions sur celles de son bitmap.

    A plus !

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

Discussions similaires

  1. problème avec procédure stockée
    Par kanebody dans le forum SQL Procédural
    Réponses: 1
    Dernier message: 04/08/2009, 13h55
  2. [AC-2003] Affichage d'un etat avec une fonction ayant date comme parametre
    Par yupyupxav dans le forum IHM
    Réponses: 0
    Dernier message: 06/06/2009, 00h43
  3. [A-03] Problème avec procédure "acDialog"
    Par moilou2 dans le forum IHM
    Réponses: 2
    Dernier message: 22/10/2008, 12h00
  4. Creation d'un Sub avec un tableau dynamique comme parametre
    Par Nico820 dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 31/07/2008, 07h16
  5. Réponses: 1
    Dernier message: 17/07/2006, 17h08

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