欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

压缩图片至额定大小

程序员文章站 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);
    }
相关标签: java