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!
java javafx swing awt printerjob printable swingfxutils fxml
Commentami!