Stampare immagini in Java

Mattepuffo's logo
Stampare immagini in Java

Stampare immagini in Java

In sostanza vediamo come mandare in stampa più immagini contemporaneamente usando Java; ogni immagine occupa una pagina, quindi non dobbiamo occuparci di sistemare più immagini in una pagina.

Per fare questo useremo una classe che implementa Printable (di AWT).

A questa classe passeremo un array di BufferedImage, sul quale itereremo per "sistemare" e stampare le immagini.

Nei punti chiave della classe ci sono dei commenti; inoltre qui potete leggere il thread di riferimento sul forum HTML.it.

Questa la classe:

import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.awt.print.PageFormat;
import java.awt.print.Printable;

public class PrintImage implements Printable {

    private final BufferedImage[] images;

    public PrintImage(BufferedImage[] images) {
        this.images = images.clone();
    }

    @Override
    public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) {
        if (pageIndex >= 0 && pageIndex < images.length) {
            Graphics2D g2d = (Graphics2D) graphics;
            AffineTransform oldTransform = g2d.getTransform();
            try {
                printImage(g2d, pageFormat, images[pageIndex]);
            } finally {
                g2d.setTransform(oldTransform);
            }
            return Printable.PAGE_EXISTS;
        } else {
            return Printable.NO_SUCH_PAGE;
        }
    }

    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);
    }

}

Poi dobbiamo usare questa classe; qui sotto un esempio di come lancio il tutto da una schermata creata in JavaFX:

    @FXML
    private void printImages() {
        int lvSize = listViewImages.getItems().size();
        if (lvSize > 0) {
            ArrayList<String> lp = new ArrayList<>(listViewImages.getItems());
            BufferedImage[] bufferedImages = new BufferedImage[lp.size()];
            for (int i = 0; i < lp.size(); i++) {
                Image image = new Image(new File(lp.get(i)).toURI().toString());
                bufferedImages[i] = SwingFXUtils.fromFXImage(image, null);
            }
            PrinterJob pj = PrinterJob.getPrinterJob();
            pj.setJobName("MPPhotoGallery printer");
            pj.setPrintable(new PrintImage(bufferedImages));
            if (pj.printDialog()) {
                try {
                    pj.print();
                } catch (PrinterException e) {
                    
                }
            }
        }
    }

Dove listViewImages è una di ListView<String> JavaFX; ecco perchè quel SwingFXUtils.fromFXImage.

Se andate a leggere la documentazione, infatti, notere che SwingFXUtils serve per convertire i componenti Swing / AWT in JavaFX.

Comunque, anche qui, usiamo il PrinterJob di AWT; li ho trovati più facili da usare rispetto ai corrispettivi di JavaFX.

Enjoy!


Condividi

Commentami!