Visualizzazione dei risultati da 1 a 8 su 8
  1. #1

    PDF con immagini sgranate o fuori pagina

    ciao!

    sto cercando creare un pdf con immagini prese da un ArrayList<String>.
    una immagine a pagina:
    codice:
    import org.apache.pdfbox.pdmodel.PDDocument;
    import org.apache.pdfbox.pdmodel.PDPage;
    import org.apache.pdfbox.pdmodel.PDPageContentStream;
    import org.apache.pdfbox.pdmodel.common.PDRectangle;
    import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
    
    import java.io.IOException;
    import java.util.ArrayList;
    
    public class PdfGallery {
        private ArrayList<String> images = null;
    
        public PdfGallery(ArrayList<String> images) {
            this.images = images;
        }
    
        public void createPdf() throws IOException {
            try (PDDocument doc = new PDDocument()) {
                for (String str : images) {
                    PDPage page = new PDPage(PDRectangle.A4);
                    doc.addPage(page);
                    PDImageXObject pdImage = PDImageXObject.createFromFile(str, doc);
                    float w = pdImage.getWidth();
                    float h = pdImage.getHeight();
                    try (PDPageContentStream contents = new PDPageContentStream(doc, page)) {
                        contents.drawImage(pdImage, 0, 0, w, h);
                    }
                }
                doc.save("/home/matte/Desktop/sample.pdf");
            }
        }
    }
    le pagine vengono create correttamente.
    e le immagini vengono aggiunte alla pagina.
    solo che:
    - se sono grandi (ad esempio 1920*1080) si vedono sgranate e / o più grandi della pagina
    - se sono piccole (ad esempio 300*400) si vedono sgranate (anche se l'originale ovviamente non lo è)

    per creare il pdf sto usando PDFBox.
    qualcuno ha qualche idea??

  2. #2
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,254
    Devi fare una cosa, concettualmente parlando, similare a quanto abbiamo visto insieme qui.

    Il punto è che quei w e h che stai usando per disegnare l'immagine sono PIXEL.
    Mentre nei PDF l'unità di misura predefinita è il "solito" punto di 1/72 inch.
    Stavi usando pixel come se fossero in questa unità.

    Quindi per 1920 pixel:
    1920 / 72 = 26,66666 inch × 2,54 cm = 67,73333 cm

    67 centimetri !! Ben più lungo di un foglio A4.

    Inoltre bisogna anche ricordare che nei PDF l'origine (0,0) degli assi è in BASSO a sinistra.
    Questa è solo una piccola "rottura" in più.


    È da un po' che non uso la PDFBox, appena ho tempo faccio qualche prova.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    Java Versions Cheat Sheet

  3. #3
    ciao andbin!

    si in effetti mi sono basato su un esempio visto qui, e non ci ho pensato.
    quello che dovrei fare, in sostanza, è convertire i pixel in cm.
    e da li settare la dimensione se non ho capito male.

    oppure ho trovato un esempio che fa una cosa del genere (ma non l'ho ben capita onestamente):
    codice:
                try (PDPageContentStream contentStream = new PDPageContentStream(doc, page, AppendMode.APPEND, true, true))
                {
                    // contentStream.drawImage(ximage, 20, 20 );
                    // better method inspired by http://stackoverflow.com/a/22318681/535646
                    // reduce this value if the image is too large
                    float scale = 1f;
                    contentStream.drawImage(pdImage, 20, 20, pdImage.getWidth() * scale, pdImage.getHeight() * scale);
                }


    per quanto riguarda il posizionamento, in effetti ho notato che parte da in basso a sinistra.
    ho trovato un esempio che dovrebbe posizionare a partire da in altro a sinistra:
    codice:
    PDRectangle mediaBox = page.getMediaBox();
    
    // draw with the starting point 1 inch to the left
    // and 2 inch from the top of the page
    contentStream.drawImage(pdImage, 72, mediaBox.getHeight() - 2 * 72);

    purtroppo ho qualche problema col pc, e non riesco a testare il tutto!
    appena sistemo mi ci metto!

  4. #4
    ciao!

    partendo dal presupposto che un A4 è 595.35x842 points.
    per quanto riguarda la dimensione, ho provato questa conversione:
    codice:
        public void createPdf() throws IOException {
            try (PDDocument doc = new PDDocument()) {
                for (String str : images) {
                    PDPage page = new PDPage(PDRectangle.A4);
                    doc.addPage(page);
                    PDImageXObject pdImage = PDImageXObject.createFromFile(str, doc);
    
                    float w = pdImage.getWidth();
                    float h = pdImage.getHeight();
    //                float areaX = page.getMediaBox().getWidth();
    //                float areaY = page.getMediaBox().getHeight();
    float finalW = w * 25.4f / 72;
                    float finalH = h * 25.4f / 72;
    
                    System.out.println(finalW);
                    System.out.println(finalH);
    
                    try (PDPageContentStream contents = new PDPageContentStream(doc, page)) {
                        contents.drawImage(pdImage, 0, 0, finalW, finalH);
                    }
                }
                doc.save("/home/matte/Desktop/sample.pdf");
            }
        }
    }

    andiamo un pò meglio.
    però, ad esempio una immagine ha queste dimensioni convertite: 903.1111x564.44446.
    quindi sfora ancora in larghezza.

  5. #5
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,254
    Quote Originariamente inviata da fermat Visualizza il messaggio
    però, ad esempio una immagine ha queste dimensioni convertite: 903.1111x564.44446.
    quindi sfora ancora in larghezza.
    Se vuoi fare il "aspect fit", la formula è la stessa che avevamo già visto nell'altra discussione.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    Java Versions Cheat Sheet

  6. #6
    si lo stavo guardando:
    codice:
    private void printImage(Graphics2D g2d, PageFormat pageFormat, BufferedImage image) {
        int imageWidth = image.getWidth();
        int imageHeight = image.getHeight();
        double areaX = pageFormat.getImageableX();
        double areaY = pageFormat.getImageableY();
        double areaWidth = pageFormat.getImageableWidth();
        double areaHeight = pageFormat.getImageableHeight();
        g2d.translate(areaX, areaY);
    
        // Verifica se gli orientamenti di area e immagine non coincidono
    if (areaWidth > areaHeight ^ imageWidth > imageHeight) {
            g2d.translate(areaWidth, 0);
            g2d.rotate(Math.PI / 2);   // ruota di +90 gradi
    
            // inverte le lunghezze
    areaHeight = pageFormat.getImageableWidth();
            areaWidth = pageFormat.getImageableHeight();
        }
    
        double scale = Math.min(areaWidth / imageWidth, areaHeight / imageHeight);
    
        g2d.scale(scale, scale);
        g2d.drawImage(image, 0, 0, null);
    }

    però io non vorrei ruotare la pagina.
    vorrei farla sempre rientrare nelle dimensioni anche se larghezza > altezza.
    non so me mi sono spiegato bene!

  7. #7
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,254
    Per il "aspect fit" la formula è solo quella dello scale (quel Math.min sui due rapporti). Quella dice "quale è il fattore di scala per occupare al massimo ma senza sforare".
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    Java Versions Cheat Sheet

  8. #8
    ok ho fatto così e sembra funzionare:

    codice:
    public class PdfGallery {
    
        private ArrayList<String> images = null;
    
        public PdfGallery(ArrayList<String> images) {
            this.images = images;
        }
    
        public void createPdf() throws IOException {
            try (PDDocument doc = new PDDocument()) {
                for (String str : images) {
                    PDPage page = new PDPage(PDRectangle.A4);
                    doc.addPage(page);
                    PDImageXObject pdImage = PDImageXObject.createFromFile(str, doc);
    
                    float imageWidth = pdImage.getWidth();
                    float imageHeight = pdImage.getHeight();
                    float areaWidth = page.getMediaBox().getWidth();
                    float areaHeight = page.getMediaBox().getHeight();
                    float scale = Math.min(areaWidth / imageWidth, areaHeight / imageHeight);
                    float finalW = imageWidth * scale;
                    float finalH = imageHeight * scale;
                    float cornerLeftTop = areaHeight - finalH;
    
                    try (PDPageContentStream contents = new PDPageContentStream(doc, page)) {
                        contents.drawImage(pdImage, 0, cornerLeftTop, finalW, finalH);
                    }
                }
                doc.save("/home/matte/Desktop/sample.pdf");
            }
        }
    }

    per quanto riguarda il posizionamento a partire da in alto a sinistra.
    ho pensato di fare banalmente di calcolare il punto sottraendo l'altezza della pagina e l'altezza dell'immagine.
    ho provato con varie immagini, e sembra si posizioni sempre bene.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.