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

Langage Delphi Discussion :

Comment dessiner une bitmap dans le canvas d'un TImage ?


Sujet :

Langage Delphi

  1. #1
    Expert éminent
    Avatar de Lung
    Profil pro
    Analyste-programmeur
    Inscrit en
    Mai 2002
    Messages
    2 664
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste-programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 664
    Points : 6 967
    Points
    6 967
    Par défaut Comment dessiner une bitmap dans le canvas d'un TImage ?
    Comment dessiner une bitmap dans le canvas d'un TImage ?

    J'ai une sous-procédure qui me retourne une bitmap sur lequel elle a dessiné tout un tas de chose.
    Quand j'essai de la dessiner dans le Canvas d'un TImage, ça ne fonctionne pas (le TImage reste blanc).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    GenerationImpression(BitmapImpression);
    FormApercuAvantImpression.Image.Canvas.Draw(0, nHauteur, BitmapImpression);
    Par contre, si je passe par un fichier intermédiaire, là ça marche :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    // Dans la sous-procédure GenerationImpression :
    BitmapImpression.SaveToFile(GetRepertoireTemp + FICHIER_TEMP);
     
    ...
     
    // Pour afficher la bitmap dans mon TImage :
    FormApercuAvantImpression.Image.Picture.Bitmap.LoadFromFile(GetRepertoireTemp + FICHIER_TEMP);
    Mais, c'est pas une solution.
    Déjà c'est un peu lourd, et surtout j'ai besoin de dessiner des bitmaps les unes à la suite des autres (en hauteur).

    Comment dois-je faire ?
    L'urgent est fait, l'impossible est en cours, pour les miracles prévoir un délai. ___ Écrivez dans un français correct !!

    C++Builder 5 - Delphi 6#2 Entreprise - Delphi 2007 Entreprise - Delphi 2010 Architecte - Delphi XE Entreprise - Delphi XE7 Entreprise - Delphi 10 Entreprise - Delphi 10.3.2 Entreprise - Delphi 10.4.2 Entreprise - Delphi 11.1 Entreprise
    OpenGL 2.1 - Oracle 10g - Paradox - Interbase (XE) - PostgreSQL (15.4)

  2. #2
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 445
    Points
    28 445
    Par défaut
    si je ne m'abuse FormApercuAvantImpression.Image.Picture.Assign(BitmapImpression)
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  3. #3
    Membre émérite

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 387
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 387
    Points : 2 999
    Points
    2 999
    Par défaut
    bonjour ??
    svp ???

    sinon: +1


    Au pire, si ça fonctionne avec SaveTofile, ça fonctionnera aussi avec SaveToStream et ça évite l'enregistrement sur disque.

  4. #4
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 263
    Points
    3 263
    Par défaut
    Bonjour,

    J'ai une sous-procédure qui me retourne une bitmap sur lequel elle a dessiné tout un tas de chose.
    Quand j'essai de la dessiner dans le Canvas d'un TImage, ça ne fonctionne pas (le TImage reste blanc).
    Il manque peut-être un Image.Refresh, Image.RePaint, ou un Image.Invalidate.
    Ou bien c'est que le BitmapImpression est lui-même tout blanc.

    A+.
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  5. #5
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 693
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 693
    Points : 13 128
    Points
    13 128
    Par défaut
    nHauteur est dans la limite de l'image ?

  6. #6
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 445
    Points
    28 445
    Par défaut
    Citation Envoyé par Andnotor Voir le message
    nHauteur est dans la limite de l'image ?
    ah tient j'avais pas vu, le but n'est pas de placer l'image dans un TImage mais de la dessiner à une position donnée
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  7. #7
    Expert éminent
    Avatar de Lung
    Profil pro
    Analyste-programmeur
    Inscrit en
    Mai 2002
    Messages
    2 664
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste-programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 664
    Points : 6 967
    Points
    6 967
    Par défaut
    Citation Envoyé par Paul TOTH Voir le message
    si je ne m'abuse FormApercuAvantImpression.Image.Picture.Assign(BitmapImpression)
    Effectivement ça fonctionne, mais je n'ai plus le choix de la position en hauteur.

    Citation Envoyé par Gilbert Geyer Voir le message
    Ou bien c'est que le BitmapImpression est lui-même tout blanc.
    Non, il est bon. Je l'ai vérifié avec le SaveToFile. Le fichier BMP est bon.

    Citation Envoyé par Andnotor Voir le message
    nHauteur est dans la limite de l'image ?
    Normalement oui (sinon, ça serait embêtant ).

    Citation Envoyé par Paul TOTH Voir le message
    ah tient j'avais pas vu, le but n'est pas de placer l'image dans un TImage mais de la dessiner à une position donnée
    C'est ça.
    En gros, la sous-procédure est dans une boucle. Et chaque bitmap doit être dessinée à la suite de la précédente (en hauteur) dans le canvas de mon TImage.
    Je suis sûr qu'il ne me manque pas grand chose, mais je ne vois pas comment faire ...
    L'urgent est fait, l'impossible est en cours, pour les miracles prévoir un délai. ___ Écrivez dans un français correct !!

    C++Builder 5 - Delphi 6#2 Entreprise - Delphi 2007 Entreprise - Delphi 2010 Architecte - Delphi XE Entreprise - Delphi XE7 Entreprise - Delphi 10 Entreprise - Delphi 10.3.2 Entreprise - Delphi 10.4.2 Entreprise - Delphi 11.1 Entreprise
    OpenGL 2.1 - Oracle 10g - Paradox - Interbase (XE) - PostgreSQL (15.4)

  8. #8
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 693
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 693
    Points : 13 128
    Points
    13 128
    Par défaut
    GenerationImpression ne se présenterait-il pas comme ça ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    procedure GenerationImpression(aBitmap :TBitmap);
    begin
      aBitmap := TBitmap.Create;
    Dans quel cas il manquerait un var.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    procedure GenerationImpression(var aBitmap :TBitmap);
    begin
      aBitmap := TBitmap.Create;

  9. #9
    Expert éminent
    Avatar de Lung
    Profil pro
    Analyste-programmeur
    Inscrit en
    Mai 2002
    Messages
    2 664
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste-programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 664
    Points : 6 967
    Points
    6 967
    Par défaut
    J'avais mis out
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    procedure TOngletMusique.GenerationImpression(out BitmapImpression: Graphics.TBitmap);
    Même avec var, ça ne change rien.

    BitmapImpression est créée et détruite à l'extérieur par l'appelant.
    Voici ma boucle d'appel :
    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
    var
       i, nHauteur: Integer;
       BitmapImpression: TBitmap;
    begin
       if PageControl.PageCount = 0 then
          Exit;
     
       nHauteur := 0;
       FormApercuAvantImpression.Image.Height := 0;
     
       for i:=0 to Pred(PageControl.PageCount) do
       begin
          BitmapImpression := TBitmap.Create;
          try
             //.
             (PageControl.Pages[i] as TOngletMusique).GenerationImpression(BitmapImpression);
     
             FormApercuAvantImpression.Image.Height := FormApercuAvantImpression.Image.Height + BitmapImpression.Height;
             FormApercuAvantImpression.Image.Width := BitmapImpression.Width;
    //         FormApercuAvantImpression.Image.Picture.Assign(BitmapImpression);
             FormApercuAvantImpression.Image.Canvas.Draw(0, nHauteur, BitmapImpression);
          finally
             BitmapImpression.Free;
          end;
     
          nHauteur := FormApercuAvantImpression.Image.Height;
       end;
    L'urgent est fait, l'impossible est en cours, pour les miracles prévoir un délai. ___ Écrivez dans un français correct !!

    C++Builder 5 - Delphi 6#2 Entreprise - Delphi 2007 Entreprise - Delphi 2010 Architecte - Delphi XE Entreprise - Delphi XE7 Entreprise - Delphi 10 Entreprise - Delphi 10.3.2 Entreprise - Delphi 10.4.2 Entreprise - Delphi 11.1 Entreprise
    OpenGL 2.1 - Oracle 10g - Paradox - Interbase (XE) - PostgreSQL (15.4)

  10. #10
    Membre chevronné

    Homme Profil pro
    au repos
    Inscrit en
    Février 2014
    Messages
    429
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : au repos

    Informations forums :
    Inscription : Février 2014
    Messages : 429
    Points : 1 884
    Points
    1 884
    Par défaut
    Bonjour.

    Tu utilises un seul TImage que tu redimensionnes à chaque fois tant en hauteur qu'en largeur !!! Dans ton code, je ne vois pas de vérification de image.width minimale. Si ton dernier bitmap est moins large que les précédents, tu amputes ceux-ci !
    Pourquoi ne pas utiliser plusieurs TImage créés dynamiquement avec comme Parent, par exemple, un TPanel ou un TScrollBox ?
    Tu n'as plus alors à te soucier de la position Y où tu dessines sur l'image : mettre chaque image à la taille du bitmap, lui assigner le bitmap, puis la positionner juste en dessous de l'image précédente.

    Autre solution: créer un seul grand bitmap (prévoir une hauteur et une largeur suffisante), lui donner une couleur de fond (FillRect), dessiner sur ce bitmap les BitmapImpression, puis "retailler" le bitmap en fonction de la hauteur totale obtenue et de la plus grande largeur. Il ne reste plus qu'à afficher ce bitmap.

    Thierry

  11. #11
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 693
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 693
    Points : 13 128
    Points
    13 128
    Par défaut
    @Lung

    out en tout cas pas !

    Mais ça ne pourra de toute façon pas marcher ainsi. Si le TImage est vide à l'appel de son canevas, un bitmap est automatiquement créé à la dimension du TImage. Mais par la suite, retailler le TImage n'a aucun influence sur le bitmap interne, il faut aussi le redimensionner
    Là, au deuxième passage, tu dessines hors bitmap, et si le premier BitmapImpression est vide...

  12. #12
    Expert éminent
    Avatar de Lung
    Profil pro
    Analyste-programmeur
    Inscrit en
    Mai 2002
    Messages
    2 664
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste-programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 664
    Points : 6 967
    Points
    6 967
    Par défaut
    Citation Envoyé par ThWilliam Voir le message
    Tu utilises un seul TImage que tu redimensionnes à chaque fois tant en hauteur qu'en largeur !!! Dans ton code, je ne vois pas de vérification de image.width minimale. Si ton dernier bitmap est moins large que les précédents, tu amputes ceux-ci !
    La largeur est commune à toutes les images (même si je ne la connait pas d'avance). C'est pour ça.

    Citation Envoyé par ThWilliam Voir le message
    Pourquoi ne pas utiliser plusieurs TImage créés dynamiquement avec comme Parent, par exemple, un TPanel ou un TScrollBox ?
    Tu n'as plus alors à te soucier de la position Y où tu dessines sur l'image : mettre chaque image à la taille du bitmap, lui assigner le bitmap, puis la positionner juste en dessous de l'image précédente.
    Ça serait un moyen de contourner le problème si ça ne servait qu'à ça.
    Mais, si l'aperçu des image est convenable, j'utilise la même chose pour dessiner sur le canvas du TPrinter et imprimer mes images.
    Donc, il faut absolument que je dessine ces images sur un canvas (TImage et TPrinter).

    Citation Envoyé par ThWilliam Voir le message
    Autre solution: créer un seul grand bitmap (prévoir une hauteur et une largeur suffisante), lui donner une couleur de fond (FillRect), dessiner sur ce bitmap les BitmapImpression, puis "retailler" le bitmap en fonction de la hauteur totale obtenue et de la plus grande largeur. Il ne reste plus qu'à afficher ce bitmap.
    Bonne idée.
    Je vais probablement finir par faire ça, étant donné qu'une feuille A4 n'a pas une hauteur infinie.
    Mais, avant d'en arriver à ces problématiques là, j'essayais de mettre au moins 2 bitmaps, l'une en dessous de l'autre.
    L'urgent est fait, l'impossible est en cours, pour les miracles prévoir un délai. ___ Écrivez dans un français correct !!

    C++Builder 5 - Delphi 6#2 Entreprise - Delphi 2007 Entreprise - Delphi 2010 Architecte - Delphi XE Entreprise - Delphi XE7 Entreprise - Delphi 10 Entreprise - Delphi 10.3.2 Entreprise - Delphi 10.4.2 Entreprise - Delphi 11.1 Entreprise
    OpenGL 2.1 - Oracle 10g - Paradox - Interbase (XE) - PostgreSQL (15.4)

  13. #13
    Expert éminent
    Avatar de Lung
    Profil pro
    Analyste-programmeur
    Inscrit en
    Mai 2002
    Messages
    2 664
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste-programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 664
    Points : 6 967
    Points
    6 967
    Par défaut
    Citation Envoyé par Andnotor Voir le message
    Mais ça ne pourra de toute façon pas marcher ainsi. Si le TImage est vide à l'appel de son canevas, un bitmap est automatiquement créé à la dimension du TImage. Mais par la suite, retailler le TImage n'a aucun influence sur le bitmap interne, il faut aussi le redimensionner
    Là, au deuxième passage, tu dessines hors bitmap, et si le premier BitmapImpression est vide...
    C'était donc ça le truc !

    Et comment redimensionner ce canvas ?
    Il n'a pas de propriété Height (width non plus d'ailleur). Ca serait trop facile ...
    L'urgent est fait, l'impossible est en cours, pour les miracles prévoir un délai. ___ Écrivez dans un français correct !!

    C++Builder 5 - Delphi 6#2 Entreprise - Delphi 2007 Entreprise - Delphi 2010 Architecte - Delphi XE Entreprise - Delphi XE7 Entreprise - Delphi 10 Entreprise - Delphi 10.3.2 Entreprise - Delphi 10.4.2 Entreprise - Delphi 11.1 Entreprise
    OpenGL 2.1 - Oracle 10g - Paradox - Interbase (XE) - PostgreSQL (15.4)

  14. #14
    Expert éminent
    Avatar de Lung
    Profil pro
    Analyste-programmeur
    Inscrit en
    Mai 2002
    Messages
    2 664
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste-programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 664
    Points : 6 967
    Points
    6 967
    Par défaut
    Ça marche !

    J'ai tenté de jouer avec le bitmap du TImage (histoire de), et ça semble être la solution :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
             (PageControl.Pages[i] as TOngletMusique).GenerationImpression(BitmapImpression);
     
             FormApercuAvantImpression.Image.Height := FormApercuAvantImpression.Image.Height + BitmapImpression.Height;
             FormApercuAvantImpression.Image.Width := BitmapImpression.Width;
             FormApercuAvantImpression.Image.Picture.Bitmap.Height := FormApercuAvantImpression.Image.Height + BitmapImpression.Height;
             FormApercuAvantImpression.Image.Picture.Bitmap.Width := BitmapImpression.Width;
     
    //         FormApercuAvantImpression.Image.Picture.Assign(BitmapImpression);
             FormApercuAvantImpression.Image.Canvas.Draw(0, nHauteur, BitmapImpression);
    Mais, je ne comprend pas le rapport entre dessiner sur le canvas du TImage, et redimensionner le Timage.Picture.Bitmap.

    En tout cas, pour votre aide à tous.
    L'urgent est fait, l'impossible est en cours, pour les miracles prévoir un délai. ___ Écrivez dans un français correct !!

    C++Builder 5 - Delphi 6#2 Entreprise - Delphi 2007 Entreprise - Delphi 2010 Architecte - Delphi XE Entreprise - Delphi XE7 Entreprise - Delphi 10 Entreprise - Delphi 10.3.2 Entreprise - Delphi 10.4.2 Entreprise - Delphi 11.1 Entreprise
    OpenGL 2.1 - Oracle 10g - Paradox - Interbase (XE) - PostgreSQL (15.4)

  15. #15
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 693
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 693
    Points : 13 128
    Points
    13 128
    Par défaut
    Il te suffit de regarder la source de TImage. Derrière Canvas, il y a un GetCanvas qui crée un bitmap aux dimensions du TImage si Picture.Graphic n'est pas assigné.
    Un canevas n'est qu'une surface de dessin mais n'est pas mémorisé. Le TImage passe par un TBitmap pour qu'il le soit. S'il ne le faisait pas, ce serait simplement un TPaintBox

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

Discussions similaires

  1. Réponses: 7
    Dernier message: 11/03/2016, 20h22
  2. Comment remplacer une image dans un canvas.
    Par morchea dans le forum SWT/JFace
    Réponses: 1
    Dernier message: 17/05/2009, 03h44
  3. Comment stocker un Bitmap dans une chaine XML ?
    Par Danny Blue dans le forum C#
    Réponses: 3
    Dernier message: 14/07/2008, 12h15
  4. Réponses: 2
    Dernier message: 15/03/2007, 13h17
  5. Comment dessiner une ligne dans un Chart ?
    Par libititi dans le forum Composants VCL
    Réponses: 3
    Dernier message: 16/06/2005, 14h56

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