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 :

Dessiner un histogramme dans un autre TForm


Sujet :

C++Builder

  1. #21
    Membre éclairé Avatar de SmileSoft
    Inscrit en
    Mars 2008
    Messages
    436
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 436
    Par défaut
    Citation Envoyé par kmaniche Voir le message
    Tu devrais peut être analyser ton code à tête reposée :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Histogramme->Canvas->MoveTo(Histogramme->ImageH->Left,70);
    Avec la ligne en rouge, tu demande à dessiner sur le canvas de la fiche (form) et en bleu tu lis la position du composant ImageH

    Normalement, le dessin s'effectue directement sur le composant ImageH non ?
    oui, merci kmaniche je vois bien maintenant.
    donc je dessinais sur la fiche directement, j'ai rectifié avec ce code
    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
    // Dessin des axes de l'histogramme
    Histogramme->ImageH->Canvas->Pen->Color=clBlack;
    Histogramme->ImageH->Canvas->MoveTo(Histogramme->ImageH->Left,70);
    Histogramme->ImageH->Canvas->LineTo(Histogramme->ImageH->Left,300);
     
    Histogramme->ImageH->Canvas->MoveTo(Histogramme->ImageH->Left,300);
    Histogramme->ImageH->Canvas->LineTo(Histogramme->ImageH->Width,300);
     
     
    // Dessin de l'histogramme ...
    Histogramme->ImageH->Canvas->Pen->Color=clRed;
    for(int i=0;i<255; i++) {
    Histogramme->Canvas->MoveTo(i+Histogramme->ImageH->Left,300);
     
     
     
     Histogramme->ImageH->Canvas->LineTo(i+Histogramme->ImageH->Left, 300-Pretraitement->H[i]/100);
     
      }
     
    Histogramme->Show();
    mais j'ai une droite rouge qui s'affiche (je pense que c'est un problème d'ajustement du dessin en plus l'histogramme affiché n'est pas plain.

    ci joint une image du résultat

  2. #22
    Membre Expert
    Avatar de sat83
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2004
    Messages
    1 040
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mars 2004
    Messages : 1 040
    Par défaut
    Juste pour info, pour réaliser des graph ou des histogrammes, il y a la possibilité d'utiliser le composant TChart.

  3. #23
    Membre Expert
    Avatar de kmaniche
    Inscrit en
    Janvier 2006
    Messages
    1 717
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 1 717
    Par défaut
    Rappelles toi ce que j'ai dis :

    Il faut que la partie ou tu dessine l'histogramme soit d'une largeur supérieure au moins à 260.

    Pour arriver à dessiner un histogramme plein, il faut pour chaque itération de i, tu dessine une ligne entre l'axe X et la valeur de ton vecteur d'histogramme Pretaitement -> H[i] en gardant le même abscisse.

    Tu peux faire mieux, pourquoi ne pas utiliser simplement un TChart, ça donne un résultat meilleur que celui tu as obtenu.

    Bonne journée.

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

    TCanvas apporte son propre référentiel dans la zone client de l'objet.
    Donc les coordonnées à fournir sont celles dans ce référentiel (et non par rapport à l'écran ... ou autre) !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    int bord;
    int fond = 300;
    TCanvas *C = Form2->Image->Picture->Bitmap->Canvas;
     
    for(x=0;x < 256; x++)
        {
        bord = x+16;
        C->MoveTo(bord, fond);
        C->LineTo(bord, fond - GrisAjustes[x]);
        }
    On termine donc avec :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Form2->Image->Repaint();
    A plus !

  5. #25
    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 !

    Par ailleurs on peut améliorer un peu l'aspect avec des lignes tracées en tenant compte de la couleur :

    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
     
    Graphics::TBitmap *Bitmap = Image1->Picture->Bitmap;
    Bitmap->Width = Image1->Width;
    Bitmap->Height = Image1->Height;
    TCanvas *C = Bitmap->Canvas;
    C->Brush->Style = bsSolid;
    C->Brush->Color = clAqua; // << pourquoi pas !
    C->FillRect(Rect(0,0,Bitmap->Width, Bitmap->Height));
     
    int x;
    int bord = 16;
    int fond = 300;
    for(int j=0; j < 256; j++)
        {
        x = bord + j;
        C->Pen->Color = (TColor)RGB(j,j,j);
        C->MoveTo(x, fond);
        C->LineTo(x, fond - Gris[j]);
        }
    Personnellement ... j'aime bien !

    Donc ça se décline assez bien pour les histogrammes de R, G et B :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    C->Pen->Color = (TColor)RGB(j,0,0);
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    C->Pen->Color = (TColor)RGB(0,j,0);
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    C->Pen->Color = (TColor)RGB(0,0,j);
    A plus !

  6. #26
    Membre éclairé Avatar de SmileSoft
    Inscrit en
    Mars 2008
    Messages
    436
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 436
    Par défaut
    Merci kamniche et sat83 pour tout j'utiliserai la solution du TChart si je bloque encore quoique j'aimerai bien dessiner l'histogramme pour m'entrainer.

    Merci henderson pour ce joli code, il marche très bien mais j'ai le problème de débordement d'amplitude dans l'histogramme de certaines images, j'ai pensé à deviser le tableau d'histogramme sur un nombre mais le choix de ce dernier pose problème pour les images qui ont des petites amplitudes dans l'histogramme, je ne sais pas est ce qu'il existe un moyen pour adapter l'histogramme à la taille du bitmap?
    autres question si possible:
    j'ai déposé quelques labels sur le bitmap mais ils ne s'affichent pas à l'exécution, comment faire pour les affiché?
    j'aimerai aussi savoir comment dessiner des droites orientées pour orienter les 2 axes donnés par ces cordonnées
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    C->MoveTo(bord,16);
    C->LineTo(16, fond );
     
    C->MoveTo(16,fond);
    C->LineTo(Bitmap->Width-16,fond);
    merci d'avance.

  7. #27
    Membre Expert
    Avatar de kmaniche
    Inscrit en
    Janvier 2006
    Messages
    1 717
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 1 717
    Par défaut
    j'ai le problème de débordement d'amplitude dans l'histogramme de certaines images, j'ai pensé à deviser le tableau d'histogramme sur un nombre mais le choix de ce dernier pose problème pour les images qui ont des petites amplitudes dans l'histogramme, je ne sais pas est ce qu'il existe un moyen pour adapter l'histogramme à la taille du bitmap?
    C'est normal , et logiquement il y a une solution

    Si ton bitmap fait H pixels de hauteur, et le vecteur de l'hitogramme comporte une valeur max de vmax, alors pour pouvoir tracer ton histrogramme dans le bitmap, il faut multiplier chaque valeur du vectur par le rapport de H/vmax.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    j'aimerai aussi savoir comment dessiner des droites orientées pour  orienter les 2 axes donnés par ces cordonnées
    Cad si tu veux des flèches, il faut les dessiner manuellement !

  8. #28
    Membre éclairé Avatar de SmileSoft
    Inscrit en
    Mars 2008
    Messages
    436
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 436
    Par défaut
    salut,

    Citation Envoyé par kmaniche Voir le message
    Si ton bitmap fait H pixels de hauteur, et le vecteur de l'hitogramme comporte une valeur max de vmax, alors pour pouvoir tracer ton histrogramme dans le bitmap, il faut multiplier chaque valeur du vectur par le rapport de H/vmax.
    je n'ai pas un grand changement en traçant ceci

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    for(int j=0; j < 256; j++)
        {
        x = bord + j;
        C->Pen->Color = (TColor)RGB(j,j,j);
        C->MoveTo(x, fond);
        C->LineTo(x, fond -H[j]*MaxG/Bitmap->Height);
    //MaxG étant le max du tableau H[i]; 
    
    
        }

    Cad si tu veux des flèches, il faut les dessiner manuellement !
    oui je veux des flèches mais avec BCB pas manuellement

  9. #29
    Membre Expert
    Avatar de kmaniche
    Inscrit en
    Janvier 2006
    Messages
    1 717
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 1 717
    Par défaut
    Quand je dis manuellement, c'est par programmation bien sur. Je voulais dire aussi qu'il n y a pas une fonction prête pour tracer des flèche.

    Une flèche est dessiner en utilisant MoveTo & LineTo
    par exemple :

    exemple :
    p1(100, 100)
    p2(110, 90)
    p3(100, 80)

  10. #30
    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 !

    C->LineTo(x, fond -H[j]*MaxG/Bitmap->Height);
    Ca irait beaucoup mieux en appliquant correctement la règle de trois :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    C->LineTo(x, fond - (H[j] * Bitmap->Height / MaxG) );
    A plus !

  11. #31
    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 !

    oui je veux des flèches mais avec BCB pas manuellement
    Comme dirait l'autre : "vouloir ... c'est pouvoir"
    Ceci dit...

    Pour dessiner une flèche orientée il faut ressortir les formules de trigonométrie !
    J'ai donné du code sur ce forum ... le problème ... il faudrait faire une recherche.
    Il me semble que c'était une flèche orientée au bout d'une courbe de Bézier (avec une poignée pour controler en "live"...)... mais peut-être aussi au bout d'un segment (???)...

    Il faudrait juste connaître ce dont on dispose pour la tracer : 2 points connus, 1 point 1 angle ... ?

    Je ne pourrai pas répondre avant ce soir tard donc ...

    A plus !

  12. #32
    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 !

    Donc on va partir du principe qu'il existe deux points S et E et que l'on a tracé le segment SE.
    On va utiliser le point E comme pointe de la flèche : S ---> E

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    #include <math.h> // pour hypot
    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
     
    // Calcul de la pente du segment SE
    int dx = E.x - S.x;
    int dy = E.y - S.y;
    double d = hypot(dx, dy);
    double sina = 0.0;
    double cosa = 1.0;
    double sinb;
    double cosb;
    if(d != 0.0)
        {
        sina = dy / d;
        cosa = dx / d;
        }
     
    //--------------------------------------------------------------------
    // Au repos (avant rotation), la position des points S1 et S2 de la 
    // base de la flèche est prédéfinie relativement par rapport à la pointe :
    //
    //       S2 (-12, +6)
    //        |****
    //        |    ****
    //        |        **** E' (0,0)
    //        |    ****
    //        |****
    //       S1 (-12, -6)
    //
    //--------------------------------------------------------------------
     
    // Le point S1 
    double x1 = -12;
    double y1 = -6;
    d = hypot(x1, y1);
    sinb = y1 / d;
    cosb = x1 / d;
    // Rotation autour de E
    y1 = E.y + (((sina * cosb) + (sinb * cosa)) * d);
    x1 = E.x + (((cosa * cosb) - (sina * sinb)) * d);
     
    //Le point S2
    double x2 = -12;
    double y2 = +6;
    d = hypot(x2, y2);
    sinb = y2 / d;
    cosb = x2 / d;
    // Rotation autour de E
    y2 = E.y + (((sina * cosb) + (sinb * cosa)) * d);
    x2 = E.x + (((cosa * cosb) - (sina * sinb)) * d);
     
    // On dessine le contour avec une couleur sale
    Canvas->Pen->Color = (TColor)0x00000001;
    Canvas->MoveTo(E.x, E.y);
    Canvas->LineTo(x1, y1);
    Canvas->LineTo(x2, y2);
    Canvas->LineTo(E.x, E.y);
     
    // Isobarycentre du triangle
    double x3 = (x1 + x2 + E.x) / 3;
    double y3 = (y1 + y2 + E.y) / 3;
     
    // Remplissage avec la couleur sale (pas tout à fait clBlack)
    Canvas->Brush->Color = (TColor)0x00000001;
    Canvas->FloodFill(x3,y3, (TColor)0x00000001, fsBorder);
    A plus !

  13. #33
    Membre éclairé Avatar de SmileSoft
    Inscrit en
    Mars 2008
    Messages
    436
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 436
    Par défaut
    Merci beaucoup henderson je regarderai ça un tête reposée, pour mon ex problème j'ai opté pour cette solution qui m'a arrangé:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     C->LineTo(x, fond -((H[j]*Bitmap->Height)/(2*MaxG)) );

Discussions similaires

  1. Réponses: 0
    Dernier message: 02/01/2011, 13h24
  2. Dessiner une portion d'image dans une autre image
    Par Harry_polin dans le forum Windows Presentation Foundation
    Réponses: 4
    Dernier message: 24/11/2009, 13h19
  3. Réponses: 7
    Dernier message: 10/06/2009, 22h29
  4. [BCB6] Mettre dans une TForm une autre TForm.
    Par almisuifre dans le forum C++Builder
    Réponses: 17
    Dernier message: 25/11/2006, 07h08
  5. Réponses: 6
    Dernier message: 31/08/2006, 15h19

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