背景:
现在的网站为提升与用户的交互,上传文件是难免的,用户上传的图片多种多样,方面有文件大小,尺寸,等等为了处理此类的问题。服务器端必须实现对用户上传的图片进行相应的处理以适应网站的需要。其中最重要的就是压缩图片,将用户上传的图片压缩成宽度等比里大小的图片。
实现方式:
java实现图片压缩:java有实现图片压缩的jar包,压缩的源文件的格式包括bmp,jig,jpg等等,还有的是压缩动态图片jar,但要购买。价格是好像要几百块人民币。接下里演示的是一个实现简单图片压缩的代码,不包括动态图片,免费的。
代码不是我写的,我在一个论坛看到的。但我测试过可以实现图片的压缩,可以随便看一下。
1 package cn.hp.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.image.BufferedImage; 11 import java.awt.image.ConvolveOp; 12 import java.awt.image.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.imageio.ImageIO; 21 import javax.swing.ImageIcon; 22 23 import com.sun.image.codec.jpeg.JPEGCodec; 24 import com.sun.image.codec.jpeg.JPEGEncodeParam; 25 import com.sun.image.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 imageWidth = inputImage.getWidth( null ); 63 if ( imageWidth < 1 ) 64 throw new IllegalArgumentException( "image width " + imageWidth + " is out of range" ); 65 int imageHeight = inputImage.getHeight( null ); 66 if ( imageHeight < 1 ) 67 throw new IllegalArgumentException( "image height " + imageHeight + " is out of range" ); 68 69 // Create output image. 70 int height = -1; 71 double scaleW = (double) imageWidth / (double) width; 72 double scaleY = (double) imageHeight / (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 image for valid width and height. */ 86 private static void checkImage( Image image ) { 87 waitForImage( image ); 88 int imageWidth = image.getWidth( null ); 89 if ( imageWidth < 1 ) 90 throw new IllegalArgumentException( "image width " + imageWidth + " is out of range" ); 91 int imageHeight = image.getHeight( null ); 92 if ( imageHeight < 1 ) 93 throw new IllegalArgumentException( "image height " + imageHeight + " is out of range" ); 94 } 95 96 /** Waits for given image to load. Use before querying image height/width/colors. */ 97 private static void waitForImage( Image image ) { 98 try { 99 tracker.addImage( image, 0 ); 100 tracker.waitForID( 0 ); 101 tracker.removeImage(image, 0); 102 } catch( InterruptedException e ) { e.printStackTrace(); } 103 } 104 105 /** Encodes the given image 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 image width " + outputWidth + " is out of range" ); 111 int outputHeight = outputImage.getHeight( null ); 112 if ( outputHeight < 1 ) 113 throw new IllegalArgumentException( "output image height " + outputHeight + " is out of range" ); 114 115 // Get a buffered image from the image. 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 image are loaded. 147 Image temp = new ImageIcon(resizedImage).getImage(); 148 // Create the buffered image. 149 BufferedImage bufferedImage = new BufferedImage(temp.getWidth(null), temp.getHeight(null), 150 BufferedImage.TYPE_INT_RGB); 151 // Copy image to buffered image. 152 Graphics g = bufferedImage.createGraphics(); 153 // Clear background and paint the image. 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 image 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 } 173 }
简单的单元测试类。
1 package junit.test; 2 3 import java.io.File; 4 import java.io.IOException; 5 6 import org.junit.Test; 7 8 import cn.hp.utils.ImageSizer; 9 10 11 public class ImageTest { 12 @Test 13 public void createImage(){ 14 try { 15 ImageSizer.resize(new File("d:\12.jpg"), new File("d:\testabc.jpg"), 200, "jpg"); 16 } catch (IOException e) { 17 e.printStackTrace(); 18 } 19 } 20 21 }
发现经过压缩后的图片大小变化了。
压缩前的图片大小
压缩后的图片大小