1 package com.atlassian.core.util.thumbnail;
2
3 import com.google.common.base.Optional;
4 import org.apache.commons.io.IOUtils;
5
6 import javax.imageio.ImageIO;
7 import javax.imageio.ImageReader;
8 import javax.imageio.stream.ImageInputStream;
9 import java.awt.Image;
10 import java.io.BufferedInputStream;
11 import java.io.IOException;
12 import java.io.InputStream;
13 import java.util.Iterator;
14
15 public class DimensionsHelper {
16
17 public Dimensions dimensionsForImage(final InputStream inputStream) throws IOException {
18 final BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
19
20 try
21 {
22 final ImageInputStream imageInputStream = getImageInputStream(inputStream);
23 final Optional<ImageReader> imageReader = getImageReader(imageInputStream);
24 if (!imageReader.isPresent())
25 {
26 throw new IOException("There is no ImageReader available for the given ImageInputStream");
27 }
28
29 final ImageReader reader = imageReader.get();
30 try
31 {
32 reader.setInput(imageInputStream);
33 return new Dimensions(reader.getWidth(0), reader.getHeight(0));
34 }
35 finally
36 {
37 reader.dispose();
38 }
39 }
40 finally
41 {
42 IOUtils.closeQuietly(bufferedInputStream);
43 }
44 }
45
46 public Dimensions determineScaledDimensions(int maxWidth, int maxHeight, Image image)
47 {
48 return determineScaledDimensions(maxWidth, maxHeight, image.getWidth(null), image.getHeight(null));
49 }
50
51 public Dimensions determineScaledDimensions(int maxWidth, int maxHeight, int imageWidth, int imageHeight)
52 {
53 if (maxHeight > imageHeight && maxWidth > imageWidth)
54 {
55 return new Dimensions(imageWidth, imageHeight);
56 }
57
58
59 double thumbRatio = (double) maxWidth / (double) maxHeight;
60
61 double imageRatio = (double) imageWidth / (double) imageHeight;
62
63 if (thumbRatio < imageRatio)
64 {
65 return new Dimensions(maxWidth, (int) Math.max(1, maxWidth / imageRatio));
66 }
67 else
68 {
69 return new Dimensions((int) Math.max(1, maxHeight * imageRatio), maxHeight);
70 }
71 }
72
73 ImageInputStream getImageInputStream(InputStream inputStream) throws IOException
74 {
75 return ImageIO.createImageInputStream(inputStream);
76 }
77
78 Optional<ImageReader> getImageReader(ImageInputStream imageInputStream) throws IOException
79 {
80 final Iterator<ImageReader> readers = ImageIO.getImageReaders(imageInputStream);
81 return readers.hasNext() ? Optional.of(readers.next()) : Optional.<ImageReader>absent();
82 }
83 }