1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.mycore.iview2.services;
20
21 import java.awt.Graphics2D;
22 import java.awt.image.BufferedImage;
23 import java.io.IOException;
24 import java.nio.file.FileSystem;
25 import java.nio.file.Path;
26 import java.util.Optional;
27 import java.util.regex.Pattern;
28
29 import javax.imageio.ImageReader;
30
31 import org.mycore.datamodel.niofs.MCRPath;
32 import org.mycore.imagetiler.MCRImage;
33 import org.mycore.imagetiler.MCRTiledPictureProps;
34 import org.mycore.media.services.MCRThumbnailGenerator;
35
36 public class MCRImageThumbnailGenerator implements MCRThumbnailGenerator {
37
38 private static final Pattern MATCHING_MIMETYPE = Pattern.compile("^image\\/.*");
39
40 @Override
41 public boolean matchesFileType(String mimeType, MCRPath path) {
42 return MATCHING_MIMETYPE.matcher(mimeType).matches();
43 }
44
45 @Override
46 public Optional<BufferedImage> getThumbnail(MCRPath path, int size) throws IOException {
47 Path iviewFile = MCRImage.getTiledFile(MCRIView2Tools.getTileDir(), path.getOwner(),
48 path.getOwnerRelativePath());
49 MCRTiledPictureProps iviewFileProps = getIviewFileProps(iviewFile);
50 final double width = iviewFileProps.getWidth();
51 final double height = iviewFileProps.getHeight();
52 final int newWidth = width > height ? (int) Math.ceil(size * width / height) : size;
53 final int newHeight = width > height ? size : (int) Math.ceil(size * height / width);
54
55
56 final double scale = newWidth / width;
57
58
59 int sourceZoomLevel = (int) Math.min(
60 Math.max(0, Math.ceil(iviewFileProps.getZoomlevel() - Math.log(scale) / Math.log(1.0 / 2.0))),
61 iviewFileProps.getZoomlevel());
62
63
64 double zoomLevelScale = Math.min(1.0, Math.pow(0.5, iviewFileProps.getZoomlevel() - sourceZoomLevel));
65
66
67 double drawScale = (newWidth / (width * zoomLevelScale));
68
69 try (FileSystem zipFileSystem = MCRIView2Tools.getFileSystem(iviewFile)) {
70 Path rootPath = zipFileSystem.getPath("/");
71 ImageReader imageReader = MCRIView2Tools.getTileImageReader();
72 BufferedImage testTile = MCRIView2Tools.readTile(rootPath, imageReader, sourceZoomLevel, 0, 0);
73 BufferedImage targetImage = getTargetImage(newWidth, newHeight, testTile);
74 Graphics2D graphics = targetImage.createGraphics();
75 graphics.scale(drawScale, drawScale);
76 for (int x = 0; x < Math.ceil(width * zoomLevelScale / 256); x++) {
77 for (int y = 0; y < Math.ceil(height * zoomLevelScale / 256); y++) {
78 BufferedImage tile = MCRIView2Tools.readTile(rootPath, imageReader, sourceZoomLevel, x, y);
79 graphics.drawImage(tile, x * 256, y * 256, null);
80 }
81 }
82 return Optional.of(targetImage);
83 }
84 }
85
86 private MCRTiledPictureProps getIviewFileProps(Path tiledFile) throws IOException {
87 MCRTiledPictureProps tiledPictureProps = null;
88 try (FileSystem fileSystem = MCRIView2Tools.getFileSystem(tiledFile)) {
89 tiledPictureProps = MCRTiledPictureProps.getInstanceFromDirectory(fileSystem.getPath("/"));
90 } catch (IOException e) {
91 throw new IOException("Could not provide image information!", e);
92 }
93 return tiledPictureProps;
94 }
95
96 private BufferedImage getTargetImage(int width, int height, BufferedImage firstTile) {
97 return new BufferedImage(width, height, firstTile.getType());
98 }
99 }