1. package com.itcast.utils;  
  2.  
  3. import java.awt.Color;  
  4. import java.awt.Component;  
  5. import java.awt.Graphics;  
  6. import java.awt.Graphics2D;  
  7. import java.awt.Image;  
  8. import java.awt.MediaTracker;  
  9. import java.awt.Toolkit;  
  10. import java.awt.p_w_picpath.BufferedImage;  
  11. import java.awt.p_w_picpath.ConvolveOp;  
  12. import java.awt.p_w_picpath.Kernel;  
  13. import java.io.ByteArrayOutputStream;  
  14. import java.io.File;  
  15. import java.io.FileInputStream;  
  16. import java.io.FileOutputStream;  
  17. import java.io.IOException;  
  18. import java.io.OutputStream;  
  19.  
  20. import javax.p_w_picpathio.ImageIO;  
  21. import javax.swing.ImageIcon;  
  22.  
  23. import com.sun.p_w_picpath.codec.jpeg.JPEGCodec;  
  24. import com.sun.p_w_picpath.codec.jpeg.JPEGEncodeParam;  
  25. import com.sun.p_w_picpath.codec.jpeg.JPEGImageEncoder;  
  26.  
  27. /**  
  28. * 图像压缩工具  
  29. * @author lihuoming@sohu.com  
  30. *  
  31. */  
  32. public class ImageSizer {  
  33.     public static final MediaTracker tracker = new MediaTracker(new Component() {  
  34.         private static final long serialVersionUID = 1234162663955668507L;}  
  35.     );  
  36.     /**  
  37.      * @param originalFile 原图像  
  38.      * @param resizedFile 压缩后的图像  
  39.      * @param width 图像宽  
  40.      * @param format 图片格式 jpg, png, gif(非动画)  
  41.      * @throws IOException  
  42.      */  
  43.     public static void resize(File originalFile, File resizedFile, int width, String format) throws IOException {  
  44.         if(format!=null && "gif".equals(format.toLowerCase())){  
  45.             resize(originalFile, resizedFile, width, 1);  
  46.             return;  
  47.         }  
  48.         FileInputStream fis = new FileInputStream(originalFile);  
  49.         ByteArrayOutputStream byteStream = new ByteArrayOutputStream();  
  50.         int readLength = -1;  
  51.         int bufferSize = 1024;  
  52.         byte bytes[] = new byte[bufferSize];  
  53.         while ((readLength = fis.read(bytes, 0, bufferSize)) != -1) {  
  54.             byteStream.write(bytes, 0, readLength);  
  55.         }  
  56.         byte[] in = byteStream.toByteArray();  
  57.         fis.close();  
  58.         byteStream.close();  
  59.  
  60.         Image inputImage = Toolkit.getDefaultToolkit().createImage( in );  
  61.         waitForImage( inputImage );  
  62.         int p_w_picpathWidth = inputImage.getWidth( null );  
  63.         if ( p_w_picpathWidth < 1 )  
  64.            throw new IllegalArgumentException( "p_w_picpath width " + p_w_picpathWidth + " is out of range" );  
  65.         int p_w_picpathHeight = inputImage.getHeight( null );  
  66.         if ( p_w_picpathHeight < 1 )  
  67.            throw new IllegalArgumentException( "p_w_picpath height " + p_w_picpathHeight + " is out of range" );  
  68.  
  69.         // Create output p_w_picpath.  
  70.         int height = -1;  
  71.         double scaleW = (double) p_w_picpathWidth / (double) width;  
  72.         double scaleY = (double) p_w_picpathHeight / (double) height;  
  73.         if (scaleW >= 0 && scaleY >=0) {  
  74.             if (scaleW > scaleY) {  
  75.                 height = -1;  
  76.             } else {  
  77.                 width = -1;  
  78.             }  
  79.         }  
  80.         Image outputImage = inputImage.getScaledInstance( width, height, java.awt.Image.SCALE_DEFAULT);  
  81.         checkImage( outputImage );  
  82.         encode(new FileOutputStream(resizedFile), outputImage, format);  
  83.     }  
  84.  
  85.     /** Checks the given p_w_picpath for valid width and height. */  
  86.     private static void checkImage( Image p_w_picpath ) {  
  87.        waitForImage( p_w_picpath );  
  88.        int p_w_picpathWidth = p_w_picpath.getWidth( null );  
  89.        if ( p_w_picpathWidth < 1 )  
  90.           throw new IllegalArgumentException( "p_w_picpath width " + p_w_picpathWidth + " is out of range" );  
  91.        int p_w_picpathHeight = p_w_picpath.getHeight( null );  
  92.        if ( p_w_picpathHeight < 1 )  
  93.           throw new IllegalArgumentException( "p_w_picpath height " + p_w_picpathHeight + " is out of range" );  
  94.     }  
  95.  
  96.     /** Waits for given p_w_picpath to load. Use before querying p_w_picpath height/width/colors. */  
  97.     private static void waitForImage( Image p_w_picpath ) {  
  98.        try {  
  99.           tracker.addImage( p_w_picpath, 0 );  
  100.           tracker.waitForID( 0 );  
  101.           tracker.removeImage(p_w_picpath, 0);  
  102.        } catch( InterruptedException e ) { e.printStackTrace(); }  
  103.     }  
  104.  
  105.     /** Encodes the given p_w_picpath at the given quality to the output stream. */  
  106.     private static void encode( OutputStream outputStream, Image outputImage, String format )  
  107.        throws java.io.IOException {  
  108.        int outputWidth = outputImage.getWidth( null );  
  109.        if ( outputWidth < 1 )  
  110.           throw new IllegalArgumentException( "output p_w_picpath width " + outputWidth + " is out of range" );  
  111.        int outputHeight = outputImage.getHeight( null );  
  112.        if ( outputHeight < 1 )  
  113.           throw new IllegalArgumentException( "output p_w_picpath height " + outputHeight + " is out of range" );  
  114.  
  115.        // Get a buffered p_w_picpath from the p_w_picpath.  
  116.        BufferedImage bi = new BufferedImage( outputWidth, outputHeight,  
  117.           BufferedImage.TYPE_INT_RGB );  
  118.        Graphics2D biContext = bi.createGraphics();  
  119.        biContext.drawImage( outputImage, 0, 0, null );  
  120.        ImageIO.write(bi, format, outputStream);  
  121.        outputStream.flush();  
  122.     }  
  123.  
  124.     /**  
  125.     * 缩放gif图片  
  126.     * @param originalFile 原图片  
  127.     * @param resizedFile 缩放后的图片  
  128.     * @param newWidth 宽度  
  129.     * @param quality 缩放比例 (等比例)  
  130.     * @throws IOException  
  131.     */  
  132.     private static void resize(File originalFile, File resizedFile, int newWidth, float quality) throws IOException {  
  133.         if (quality < 0 || quality > 1) {  
  134.             throw new IllegalArgumentException("Quality has to be between 0 and 1");  
  135.         }  
  136.         ImageIcon ii = new ImageIcon(originalFile.getCanonicalPath());  
  137.         Image i = ii.getImage();  
  138.         Image resizedImage = null;  
  139.         int iWidth = i.getWidth(null);  
  140.         int iHeight = i.getHeight(null);  
  141.         if (iWidth > iHeight) {  
  142.             resizedImage = i.getScaledInstance(newWidth, (newWidth * iHeight) / iWidth, Image.SCALE_SMOOTH);  
  143.         } else {  
  144.             resizedImage = i.getScaledInstance((newWidth * iWidth) / iHeight, newWidth, Image.SCALE_SMOOTH);  
  145.         }  
  146.         // This code ensures that all the pixels in the p_w_picpath are loaded.  
  147.         Image temp = new ImageIcon(resizedImage).getImage();  
  148.         // Create the buffered p_w_picpath.  
  149.         BufferedImage bufferedImage = new BufferedImage(temp.getWidth(null), temp.getHeight(null),  
  150.                                                         BufferedImage.TYPE_INT_RGB);  
  151.         // Copy p_w_picpath to buffered p_w_picpath.  
  152.         Graphics g = bufferedImage.createGraphics();  
  153.         // Clear background and paint the p_w_picpath.  
  154.         g.setColor(Color.white);  
  155.         g.fillRect(0, 0, temp.getWidth(null), temp.getHeight(null));  
  156.         g.drawImage(temp, 0, 0, null);  
  157.         g.dispose();  
  158.         // Soften.  
  159.         float softenFactor = 0.05f;  
  160.         float[] softenArray = {0, softenFactor, 0, softenFactor, 1-(softenFactor*4), softenFactor, 0, softenFactor, 0};  
  161.         Kernel kernel = new Kernel(3, 3, softenArray);  
  162.         ConvolveOp cOp = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP, null);  
  163.         bufferedImage = cOp.filter(bufferedImage, null);  
  164.         // Write the jpeg to a file.  
  165.         FileOutputStream out = new FileOutputStream(resizedFile);  
  166.         // Encodes p_w_picpath as a JPEG data stream  
  167.         JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);  
  168.         JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(bufferedImage);  
  169.         param.setQuality(quality, true);  
  170.         encoder.setJPEGEncodeParam(param);  
  171.         encoder.encode(bufferedImage);  
  172.     }