1 package com.atlassian.core.util.thumbnail;
2
3 import com.atlassian.core.util.ReusableBufferedInputStream;
4 import com.atlassian.core.util.thumbnail.loader.ImageFactory;
5
6 import java.awt.*;
7 import java.awt.image.BufferedImage;
8 import java.io.IOException;
9
10 public class MemoryImageScale implements ImageScaler
11 {
12 private final DimensionsHelper dimensionsHelper;
13 private final ImageFactory imageFactory;
14
15 public MemoryImageScale(DimensionsHelper dimensionsHelper, ImageFactory imageFactory)
16 {
17 this.dimensionsHelper = dimensionsHelper;
18 this.imageFactory = imageFactory;
19 }
20
21 @Override
22 public BufferedImage scaleImage(int maxWidth, int maxHeight, ReusableBufferedInputStream imageStream) throws IOException
23 {
24 final BufferedImage imageToScale = imageFactory.loadImage(imageStream);
25 final Dimensions newDimensions = dimensionsHelper.determineScaledDimensions(maxWidth, maxHeight, imageToScale);
26 return scaleImage(imageToScale, newDimensions);
27 }
28
29 public static BufferedImage scaleImage(final BufferedImage imageToScale, final Thumber.WidthHeightHelper newDimensions)
30 {
31 return scaleImage(imageToScale, new Dimensions(newDimensions.getWidth(), newDimensions.getHeight()));
32 }
33
34 public static BufferedImage scaleImage(final BufferedImage imageToScale, final Dimensions newDimensions)
35 {
36 if (newDimensions.getWidth() > imageToScale.getWidth() || newDimensions.getHeight() > imageToScale.getHeight())
37 {
38 return getScaledInstance(imageToScale, newDimensions.getWidth(), newDimensions.getHeight(),
39 RenderingHints.VALUE_INTERPOLATION_BICUBIC, false);
40 }
41 else
42 {
43 return getScaledInstance(imageToScale, newDimensions.getWidth(), newDimensions.getHeight(),
44 RenderingHints.VALUE_INTERPOLATION_BILINEAR, true);
45 }
46 }
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66 public static BufferedImage getScaledInstance(BufferedImage image,
67 int targetWidth,
68 int targetHeight,
69 Object hint,
70 boolean higherQuality)
71 {
72 int type = (image.getTransparency() == Transparency.OPAQUE) ?
73 BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;
74 int w, h;
75 if (higherQuality)
76 {
77
78
79
80 w = image.getWidth();
81 h = image.getHeight();
82 }
83 else
84 {
85
86
87 w = targetWidth;
88 h = targetHeight;
89 }
90
91 do
92 {
93 if (higherQuality && w > targetWidth)
94 {
95 w /= 2;
96 if (w < targetWidth)
97 {
98 w = targetWidth;
99 }
100 }
101
102 if (higherQuality && h > targetHeight)
103 {
104 h /= 2;
105 if (h < targetHeight)
106 {
107 h = targetHeight;
108 }
109 }
110
111 BufferedImage tmp = new BufferedImage(w, h, type);
112 Graphics2D g2 = tmp.createGraphics();
113 g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint);
114 g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
115 g2.setComposite(AlphaComposite.SrcOver);
116 g2.drawImage(image, 0, 0, w, h, null);
117 g2.dispose();
118
119 image = tmp;
120 }
121 while (w != targetWidth || h != targetHeight);
122
123 return image;
124 }
125 }