`
dingherry
  • 浏览: 67660 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

压缩图片至额定大小

    博客分类:
  • java
阅读更多
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);
    }
分享到:
评论

相关推荐

    友邦大电流接线分线T接端子样本.zip

    而images文件夹则通常包含与文档相关的图片,如产品实物图、结构示意图、接线图等,这些图像信息对理解和使用产品至关重要,因为它们直观地展示了产品的外观和工作原理。 综合以上信息,我们可以推测这篇文档可能...

    SS_Motor.zip.zip

    这通常发生在用户需要通过电子邮件或其他方式传输大型文件时,为了减小文件大小而进行的额外压缩。在Windows或Mac操作系统中,可以通过解压软件(如WinRAR、7-Zip或Zip解压工具)来打开这样的双重压缩文件。 描述中...

    多普 2.5MM 5264条形连接产品介绍.rar

    2.5MM通常指的是连接器的尺寸规格,这在电子硬件领域是很常见的参数,用于标识接口的大小。5264可能是产品的型号或者特定的系列代码,它通常是制造商为了区分不同种类或功能的设备而设定的。条形连接器,也称为线束...

    Legrand 低压配电产品目录(上册).zip

    5.93M 的大小表明这是一个内容丰富的文件,包含了详细的产品图片、说明和技术数据。 **详细知识点:** 1. **低压配电系统**:低压配电系统是建筑电力供应的核心部分,用于将高压电网的电能转换成适合建筑物内部...

    iSee视频监控 v5.2

    视频录像图像质量有多种等级可调,以改变存储文件大小,方便不同场合应用。 视频移动报警录像功能,报警录像灵敏度、预录像时间、延迟录像时间可调,支持声音 报警输出。 智能检索,可按摄像镜头年/月/日/时间...

    九年级物理下册期末检测卷9新版苏科版

    图片未给出,但根据描述,需要识别哪种剪刀在正常使用时会是费力杠杆。 2. 滑轮组的机械效率:第二个选择题涉及到滑轮组的机械效率,机械效率是指有用功与总功的比率。若G1=G2,说明提升的重量相同,但甲和乙的滑轮...

    人力资源管理软件(完全免费)

    人力资源管理软件支持照片的打印(照片对象标识 emp_pict,类型为图片)(感谢Lucky Cat) 员工编辑和管理体现工龄和年龄(打印标识对应age、work_age、work_age_c)(感谢hui~星辉~) 一个岗位允许对应多个部门...

Global site tag (gtag.js) - Google Analytics