View Javadoc

1   package com.atlassian.core.util.thumbnail;
2   
3   import com.atlassian.core.util.ReusableBufferedInputStream;
4   import com.google.common.base.Predicate;
5   import org.apache.commons.io.IOUtils;
6   import org.apache.log4j.Logger;
7   
8   import java.awt.image.BufferedImage;
9   import java.io.IOException;
10  import java.io.InputStream;
11  
12  public class ThumbnailRenderer
13  {
14  
15      private final static Logger log = Logger.getLogger(ThumbnailRenderer.class);
16  
17      private final Predicate<Dimensions> rasterBasedRenderingThreshold;
18      private final ImageScaler memoryImageScaler;
19      private final ImageScaler streamImageScaler;
20      private final DimensionsHelper dimensionsHelper;
21  
22      public ThumbnailRenderer(ImageScaler rasterScaler, ImageScaler streamScaler, DimensionsHelper dimensionsHelper, Predicate<Dimensions> rasterBasedRenderingThreshold)
23      {
24          this.rasterBasedRenderingThreshold = rasterBasedRenderingThreshold;
25          this.memoryImageScaler = rasterScaler;
26          this.streamImageScaler = streamScaler;
27          this.dimensionsHelper = dimensionsHelper;
28      }
29  
30      /**
31       * Create a {@link BufferedImage} from the input stream.
32       *
33       * @param inputStream   - The stream that contains the image data
34       * @param maxWidth      - The maximum width of the thumbnail - this renderer maintains the aspect ratio of the original image
35       * @param maxHeight     - The maximum height of the thumbnail - this renderer maintains the aspect ratio of the original image
36       * @return BufferedImage that is at most {@code maxWidth}x{@code maxHeight}, never returns null
37       */
38      public BufferedImage createThumbnailImage(final InputStream inputStream, final int maxWidth, final int maxHeight)
39      {
40          ReusableBufferedInputStream reusableInputStream = new ReusableBufferedInputStream(inputStream);
41          try
42          {
43              final Dimensions originalImageDimensions = dimensionsHelper.dimensionsForImage(reusableInputStream);
44              if (!rasterBasedRenderingThreshold.apply(originalImageDimensions))
45              {
46                  log.debug(String.format("Image dimensions (%s) exceed the threshold for raster based image manipulation. Using stream based renderer.", originalImageDimensions));
47                  return streamImageScaler.scaleImage(maxWidth, maxHeight, reusableInputStream);
48              }
49              return memoryImageScaler.scaleImage(maxWidth, maxHeight, reusableInputStream);
50          }
51          catch (IOException e)
52          {
53              throw new ThumbnailRenderException(e);
54          }
55          finally
56          {
57              IOUtils.closeQuietly(inputStream);
58              try
59              {
60                  reusableInputStream.destroy();
61              }
62              catch (IOException e)
63              {
64                  // Do nothing
65              }
66          }
67      }
68  }