SHARE
TWEET

Kris

a guest May 18th, 2009 939 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2. This is re-constructed code I've written.  Although the methods have all been tested, I've
  3. only pasted methods in here for things relevant to the discussion.  I haven't compiled
  4. this exact version.
  5. */
  6.  
  7. public class ImageResizer {
  8.         private static RenderingHints hints;
  9.         static {
  10.                 hints = new RenderingHints(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
  11.                 hints.put(RenderingHints.KEY_COLOR_RENDERING,RenderingHints.VALUE_COLOR_RENDER_QUALITY);
  12.                 hints.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
  13.                
  14.                 /*
  15.                  * this block is to silence the warning that we're not using JAI
  16.                  * native acceleration but are using the pure java implementation.
  17.                  */
  18.                 Properties p = new Properties(System.getProperties());
  19.                 p.put("com.sun.media.jai.disableMediaLib", "true");
  20.                 System.setProperties(p);
  21.         }      
  22.  
  23.     public static BufferedImage getScaledInstance(BufferedImage img, int maxWidth) {
  24.         double scale = (double) maxWidth / img.getWidth();
  25.         if ( scale > 1.0d ) {
  26.                 return getScaledUpGraphics(img, scale);
  27.         } else if (scale > 0.5d && scale < 1.0d) {
  28.                 return getScaledDownByGraphics(img, scale);
  29.         } else if (scale <= 0.5d) {
  30.                 return getScaledDownByJAI(img, scale);
  31.         }
  32.         // else scale == 1.0d; no change required.
  33.         return img;
  34.     }
  35.    
  36.     /**
  37.      * See http://www.digitalsanctuary.com/tech-blog/java/how-to-resize-uploaded-images-using-java-better-way.html
  38.      * This instance seems to produce quality images ONLY when you are
  39.      * scaling down to something less than 50% of the original size.
  40.      * @param img
  41.      * @param scale
  42.      * @return the scaled image
  43.      */
  44.     private static BufferedImage getScaledDownByJAI(BufferedImage img, double scale) {
  45.         if(scale > 1.0d) {
  46.                 throw new RuntimeException("Can't scale according to " + scale + " : This method only scales down.");
  47.         }
  48.         PlanarImage originalImage = PlanarImage.wrapRenderedImage(img);
  49.         // now resize the image
  50.         ParameterBlock paramBlock = new ParameterBlock();
  51.         paramBlock.addSource(originalImage); // The source image
  52.         paramBlock.add(scale); // The xScale
  53.         paramBlock.add(scale); // The yScale
  54.         paramBlock.add(0.0); // The x translation
  55.         paramBlock.add(0.0); // The y translation
  56.  
  57.         RenderedOp resizedImage = JAI.create("SubsampleAverage", paramBlock, hints);
  58.         return resizedImage.getAsBufferedImage();      
  59.     }
  60.    
  61.     /**
  62.      * This method produces high quality images when target scale is greater
  63.      * than 50% of the original.
  64.      * @param img
  65.      * @param scale
  66.      * @return the scaled image
  67.      */
  68.     private static BufferedImage getScaledDownByGraphics(BufferedImage img, double scale) {
  69.         final float scaleFactor = 0.8f;
  70.        
  71.                 BufferedImage ret = (BufferedImage)img;
  72.                 int w = img.getWidth();
  73.                 int h = img.getHeight();
  74.                
  75.                 int targetWidth = (int)(img.getWidth() * scale);
  76.                 int targetHeight = (int)(img.getHeight() * scale);
  77.                
  78.                 int loopCount = 0;
  79.                 int maxLoopCount = 20;
  80.                 BufferedImage tmp;
  81.                 do {
  82.                         if (w > targetWidth) {
  83.                                 w *= scaleFactor;
  84.                                 if (w < targetWidth) {
  85.                                         w = targetWidth;
  86.                                 }
  87.                         }
  88.                         if (h > targetHeight) {
  89.                                 h *= scaleFactor;
  90.                                 if (h < targetHeight) {
  91.                                         h = targetHeight;
  92.                                 }
  93.                         }
  94.                         tmp = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
  95.                         Graphics2D g2 = tmp.createGraphics();
  96.                        
  97.                         g2.addRenderingHints(hints);
  98.                         g2.drawImage(ret, 0, 0, w, h, null);
  99.                         g2.dispose();
  100.                        
  101.                         ret = tmp;
  102.                         if(++loopCount > maxLoopCount) {
  103.                                 throw new RuntimeException("Hit maximum loop count " + maxLoopCount);
  104.                         }
  105.                 } while (w != targetWidth || h != targetHeight);
  106.                 return ret;    
  107.     }
  108.  
  109.     /**
  110.      * When you scale up, there's nothing complicated that will give you a better image.
  111.      * Just scale it up on a basic
  112.      * @param orig
  113.      * @param scale
  114.      * @return
  115.      */
  116.     private static BufferedImage getScaledUpGraphics(final BufferedImage orig, double scale) {
  117.         int scaledWidth  = (int)(orig.getWidth()  * scale);
  118.         int scaledHeight = (int)(orig.getHeight() * scale);
  119.                 BufferedImage scaledBI = new BufferedImage(scaledWidth, scaledHeight, BufferedImage.TYPE_INT_RGB);
  120.                 Graphics2D g = scaledBI.createGraphics();
  121.                 g.setRenderingHints(hints);
  122.                 g.drawImage(orig, 0, 0, scaledWidth, scaledHeight, null);
  123.                 g.dispose();
  124.                 return scaledBI;
  125.         }
  126. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Top