一张原始图像(1920x1080),如果每个像素32bit表示(RGBA),那么,图像需要的内存大小1920x1080x4 = 8294400 Byte
那图像为何可以压缩呢?因为它有很多冗余信息。
比如说,第一行像素基本都一样,假设亮度值Y是这么存的[105比如说,第一行像素基本都一样,假设亮度值Y是这么存的[105 105 105…….105],如果共100个像素,那需要1Byte*100。
最简单的压缩:[105, 100],表示接下来100个像素的亮度都是105,那么只要2个字节,就能表示整行数据了
(1)、写工具类
import?java.awt.Color; import?java.awt.Graphics; import?java.awt.Image; import?java.awt.image.BufferedImage; import?java.awt.image.ConvolveOp; import?java.awt.image.Kernel; import?java.io.File; import?java.io.FileOutputStream; import?java.io.IOException; ? import?javax.swing.ImageIcon; ? import?com.sun.image.codec.jpeg.JPEGCodec; import?com.sun.image.codec.jpeg.JPEGEncodeParam; import?com.sun.image.codec.jpeg.JPEGImageEncoder; ? //java项目www.fhadmin.org public?class?imagesFiler?{ /** ?????*?缩放图片(压缩图片质量,改变图片尺寸) ?????*?若原图宽度小于新宽度,则宽度不变! ?????*?@param?originalFile?原图片路径地址 ?????*?@param?resizedFile?压缩后输出路径地址 ?????*?@param?maxWidth?最大宽度 ?????*?@param?maxHeight?最大高度 ?????*?@param?newWidth?新的宽度 ?????*?@param?quality?图片质量参数?0.7f?相当于70%质量 ?????*/ ????public?static?void?imageResize(File?originalFile,?File?resizedFile, ??????????????????????????????int?maxWidth,int?maxHeight,?float?quality)?throws?IOException?{ ? ????????if?(quality?>?1)?{ ????????????throw?new?IllegalArgumentException( ????????????????????"图片质量需设置在0.1-1范围"); ????????} ? ????????ImageIcon?ii?=?new?ImageIcon(originalFile.getCanonicalPath()); ????????Image?i?=?ii.getImage(); ????????Image?resizedImage?=?null; ? ????????int?iWidth?=?i.getWidth(null); ????????int?iHeight?=?i.getHeight(null); ? ????????int?newWidth?=?maxWidth; ????????if(iWidth?<?maxWidth){ ????????????newWidth?=?iWidth; ????????} ? ? ????????if?(iWidth?>=?iHeight)?{ ????????????resizedImage?=?i.getScaledInstance(newWidth,?(newWidth?*?iHeight) ????????????????????/?iWidth,?Image.SCALE_SMOOTH); ????????} ?? ? ????????int?newHeight?=?maxHeight; ????????if(iHeight?<?maxHeight){ ????????????newHeight?=?iHeight; ????????} ? ????????if(resizedImage==null?&&?iHeight?>=?iWidth){ ????????????resizedImage?=?i.getScaledInstance((newHeight?*?iWidth)?/?iHeight, ????????????????????newHeight,?Image.SCALE_SMOOTH); ????????} ? ????????//此代码确保加载图像中的所有像素 ????????Image?temp?=?new?ImageIcon(resizedImage).getImage(); ? ????????//创建缓冲图像 ????????BufferedImage?bufferedImage?=?new?BufferedImage(temp.getWidth(null), ????????????????temp.getHeight(null),?BufferedImage.TYPE_INT_RGB); ? ????????//将图像复制到缓冲图像 ????????Graphics?g?=?bufferedImage.createGraphics(); ? ???????//清除背景并绘制图像。 ????????g.setColor(Color.white); ????????g.fillRect(0,?0,?temp.getWidth(null),?temp.getHeight(null)); ????????g.drawImage(temp,?0,?0,?null); ????????g.dispose(); ? ????????float?softenFactor?=?0.05f; ????????float[]?softenArray?=?{?0,?softenFactor,?0,?softenFactor, ????????????????1?-?(softenFactor?*?4),?softenFactor,?0,?softenFactor,?0?}; ????????Kernel?kernel?=?new?Kernel(3,?3,?softenArray); ????????ConvolveOp?cOp?=?new?ConvolveOp(kernel,?ConvolveOp.EDGE_NO_OP,?null); ????????bufferedImage?=?cOp.filter(bufferedImage,?null); ? ????????//将jpeg写入文件? ????????FileOutputStream?out?=?new?FileOutputStream(resizedFile); ? ?????????//将图像编码为jpeg数据流 ????????JPEGImageEncoder?encoder?=?JPEGCodec.createJPEGEncoder(out); ? ????????JPEGEncodeParam?param?=?encoder ????????????????.getDefaultJPEGEncodeParam(bufferedImage); ? ????????param.setQuality(quality,?true); ? ????????encoder.setJPEGEncodeParam(param); ????????encoder.encode(bufferedImage); ????}? ??? }
(2)、测试
//java项目www.fhadmin.org public?class?demo?{ public?static?void?main(String[]?args)?throws?Exception{ //需要压缩的图片地址?????aaa.jpg为需要压缩的图片 File?customaryFile?=?new?File(""); //压缩过后输出的路径地址????ddd.jpg?可进行设置为任意名称 File?compressAfter?=?new?File(""); ????????imagesFiler.imageResize(customaryFile,compressAfter,1200,2500,0.8f); } }
(1)、导入jar包
<dependency> <groupId>net.coobird</groupId> <artifactId>thumbnailator</artifactId> <version>0.4.8</version> </dependency>
gradle
implementation?group:?‘net.coobird‘,?name:?‘thumbnailator‘,?version:?‘0.4.14‘
其他工具去maven搜索Thumbnailator
(2)、测试
Thumbnails.of("原图文件的路径")? ????????.scale(1f)? ????????.outputQuality(0.5f)? ????????.toFile("压缩后文件的路径");
?
原文:https://blog.51cto.com/u_14622073/2800989