Advertisement
Guest User

Kris

a guest
May 18th, 2009
1,119
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 4.37 KB | None | 0 0
  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. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement