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

Documents Java Discussion :

[IText] Image mal dimensionnée


Sujet :

Documents Java

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 26
    Par défaut [IText] Image mal dimensionnée
    Bonjour,

    Dans mon programme, je génère un JPanel que je veux transformer en pdf. Je récupère une java.awt.Image que je transforme en import com.lowagie.text.Image, puis je l'ajoute à mon document.

    Mon premier souci c'est que je suis obligé d'affiché mon panel dans une JFrame pour pouvoir récupérer l'image (le repaint() ne suffit pas).

    Mon deuxième problème, le sujet de la discussion, c'est que, si le pdf est bien créé, je n'ai qu'un morceau de l'image : une partie est "en dehors" du pdf et une partie est entièrement noire. De plus la compression rend la lecture difficile (mon "image est en fait le texte d'un JEditorPane).

    Et le troisième (et dernier, pour le moment) truc que je ne comprends pas : mon application ne s'arrête pas. Les fonctions se terminent, j'arrive à la fin de ma fonction main mais Netbeans continue à tourner jusqu'à ce que je le stoppe de force.

    Mon souci principal reste le 2ème mais bon, tout peut-être lié alors si vous aviez des éclaircissements quelqu'ils soient je vous en remercie d'avance !

    Et pour vous aider à m'aider, je vous laisse le code de la fonction d'archivage (avec en plus, ma gestion hyper pointue des bugs, à base de "coucou" ) :
    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
    public File archiver(){
            MonPanel panel = new MonPanel(this);
            JFrame f1 = new JFrame();
            f1.setContentPane(panel);
            f1.pack();
            f1.setVisible(true);
            f1.setVisible(false);
            //f1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            java.awt.Image awtImage = panel.getImage();
            /*AfficheImage aff = new AfficheImage(awtImage);
            JFrame f = new JFrame();
            f.setContentPane(aff);
            f.pack();
            f.setVisible(true);
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);*/
            //génération du document PDF
            PdfWriter writer = null;
    	Document document = new Document(PageSize.A4, 10, 10, 45, 30);  //Format A4
            com.lowagie.text.Image img = null; //com.lowagie.text
            File archive = null;
            try
            {
                try
                {
                    img = com.lowagie.text.Image.getInstance(awtImage, null, false);
                    //TODO afficher l'image pour voir si elle est toute noire
                }
                catch(final IOException e)
                {
                    e.printStackTrace();
                }
                try
                {
                    archive = creerArchive();
                }
                catch(Exception e)
                {
                    e.toString();
                }
                try
                {
                    FileOutputStream fos = new FileOutputStream(archive);
                    try
                    {
                        writer = PdfWriter.getInstance(document, fos);
                        writer.setViewerPreferences(PdfWriter.PageLayoutOneColumn);
                        //ouverture du document
                        try
                        {
                            document.open();
                            System.out.println("coucou !");
                            PdfContentByte pcb = writer.getDirectContent();
                            //ajout graphique
                            //img = com.lowagie.text.Image.getInstance(pcb, awtImage, 1.0f);
                            img.setAbsolutePosition(10,20);
                            System.out.println("coucoubis !");
                            //pcb.addImage(img);
                            document.add(img);
                            System.out.println("coucou ?");
                        }
                        finally
                        {
                            document.close();
                            System.out.println("fermeture de coucou");
                        }
                    }
                    finally
                    {
                        writer.close();
                        System.out.println("fermeture de writer");
                    }
                }
                catch(final Exception e_pdf)
                {
                    e_pdf.printStackTrace();
                }
            }
            catch(final Exception e)
            {
                e.printStackTrace();
            }
            System.out.println("fin d'archivage");
            return archive;
        }

  2. #2
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 28
    Par défaut
    Bonjour,

    Je reprends tes trois problèmes en essayant de donner des pistes plus que des vraies réponses :

    1/ le fait qu'il soit nécessaire d'afficher le JPanel ne me surprend pas. Les component de swing sont avant tout prévus pour être rendus à l'écran, pas pour faire de la génération d'images. Tant qu'il n'a pas été affiché une fois, il n'est pas garanti de passer dans l'état "realized", nécessaire pour qu'il soit correctement dimensionné, etc... De plus, un JPanel fait partie de Swing et est donc un component Lightweight qui exploite la fenêtre des son plus proche parent de type Heavyweight, soit le JFrame dans lequel tu le places, pour se dessiner.

    2/ Il serait intéressant de voir la méthode MonPanel.getImage(). Sauf erreur de ma part, ce n'est pas une méthode fournie par JPanel.

    3/ Pour que l'application se termine, il faut appeler System.exit(0). 0 signie que l'application retourne sans erreur. Tu peux aussi forcer l'application à se terminer lorsque le JFrame est fermé mais ça me paraît être une mauvaise idée puisque ce serait prématuré.

    J'ajoute une remarque : tu affectes ton JPanel en tant que content pane du JFrame, ce qui me semble être une mauvaise idée. Ca marche probablement mais l'usage prévu est différent : le JFrame fournit déjà un content pane et tu es censé ajouter tes components à ce content pane. Ceci me paraît plus rigoureux :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    f1.getContentPane().add(panel);
    En pratique, JFrame a la bonne idée de rediriger son add() vers son content pane, ce qui te permet de simplifier le code ci-dessus en :
    Je doute quand même que ceci ait un lien avec tes problèmes. Le plus probable est qu'il y a un bug dans MonPanel.getImage().

    Hope it helps!

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 28
    Par défaut
    Je tiens tout de même à modérer ma remarque accusant péremptoirement MonPanel.getImage. J'ai un peu sous-estimé le risque de bug dans la partie qui génère le PDF. Sur ce point là, je n'ai aucune expérience et je préfère me taire

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 26
    Par défaut
    Merci de tes pistes !

    1/ Et j'imagine qu'il n'existe pas de composant Heavyweight équivalent à JPanel et plus particulièrement à JEditorPane... Enfin, ça ne m'étonne pas non plus, je vais faire avec !
    2/ Le code de getImage :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    public Image getImage(){
            BufferedImage tamponSauvegarde = new BufferedImage(this.getPreferredSize().width,this.getPreferredSize().height,BufferedImage.TYPE_3BYTE_BGR);
            Graphics g = tamponSauvegarde.getGraphics();
            this.paint(g);
            Image im = (Image)tamponSauvegarde;
            return im;
        }
    Mais le petit test (encore visible en commentaire) dans la fonction archiver m'incite à penser qu'elle marche bien (l'image affichée dans f est strictement la même que celle dans f1)

    3/ Ce qui m'étonne c'est que pour les tests de mes autres classes, il s'arrêtait bien avec un joli Build successful.

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 26
    Par défaut
    Citation Envoyé par cdefranoux Voir le message
    Je tiens tout de même à modérer ma remarque accusant péremptoirement MonPanel.getImage. J'ai un peu sous-estimé le risque de bug dans la partie qui génère le PDF. Sur ce point là, je n'ai aucune expérience et je préfère me taire
    Pas la peine de te demander si tu saurais comment visualiser une com.lowagie.text.Image du coup...

    Si quelqu'un sait ça m'arrangerait, j'aimerais bien savoir si c'est la création du nouveau type d'image ou l'ajout dans le pdf qui pose problème.

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 28
    Par défaut
    1/ Heavyweight ou Lightweight, je pense que le problème est le même. Le component doit être réalisé pour espérer en tirer une image correcte.

    2/ Attention :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    public Image getImage(){
            BufferedImage tamponSauvegarde = new BufferedImage(this.getPreferredSize().width,this.getPreferredSize().height,BufferedImage.TYPE_3BYTE_BGR);
            Graphics g = tamponSauvegarde.getGraphics();
            this.paint(g);
            Image im = (Image)tamponSauvegarde;
            return im;
        }
    Utilise plutôt this.getWidth() et this.getHeight() qui sont les dimensions réelles du JPanel et non la preferred size qui n'est qu'une proposition de dimensionnement que le Layout du JFrame (ou plutôt de son content pane si tu tiens compte de ma première remarque) est libre d'ignorer. Dans ton cas, il est très probable que la taille réelle corresponde à la preferred size mais c'est une mauvaise idée tout de même que de se fier à elle.

    3/ Je vois un f1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE) qui était plein d'inspiration mais qui intervient après que le JFrame soit fermé avec setVisible(false). C'est trop tard !
    En l'absence de ce setDefaultCloseOperation, le fait d'avoir affiché un component Swing ou AWT doit en principe empêcher l'application de se fermer, même après que toutes les fenêtres sont fermées.


    Pour la visu de ton image intermédiaire, je n'ai malheureusement pas d'info. Mais c'est sûr qu'il serait bon de voir à quoi elle ressemble.

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 28
    Par défaut
    J'ai remarqué que la doc de Image.getInstance() proposait le code source. Est-ce que ça ne t'aiderait pas à vérifier que l'image est correctement créée ? As-tu la possibilité de rentrer dans l'appel à getInstance() pour débugger ?
    Au pire, tu pourrais copier/coller le code de cette méthode dans ton code et l'appeler pour voir en live ce qui se passe. Si tu dois absolument faire appel à des méthodes privées ou protected de la classe Image, tu peux éventuellement les rendre accessibles par reflection.

  8. #8
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 26
    Par défaut
    Bon, un problème de résolu : le programme ne s'arrêtait pas car mes fenêtres existaient encore, j'ai utilisé dispose() plutôt que setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE) et ça s'arrête bien comme il faut. Merci de m'avoir mise sur la voie !

    Pour la partie difficile, j'ai aussi vu le code source de la classe Image mais à l'adresse http://kickjava.com/src/com/lowagie/text/Image.java.htm, je ne le voie pas sur le lien que tu as donné. Je vais tenter de l'insérer dans mon code pour débugger mais effectivement la dernière fois que j'ai tenté un truc du genre j'ai eu des problèmes à cause des attributs/méthodes privées. Tu me propose une solution avec la reflection, c'est quoi exactement ? En attendant, je vais copier la classe entière en espérant que ça m'évite des problèmes.

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 28
    Par défaut
    Ma solution pour accéder aux méthodes privées par réflection est un peu lourdingue. Regarde si tu ne pourrais tout simplement pas télécharger un zip des sources de cette librairie lowagie. Si tu utilises Eclipse, par exemple, il te suffit de renseigner ce zip comme étant le source du JAR que tu utilises et tu pourras rentrer dans l'appel de la méthode. C'est la méthode la plus simple.
    Et si tu utilises un autre IDE, j'imagine qu'une fonctionnalité équivalente est proposée.

  10. #10
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 26
    Par défaut
    Hello !

    Bon, bon, bon, depuis vendredi j'ai copié la classe com.lowagie.text.Image et j'ai bidouillé un peu pour l'intégrer à mon programme. Du coup j'ai fais des petits tests à coup de println mais rien de concluant. Ma première hypothèse, à savoir qu'il détectait une taille nulle de l'image est fausse... et comme je comprends pas grand-chose au code que j'ai trouvé je vois vraiment pas ce qu'il se passe pour que l'image soit tronquée. Une seconde hypothèse serait que l'image soit trop grande. Il me semblait que IText le gérait, ai-je tort ? D'après vous la talle 716 pixels de largeur et 746 de hauteur, c'est plus grand que ma page ? Comment connaitre la taille en pixel de ma page ? (si c'est possible)

    En attendant vos éclaircissements qui, j'espère, me mettrons sur la voie, je vais me plonger dans l'étude de la classe Image...

    Merci !

  11. #11
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 26
    Par défaut
    Salut,

    Encore une petite avancée : j'ai ajouté une scrollbar à la fenêtre qui me permet d'afficher l'image avant de la récupérer, du coup je n'ai plus de partie noire sur mon pdf (l'image n'était pas entièrement affichée donc pas entièrement récupérée).
    Mais le problème de dimensionnement persiste et signe, je n'ai trouvé aucun moyen d'imposer que la largeur de mon image soit adaptée à la largeur de la page... Je vous laisse en pj l'image (en jpeg) et le résultat pdf, vous jugerez sur pièces .
    Images attachées Images attachées  
    Images attachées Images attachées

  12. #12
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 26
    Par défaut
    Problème résolu !!

    J'ai utilisé la fonction addImage(Image image, float a, float b, float c, float d, float e, float f) avec les paramètres a = largeur de ma page, b = 0, c = 0, d = hauteur de ma page, e = 0, f = 0, et ça marche. Il faut que je rajoute des subtilités comme les marges et j'espère trouver une solution pour améliorer la qualité du rendu (quitte à avoir un pdf plus lourd bien sur) mais je crois pouvoir dire que ce post est résolu ! OUF !

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

Discussions similaires

  1. [iText] Images/mise en page
    Par -aulau- dans le forum Documents
    Réponses: 12
    Dernier message: 02/04/2010, 10h39
  2. Réponses: 1
    Dernier message: 05/09/2008, 14h39
  3. background image mal gérée par IE
    Par apqmwnqmap dans le forum Balisage (X)HTML et validation W3C
    Réponses: 6
    Dernier message: 30/01/2008, 11h33
  4. [iText] Image en premier plan
    Par Psykorel dans le forum Documents
    Réponses: 3
    Dernier message: 09/10/2007, 16h32
  5. Images mal placées
    Par shawty dans le forum Tableaux - Graphiques - Images - Flottants
    Réponses: 3
    Dernier message: 23/08/2007, 18h05

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