1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.mycore.media.services;
20
21 import java.awt.Graphics;
22 import java.awt.image.BufferedImage;
23 import java.io.IOException;
24 import java.io.InputStream;
25 import java.nio.file.Files;
26 import java.util.Optional;
27 import java.util.regex.Pattern;
28
29 import org.apache.pdfbox.pdmodel.PDDocument;
30 import org.apache.pdfbox.pdmodel.PDPage;
31 import org.apache.pdfbox.pdmodel.common.PDDestinationOrAction;
32 import org.apache.pdfbox.pdmodel.interactive.action.PDActionGoTo;
33 import org.apache.pdfbox.pdmodel.interactive.documentnavigation.destination.PDDestination;
34 import org.apache.pdfbox.pdmodel.interactive.documentnavigation.destination.PDPageDestination;
35 import org.apache.pdfbox.rendering.PDFRenderer;
36 import org.mycore.datamodel.niofs.MCRPath;
37
38 public class MCRPdfThumbnailGenerator implements MCRThumbnailGenerator {
39
40 private static final Pattern MATCHING_MIMETYPE = Pattern.compile("^application/pdf");
41
42 @Override
43 public boolean matchesFileType(String mimeType, MCRPath path) {
44 return MATCHING_MIMETYPE.matcher(mimeType).matches();
45 }
46
47 @Override
48 public Optional<BufferedImage> getThumbnail(MCRPath path, int size) throws IOException {
49 try (InputStream fileIS = Files.newInputStream(path); PDDocument pdf = PDDocument.load(fileIS)) {
50 final PDPage page = resolveOpenActionPage(pdf);
51 float pdfWidth = page.getCropBox().getWidth();
52 float pdfHeight = page.getCropBox().getHeight();
53 final int newWidth = pdfWidth > pdfHeight ? (int) Math.ceil(size * pdfWidth / pdfHeight) : size;
54 final float scale = newWidth / pdfWidth;
55
56 PDFRenderer pdfRenderer = new PDFRenderer(pdf);
57 BufferedImage pdfRender = pdfRenderer.renderImage(pdf.getPages().indexOf(page), scale);
58 int imageType = MCRThumbnailUtils.getImageType(pdfRender);
59 if (imageType == BufferedImage.TYPE_BYTE_BINARY || imageType == BufferedImage.TYPE_BYTE_GRAY) {
60 BufferedImage thumbnail = new BufferedImage(pdfRender.getWidth(), pdfRender.getHeight(),
61 imageType);
62 Graphics g = thumbnail.getGraphics();
63 g.drawImage(pdfRender, 0, 0, null);
64 g.dispose();
65 return Optional.of(thumbnail);
66 }
67 return Optional.of(pdfRender);
68 }
69 }
70
71 private PDPage resolveOpenActionPage(PDDocument pdf) throws IOException {
72 PDDestinationOrAction openAction = pdf.getDocumentCatalog().getOpenAction();
73
74 if (openAction instanceof PDActionGoTo) {
75 final PDDestination destination = ((PDActionGoTo) openAction).getDestination();
76 if (destination instanceof PDPageDestination) {
77 openAction = destination;
78 }
79 }
80
81 if (openAction instanceof PDPageDestination) {
82 final PDPageDestination namedDestination = (PDPageDestination) openAction;
83 final PDPage pdPage = namedDestination.getPage();
84 if (pdPage != null) {
85 return pdPage;
86 } else {
87 int pageNumber = namedDestination.getPageNumber();
88 if (pageNumber != -1) {
89 return pdf.getPage(pageNumber);
90 }
91 }
92 }
93
94 return pdf.getPage(0);
95 }
96 }