[原创] Java高清晰高品质 图片压缩

网上搜索了很多,压缩出来的效果实在不能令人满意,研究了一些代码,自己写了一个,压缩出来的效果很好。但是有一个缺点,可能也是java的缺点吧,呵呵。

在jdk1.6以下的版本环境下,压缩部分图片会很慢,经过我测试,如果图片的DPI越高,速度越慢,一般WEB使用图片DPI都是72,速度很快。大家可以试下。我测试了几张DPI为300,印刷品质的图片,大概要35秒左右,当然还和机器内存有关。

在jdk1.6环境下,速度能令人满意,从之前的35秒减少到了1秒多一点点。提升了这么多,jdk1.6改进实在是大。

 

经过我调试发现,慢的部分主要是在g2.drawImage(image, 0, 0,imageWidth, imageHeight, Color.white,null);,这一句。

主要的压缩代码是public static void ImageScale(String path,String fileName,String toFileName) 这个方法。

以下是我的代码,大家可以参考改进。

  1. package sundy.img;
  2. /**
  3.  * ImageCompress 提供用户将大图片按比例压缩为小图片,支持JPG
  4.  * Please refer to: <BR>
  5.  * http://blog.csdn.net/feng_sundy/archive/2008/08/05/2769572.aspx
  6.  * <P>
  7.  * @author feng_sunddy <sundysea@hotmail.com>
  8.  * @version 1.0
  9.  * @see java.awt.image.BufferedImage
  10. **/
  11. import java.awt.BorderLayout;
  12. import java.awt.Button;
  13. import java.awt.TextField;
  14. import java.awt.Color;
  15. import java.awt.Dimension;
  16. import java.awt.FileDialog;
  17. import java.awt.Font;
  18. import java.awt.Frame;
  19. import java.awt.Graphics;
  20. import java.awt.Graphics2D;
  21. import java.awt.Image;
  22. import java.awt.Insets;
  23. import java.awt.Label;
  24. import java.awt.MediaTracker;
  25. import java.awt.Panel;
  26. import java.awt.Toolkit;
  27. import java.awt.event.ActionEvent;
  28. import java.awt.event.ActionListener;
  29. import java.awt.event.WindowAdapter;
  30. import java.awt.event.WindowEvent;
  31. import java.awt.image.BufferedImage;
  32. import java.awt.image.ConvolveOp;
  33. import java.awt.image.Kernel;
  34. import java.io.File;
  35. import java.io.FileNotFoundException;
  36. import java.io.FileOutputStream;
  37. import java.io.IOException;
  38. import com.sun.image.codec.jpeg.JPEGCodec;
  39. import com.sun.image.codec.jpeg.JPEGImageEncoder;
  40. public class ImageCompress extends Frame {
  41.     private static final long serialVersionUID = 48L;
  42.     
  43.     public static void main(String[] args){
  44.         String fileName = "F:/share/bigimages/b-4.jpg";
  45.         String gui = "";
  46.     if (args.length > 0) fileName = args[0];
  47.     if (args.length > 1) gui = "gui";
  48.     if (gui.equals("gui")){
  49.       new ImageCompress(fileName);
  50.     }else{
  51.             long c = System.currentTimeMillis();
  52.             ImageCompress.ImageScale(getFilePath(fileName), getFileFullName(fileName), getFileName(fileName) + "-s." + getFileExt(fileName).toLowerCase());
  53.             System.out.println("elapse time:" + (System.currentTimeMillis() - c)/1000.0f + "s");
  54.       }
  55.     }
  56.     
  57.     private static final String version = "ImageCompress v1.0";
  58.     
  59.   public ImageCompress(String fileName) {
  60.     super(version);
  61.     file = fileName;
  62.     createUI();
  63.     loadImage(fileName);
  64.     setVisible(true);
  65.   }
  66.   /**
  67.    * A Hashtable member variable holds the image processing
  68.    * operations, keyed by their names.
  69.   **/
  70.   
  71.     private Panel mControlPanel;
  72.     
  73.     private BufferedImage mBufferedImage;
  74.     
  75.     private Label labelWidth = new Label("width:");    
  76.     private TextField textWidth = new TextField(7);
  77.   
  78.     private Label labelHeight = new Label("height:");    
  79.     private TextField textHeight = new TextField(7);
  80.     
  81.     private String file;
  82.   /**
  83.    * createUI() creates the user controls and lays out the window.
  84.    * It also creates the event handlers (as inner classes) for
  85.    * the user controls.
  86.   **/
  87.   private void createUI() {
  88.     setFont(new Font("Serif", Font.PLAIN, 12));
  89.     // Use a BorderLayout. The image will occupy most of the window,
  90.     //   with the user controls at the bottom.
  91.     setLayout(new BorderLayout());
  92.   
  93.     // Use a Label to display status messages to the user.
  94.     final Label statusLabel = new Label("Welcome to " + version + ".");
  95.     
  96.     textWidth.setText("160");
  97.     textHeight.setText("160");
  98.     // Create a Button for loading a new image.
  99.     Button loadButton = new Button("Load...");
  100.     // Add a listener for the button. It pops up a file dialog
  101.     //   and loads the selected image file.
  102.     loadButton.addActionListener(new ActionListener() {
  103.       public void actionPerformed(ActionEvent ae) {
  104.         FileDialog fd = new FileDialog(ImageCompress.this);
  105.         fd.setVisible(true);
  106.         if (fd.getFile() == nullreturn;
  107.         String path = fd.getDirectory() + fd.getFile();
  108.         file = path;
  109.         loadImage(path);
  110.       }
  111.     });
  112.     
  113.     Button buttonResize = new Button("Resize");
  114.     buttonResize.addActionListener(new ActionListener(){
  115.         public void actionPerformed(ActionEvent ae){
  116.             resizeImage(file);
  117.             
  118.         }
  119.     });
  120.     // Add the user controls at the bottom of the window.
  121.     mControlPanel = new Panel();
  122.     mControlPanel.add(loadButton);
  123.     mControlPanel.add(labelWidth);
  124.     mControlPanel.add(textWidth);
  125.     mControlPanel.add(labelHeight);
  126.     mControlPanel.add(textHeight);
  127.     mControlPanel.add(buttonResize);
  128.     //mControlPanel.add(processChoice);
  129.     mControlPanel.add(statusLabel);
  130.     add(mControlPanel, BorderLayout.SOUTH);
  131.     // Terminate the application if the user closes the window.
  132.     addWindowListener(new WindowAdapter() {
  133.       public void windowClosing(WindowEvent e) {
  134.         dispose();
  135.         System.exit(0);
  136.       }
  137.     });
  138.   }
  139.   
  140.   private void resizeImage(String fileName){
  141.     try{
  142.         Image image = javax.imageio.ImageIO.read(new File(file));
  143.         int imageWidth = image.getWidth(null);
  144.         int imageHeight = image.getHeight(null);
  145.         
  146.         float scale = getRatio(imageWidth,imageHeight,Integer.parseInt(textWidth.getText()),Integer.parseInt(textWidth.getText()));
  147.         imageWidth = (int)(scale*imageWidth);
  148.         imageHeight = (int)(scale*imageHeight);
  149.         
  150.         image = image.getScaledInstance(imageWidth, imageHeight, Image.SCALE_AREA_AVERAGING);
  151.         // Make a BufferedImage from the Image.
  152.         mBufferedImage = new BufferedImage(imageWidth, imageHeight,BufferedImage.TYPE_INT_RGB);
  153.         Graphics2D g2 = mBufferedImage.createGraphics();
  154.             
  155.         //Map readeringHint = new HashMap();
  156.             //readeringHint.put(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
  157.         //readeringHint.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
  158.         //readeringHint.put(RenderingHints.KEY_COLOR_RENDERING,RenderingHints.VALUE_RENDER_QUALITY);
  159.         //readeringHint.put(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
  160.         //readeringHint.put(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);//VALUE_INTERPOLATION_BICUBIC
  161.         //readeringHint.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
  162.         //g.setRenderingHints(readeringHint);
  163.             
  164.         g2.drawImage(image, 00,imageWidth, imageHeight, Color.white,null);
  165.     
  166.             float[] kernelData2 = { 
  167.                     -0.125f, -0.125f, -0.125f,
  168.             -0.125f,2, -0.125f,
  169.             -0.125f,-0.125f, -0.125f };
  170.         Kernel kernel = new Kernel(33, kernelData2);
  171.         ConvolveOp cOp = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP, null);
  172.         mBufferedImage = cOp.filter(mBufferedImage, null);
  173.         repaint();
  174.         //file = ImageCompress.getFilePath(file) + ImageCompress.getFileName(file) + "-s." + ImageCompress.getFileExt(file).toLowerCase(); 
  175.         //FileOutputStream out = new FileOutputStream(file);
  176.         //JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(bufferedImage);
  177.         //param.setQuality(0.9f, true);
  178.         //encoder.setJPEGEncodeParam(param);
  179.         //JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
  180.         //encoder.encode(mBufferedImage);
  181.         //out.close();      
  182.       }catch (IOException e){
  183.       }
  184.   }
  185.   
  186.   private void loadImage(String fileName) {
  187.     // Use a MediaTracker to fully load the image.
  188.     Image image = Toolkit.getDefaultToolkit().getImage(fileName);
  189.     MediaTracker mt = new MediaTracker(this);
  190.     mt.addImage(image, 0);
  191.     try { mt.waitForID(0); }
  192.     catch (InterruptedException ie) { return; }
  193.     if (mt.isErrorID(0)) return;
  194.     // Make a BufferedImage from the Image.
  195.     mBufferedImage = new BufferedImage(
  196.         image.getWidth(null), image.getHeight(null),
  197.         BufferedImage.TYPE_INT_RGB);
  198.     Graphics2D g2 = mBufferedImage.createGraphics();
  199.     g2.drawImage(image, nullnull);
  200.     adjustToImageSize();
  201.     center();
  202.     validate();
  203.     repaint();
  204.     setTitle(version + ": " + fileName);
  205.   }
  206.   
  207.   private void adjustToImageSize() {
  208.     if (!isDisplayable()) addNotify(); // Do this to get valid Insets.
  209.     Insets insets = getInsets();
  210.     int imageWidth = mBufferedImage.getWidth(); 
  211.     int imageHeight = mBufferedImage.getHeight();
  212.     imageWidth = 600;
  213.     imageHeight = 550;
  214.     int w = imageWidth + insets.left + insets.right;
  215.     int h = imageHeight + insets.top + insets.bottom;
  216.     h += mControlPanel.getPreferredSize().height;
  217.     setSize(w, h);
  218.   }
  219.   
  220.   /**
  221.    * Center this window in the user's desktop.
  222.   **/
  223.   private void center() {
  224.     Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
  225.     Dimension d = getSize();
  226.     int x = (screen.width - d.width) / 2;
  227.     int y = (screen.height - d.height) / 2;
  228.     setLocation(x, y);
  229.   }
  230.   
  231.   /**
  232.    * All paint() has to do is show the current image.
  233.   **/
  234.   public void paint(Graphics g) {
  235.     if (mBufferedImage == nullreturn;
  236.     Insets insets = getInsets();
  237.     g.drawImage(mBufferedImage, insets.left, insets.top, null);
  238.   }
  239.   
  240.   public static void ImageScale(String path,String fileName,String toFileName){
  241.     try {
  242.         Image image = javax.imageio.ImageIO.read(new File(path + fileName));
  243.         int imageWidth = image.getWidth(null);
  244.         int imageHeight = image.getHeight(null);
  245.         float scale = getRatio(imageWidth,imageHeight,130,130);
  246.         imageWidth = (int)(scale*imageWidth);
  247.         imageHeight = (int)(scale*imageHeight);
  248.         
  249.         image = image.getScaledInstance(imageWidth, imageHeight, Image.SCALE_AREA_AVERAGING);
  250.         // Make a BufferedImage from the Image.
  251.         BufferedImage mBufferedImage = new BufferedImage(imageWidth, imageHeight,BufferedImage.TYPE_INT_RGB);
  252.         Graphics2D g2 = mBufferedImage.createGraphics();
  253.             
  254.         //Map readeringHint = new HashMap();
  255.             //readeringHint.put(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
  256.         //readeringHint.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
  257.         //readeringHint.put(RenderingHints.KEY_COLOR_RENDERING,RenderingHints.VALUE_RENDER_QUALITY);
  258.         //readeringHint.put(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
  259.         //readeringHint.put(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);//VALUE_INTERPOLATION_BICUBIC
  260.         //readeringHint.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
  261.         //g.setRenderingHints(readeringHint);
  262.             
  263.         g2.drawImage(image, 00,imageWidth, imageHeight, Color.white,null);
  264.         g2.dispose();
  265.         
  266.             float[] kernelData2 = { 
  267.                     -0.125f, -0.125f, -0.125f,
  268.           -0.125f,2, -0.125f,
  269.           -0.125f,-0.125f, -0.125f };
  270.         Kernel kernel = new Kernel(33, kernelData2);
  271.         ConvolveOp cOp = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP, null);
  272.         mBufferedImage = cOp.filter(mBufferedImage, null);
  273.         FileOutputStream out = new FileOutputStream(path + toFileName);
  274.       //JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(bufferedImage);
  275.       //param.setQuality(0.9f, true);
  276.       //encoder.setJPEGEncodeParam(param);
  277.         JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
  278.         encoder.encode(mBufferedImage);
  279.         out.close();
  280.     }catch (FileNotFoundException fnf){
  281.     }catch (IOException ioe){
  282.     }finally{
  283.     
  284.     }
  285.   }
  286.   
  287.   public static float getRatio(int width,int height,int maxWidth,int maxHeight){
  288.     float Ratio = 1.0f;
  289.     float widthRatio ;
  290.     float heightRatio ;
  291.     widthRatio = (float)maxWidth/width;
  292.     heightRatio = (float)maxHeight/height;
  293.     if(widthRatio<1.0 || heightRatio<1.0){
  294.       Ratio = widthRatio<=heightRatio?widthRatio:heightRatio;
  295.     }
  296.     return Ratio;
  297.   }
  298.   
  299.   public static String getFileExt(String filePath) {
  300.     String tmp = filePath.substring(filePath.lastIndexOf(".") + 1);
  301.     return tmp.toUpperCase();
  302.   }
  303.   public static String getFileName(String filePath) {
  304.     int pos = -1;
  305.     int endPos = -1;
  306.     if (!filePath.equals("")) {
  307.       if (filePath.lastIndexOf("/") != -1) {
  308.         pos = filePath.lastIndexOf("/") + 1;
  309.       } else if (filePath.lastIndexOf("//") != -1) {
  310.         pos = filePath.lastIndexOf("//") + 1;
  311.       }
  312.       if (pos == -1)
  313.         pos = 0;
  314.       filePath = filePath.substring(pos);
  315.       endPos = filePath.lastIndexOf(".");
  316.       if (endPos == -1) {
  317.         return filePath;
  318.       } else {
  319.         return filePath.substring(0, endPos);
  320.       }
  321.     } else {
  322.       return "";
  323.     }
  324.   }
  325.   public static String getFileFullName(String filePath) {
  326.     int pos = -1;
  327.     if (!filePath.equals("")) {
  328.       if (filePath.lastIndexOf("/") != -1) {
  329.         pos = filePath.lastIndexOf("/") + 1;
  330.       } else if (filePath.lastIndexOf("//") != -1) {
  331.         pos = filePath.lastIndexOf("//") + 1;
  332.       }
  333.       if (pos == -1)
  334.         pos = 0;
  335.       return filePath.substring(pos);
  336.     } else {
  337.       return "";
  338.     }
  339.   }
  340.   
  341.   public static String getFilePath(String filePath) {
  342.     int pos = -1;
  343.     if (!filePath.equals("")) {
  344.       if (filePath.lastIndexOf("/") != -1) {
  345.         pos = filePath.lastIndexOf("/") + 1;
  346.       } else if (filePath.lastIndexOf("//") != -1) {
  347.         pos = filePath.lastIndexOf("//") + 1;
  348.       }
  349.       if (pos != -1) {
  350.         return filePath.substring(0, pos);
  351.       } else {
  352.         return "";
  353.       }
  354.     } else {
  355.       return "";
  356.     }
  357.   }
  358. }

源代码下载地址:http://download.csdn.net/source/570936

阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页