压缩图片至额定大小
程序员文章站
2022-06-08 20:18:10
...
import java.awt.Color; import java.awt.Graphics2D; import java.awt.Image; import java.awt.image.BufferedImage; import java.awt.image.ConvolveOp; import java.awt.image.Kernel; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.net.URLConnection; import javax.imageio.ImageIO; import com.sun.image.codec.jpeg.JPEGCodec; import com.sun.image.codec.jpeg.JPEGEncodeParam; import com.sun.image.codec.jpeg.JPEGImageEncoder; /** * 根据图片路径压缩图片至额定大小 * @param picUrl 需要压缩的图片路径 * @param scale 压缩比例 不能大于1,默认0.5 * @param quality 压缩品质介于0.1~1.0之间,默认0.75 * @param imgSize 图片大小压缩上限 * @param img 二次压缩图片对象 * @return * @throws IOException */ public static byte[] imageCompress(String picUrl, float scale, float quality, long imgSize, Image img) throws IOException{ Image image = null; if(img == null){//第一次是读取image //根据图片路径获取图片转为字节输入流 URL url = new URL(picUrl); URLConnection uc = url.openConnection(); InputStream in = uc.getInputStream(); //字节输入流转为要输出流 ByteArrayOutputStream swapStream = new ByteArrayOutputStream(); byte[] buff = new byte[100]; int rc = 0; while ((rc = in.read(buff)) > 0) { swapStream.write(buff, 0, rc); } byte[] imagSize = swapStream.toByteArray(); // System.out.println("图片实际大小:"+imagSize.length); //如果图片本身大小已在限额内则直接返回图片字节输出流 if(imagSize.length <= imgSize) return imagSize; else image = javax.imageio.ImageIO.read(url); } else{//第二次开始不读图片,直接把第一次的图片压缩 image = img; } //图片本身大小已超过限额,则根据比率从尺寸上降低 int imageWidth = image.getWidth(null); int imageHeight = image.getHeight(null); imageWidth = (int)(scale*imageWidth); imageHeight = (int)(scale*imageHeight); image = image.getScaledInstance(imageWidth, imageHeight, Image.SCALE_AREA_AVERAGING); // Make a BufferedImage from the Image. BufferedImage mBufferedImage = new BufferedImage(imageWidth, imageHeight,BufferedImage.TYPE_INT_RGB); Graphics2D g2 = mBufferedImage.createGraphics(); g2.drawImage(image, 0, 0,imageWidth, imageHeight, Color.white,null); g2.dispose(); float[] kernelData2 = { -0.125f, -0.125f, -0.125f, -0.125f,2, -0.125f, -0.125f,-0.125f, -0.125f}; Kernel kernel = new Kernel(3, 3, kernelData2); ConvolveOp cOp = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP, null); mBufferedImage = cOp.filter(mBufferedImage, null); ByteArrayOutputStream out = new ByteArrayOutputStream(); JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out); JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(mBufferedImage); // System.out.println(quality); //降低图像品质(不是降低DPI) param.setQuality(quality, true);// encoder.setJPEGEncodeParam(param); encoder.encode(mBufferedImage); byte[] comImage = out.toByteArray(); // System.out.println(comImage.length); if(comImage.length > imgSize){//如果图像压缩后大小还是超过限额则继续降低压缩比率降低品质 scale = scale - 0.10f; quality = quality - 0.10f; imageCompress(picUrl, scale, quality, imgSize, image); } return comImage; } /** * 压缩图片到指定品质和比例 * @param picUrl 需要压缩的图片路径 * @param fileName 要压缩的图片名称 * @param toFileName 压缩后的图片名称 * @param scale 压缩比例 不能大于1,默认0.5 * @param quality 压缩品质介于0.1~1.0之间 */ @SuppressWarnings("unused") private static void imageCompress(String picUrl, String fileName,String toFileName, float scale, float quality){ try { long start = System.currentTimeMillis(); Image image = javax.imageio.ImageIO.read(new File(picUrl + fileName)); int imageWidth = image.getWidth(null); int imageHeight = image.getHeight(null); imageWidth = (int)(scale*imageWidth); imageHeight = (int)(scale*imageHeight); image = image.getScaledInstance(imageWidth, imageHeight, Image.SCALE_AREA_AVERAGING); // Make a BufferedImage from the Image. BufferedImage mBufferedImage = new BufferedImage(imageWidth, imageHeight,BufferedImage.TYPE_INT_RGB); Graphics2D g2 = mBufferedImage.createGraphics(); g2.drawImage(image, 0, 0,imageWidth, imageHeight, Color.white,null); g2.dispose(); float[] kernelData2 = { -0.125f, -0.125f, -0.125f, -0.125f,2, -0.125f, -0.125f,-0.125f, -0.125f }; Kernel kernel = new Kernel(3, 3, kernelData2); ConvolveOp cOp = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP, null); mBufferedImage = cOp.filter(mBufferedImage, null); FileOutputStream out = new FileOutputStream(picUrl + toFileName); JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out); JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(mBufferedImage); param.setQuality(quality, true);//默认0.75 encoder.setJPEGEncodeParam(param); encoder.encode(mBufferedImage); out.close(); long end = System.currentTimeMillis(); System.out.println("图片:"+fileName+",压缩时间:"+(end - start) + "ms"); }catch (FileNotFoundException fnfe){ fnfe.printStackTrace(); }catch (IOException ioe){ ioe.printStackTrace(); }catch(Exception ex){ ex.printStackTrace(); } }
调用实例
public static void main(String[] args){ PicUtil.imageCompress("D:\\", "background_new.png", "background_new2.png", 0.9f, 0.9f); }
上一篇: 还要再来一杯