• 利用ImageIO压缩图片



    参考上面文章,测试了下 很好用!
    500kb左右的图片,压缩4次,1秒内完毕。

    
    import java.awt.AWTException;
    import java.awt.Dimension;
    import java.awt.Rectangle;
    import java.awt.image.BufferedImage;
    import java.awt.image.ColorModel;
    import java.io.ByteArrayInputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.Calendar;
    import java.util.GregorianCalendar;
    import java.util.Iterator;
    
    import javax.imageio.IIOImage;
    import javax.imageio.ImageIO;
    import javax.imageio.ImageReader;
    import javax.imageio.ImageWriteParam;
    import javax.imageio.ImageWriter;
    import javax.imageio.stream.ImageInputStream;
    import javax.imageio.stream.MemoryCacheImageInputStream;
    
    import com.sun.image.codec.jpeg.JPEGCodec;
    import com.sun.image.codec.jpeg.JPEGEncodeParam;
    import com.sun.image.codec.jpeg.JPEGImageEncoder;
    
    public class ImageTest {
    	/**
    	 * @param args
    	 * @throws AWTException
    	 * @throws IOException 
    	 * @throws FileNotFoundException 
    	 */
    	public void getImageSize() throws AWTException, FileNotFoundException, IOException {
    		java.awt.Robot rb = new java.awt.Robot();
    		Dimension d = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
    		Rectangle rt = new Rectangle(0, 0, (int) d.getWidth(), (int) d
    				.getHeight());
    		BufferedImage image= readMemoryImage(readBytes(new FileInputStream("C:/Users/Administrator/Desktop/2.jpg")));
    		System.out.println(image.getHeight());
    		byte[] picByte = bufferedImageTobytes(image, "gif");
    		byte[] picByte2 = bufferedImageTobytes(image, "jpeg");
    		byte[] picByte3 = bufferedImageTobytes(image, 0.9f);
    		byte[] picByte4 = newCompressImage(image, 0.4f);
    		FileOutputStream f=new FileOutputStream("C:/Users/Administrator/Desktop/2-1.gif");
    		FileOutputStream f2=new FileOutputStream("C:/Users/Administrator/Desktop/2-2.jpg");
    		FileOutputStream f3=new FileOutputStream("C:/Users/Administrator/Desktop/2-3.jpg");
    		FileOutputStream f4=new FileOutputStream("C:/Users/Administrator/Desktop/2-4.jpg");
    		f.write(picByte);
    		f2.write(picByte2);
    		f3.write(picByte3);
    		f4.write(picByte4);
    		f.close();
    		f2.close();
    		f3.close();
    		f4.close();
    	}
    	
        /**
         * 从内存字节数组中读取图像
         * 
         * @param imgBytes
         *            未解码的图像数据
         * @return 返回 {@link BufferedImage}
         * @throws IOException
         *             当读写错误或不识别的格式时抛出
         */
    	  public static final BufferedImage readMemoryImage(byte[] imgBytes) throws IOException {
    	        if (null == imgBytes || 0 == imgBytes.length)
    	            throw new NullPointerException("the argument 'imgBytes' must not be null or empty");
    	        // 将字节数组转为InputStream,再转为MemoryCacheImageInputStream
    	        ImageInputStream imageInputstream = new MemoryCacheImageInputStream(new ByteArrayInputStream(imgBytes));
    	        // 获取所有能识别数据流格式的ImageReader对象
    	        Iterator it = ImageIO.getImageReaders(imageInputstream);
    	        // 迭代器遍历尝试用ImageReader对象进行解码
    	        while (it.hasNext()) {
    	            ImageReader imageReader = it.next();
    	            // 设置解码器的输入流
    	            imageReader.setInput(imageInputstream, true, true);
    	            // 图像文件格式后缀
    	            String suffix = imageReader.getFormatName().trim().toLowerCase();
    	            // 图像宽度
    	            int width = imageReader.getWidth(0);
    	            // 图像高度
    	            int height = imageReader.getHeight(0);
    	            System.out.printf("format %s,%dx%d
    ", suffix, width, height);
    	            try {
    	                // 解码成功返回BufferedImage对象
    	                // 0即为对第0张图像解码(gif格式会有多张图像),前面获取宽度高度的方法中的参数0也是同样的意思
    	                 return imageReader.read(0, imageReader.getDefaultReadParam());
    	            } catch (Exception e) {
    	                imageReader.dispose();
    	                // 如果解码失败尝试用下一个ImageReader解码
    	            }
    	        }
    	        imageInputstream.close();
    	        // 没有能识别此数据的图像ImageReader对象,抛出异常
    	        throw new IOException("unsupported image format");
    	    }
    	  
    	    /**
    	     * 从{@link InputStream}读取字节数组
    * 结束时会关闭{@link InputStream}
    * {@code in}为{@code null}时抛出{@link NullPointerException} * * @param in * @return 字节数组 * @throws IOException */ public static final byte[] readBytes(InputStream in) throws IOException { if (null == in) throw new NullPointerException("the argument 'in' must not be null"); try { int buffSize = Math.max(in.available(), 1024 * 8); byte[] temp = new byte[buffSize]; ByteArrayOutputStream out = new ByteArrayOutputStream(buffSize); int size = 0; while ((size = in.read(temp)) != -1) { out.write(temp, 0, size); } return out.toByteArray(); } finally { in.close(); } } /** * 用Format对应格式中ImageIO默认参数把IMAGE打包成BYTE[] * @param image * @return */ private byte[] bufferedImageTobytes(BufferedImage image, String format) { System.out.println(format + "格式开始打包" + getCurrentTime()); ByteArrayOutputStream out = new ByteArrayOutputStream(); try { ImageIO.write(image, format, out); } catch (IOException e) { e.printStackTrace(); } System.out.println(format + "格式完成打包-----" + getCurrentTime() + "----lenth------" + out.toByteArray().length); return out.toByteArray(); } /** * * 自己设置压缩质量来把图片压缩成byte[] * * @param image * 压缩源图片 * @param quality * 压缩质量,在0-1之间, * @return 返回的字节数组 */ private byte[] bufferedImageTobytes(BufferedImage image, float quality) { System.out.println("jpeg" + quality + "质量开始打包" + getCurrentTime()); // 如果图片空,返回空 if (image == null) { return null; } // 得到指定Format图片的writer Iterator iter = ImageIO .getImageWritersByFormatName("jpeg");// 得到迭代器 ImageWriter writer = (ImageWriter) iter.next(); // 得到writer // 得到指定writer的输出参数设置(ImageWriteParam ) ImageWriteParam iwp = writer.getDefaultWriteParam(); iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); // 设置可否压缩 iwp.setCompressionQuality(quality); // 设置压缩质量参数 iwp.setProgressiveMode(ImageWriteParam.MODE_DISABLED); ColorModel colorModel = ColorModel.getRGBdefault(); // 指定压缩时使用的色彩模式 iwp.setDestinationType(new javax.imageio.ImageTypeSpecifier(colorModel, colorModel.createCompatibleSampleModel(16, 16))); // 开始打包图片,写入byte[] ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); // 取得内存输出流 IIOImage iIamge = new IIOImage(image, null, null); try { // 此处因为ImageWriter中用来接收write信息的output要求必须是ImageOutput // 通过ImageIo中的静态方法,得到byteArrayOutputStream的ImageOutput writer.setOutput(ImageIO .createImageOutputStream(byteArrayOutputStream)); writer.write(null, iIamge, iwp); } catch (IOException e) { System.out.println("write errro"); e.printStackTrace(); } System.out.println("jpeg" + quality + "质量完成打包-----" + getCurrentTime() + "----lenth----" + byteArrayOutputStream.toByteArray().length); return byteArrayOutputStream.toByteArray(); } /** * 自己定义格式,得到当前系统时间 * * @return */ private String getCurrentTime() { Calendar c = new GregorianCalendar(); int hour = c.get(Calendar.HOUR_OF_DAY); int min = c.get(Calendar.MINUTE); int second = c.get(Calendar.SECOND); int millsecond = c.get(Calendar.MILLISECOND); String time = hour + "点" + min + "分" + second + "秒" + millsecond; return time; } /** * 通过 com.sun.image.codec.jpeg.JPEGCodec提供的编码器来实现图像压缩 * @param image * @param quality * @return */ private byte[] newCompressImage(BufferedImage image, float quality) { // 如果图片空,返回空 if (image == null) { return null; } // 开始开始,写入byte[] ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); // 取得内存输出流 // 设置压缩参数 JPEGEncodeParam param = JPEGCodec.getDefaultJPEGEncodeParam(image); param.setQuality(quality, false); // 设置编码器 JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder( byteArrayOutputStream, param); System.out.println("newCompressive" + quality + "质量开始打包" + getCurrentTime()); try { encoder.encode(image); } catch (Exception ef){ ef.printStackTrace(); } System.out.println("newCompressive" + quality + "质量打包完成" + getCurrentTime() + "----lenth----" + byteArrayOutputStream.toByteArray().length); return byteArrayOutputStream.toByteArray(); } public static void main(String args[]) throws Exception { ImageTest test = new ImageTest(); test.getImageSize(); } }


  • 相关阅读:
    两道简单的机试题目
    C#二维数组(矩形数组,交错数组)
    用实例展示left Join,right join,inner join,join,cross join,union 的区别
    React 中的 Redux 详解:
    react 组件通信:
    vue 入门, todoList
    Vue 动画
    vue 框架,入门必看
    koa2 的使用方法:(一)
    git 的使用:
  • 原文地址:https://www.cnblogs.com/thewindkee/p/12873261.html
Copyright © 2020-2023  润新知