图片压缩与裁剪

1、图片按比例压缩

/** 
     * 根据缩放后图片的宽和高计算缩放的比例 
     * @param imgInputStream  图片的文件流 
     * @param picWidth   缩放后图片的宽
     * @param picHeight  缩放后的图片的高度 
     * @return 返回缩放后的图片的缓存 
     */  
    public static Map<String,Object> equalScale(InputStream imgInputStream, int picWidth, int picHeight){
    Map<String,Object> map = new HashMap<String,Object>();
        try {  
            BufferedImage buffer = ImageIO.read(imgInputStream);
            map.put("buffer", buffer);
            int width = buffer.getWidth(null);  //图片原宽度
            int height = buffer.getHeight(null);  //图片原高度
            int newwidth = 0;// 最终宽度
int newheight = 0;// 最终高度
//逻辑判断
if (width>height) {// 宽大于高。
if (width > picWidth) {
int _temp_height = (height * picWidth / width);
newwidth=picWidth;
newheight=_temp_height;
if(_temp_height>picHeight){
int _temp_width = (picWidth * picHeight / _temp_height);
newwidth=_temp_width;
newheight=picHeight;
}
} else {
newwidth=width;
newheight=height;
}
} else {
if (height > picHeight) {
int _temp_width = (width * picHeight / height);
newwidth=_temp_width;
newheight=picHeight;
if(_temp_width>picWidth){
int _temp_height = (height * picWidth / picWidth);
newwidth=picWidth;
newheight=_temp_height;
}
} else {
newwidth=width;
newheight=height;
}
}
            map.put("width", newwidth) ;
            map.put("height", newheight);
            return map;
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
        return null;  
    }  


/**

* @Description: 保留图片本身格式的压缩
* @param imgInputStream 文件输入流
* @param imgOutputStream 文件输出流
* @param w 宽
* @param h 高
* @param ext 扩展名
*/
public   static   void  scaleImage1(InputStream imgInputStream,OutputStream imgOutputStream,  int  w,int h,String ext)
    {
         try 
        {
        Map<String,Object> map = equalScale(imgInputStream,w,h);
        int width = map.get("width")==null?w:Integer.valueOf(map.get("width").toString());
        int height = map.get("height")==null?h:Integer.valueOf(map.get("height").toString());
        Image src  = (BufferedImage) map.get("buffer");
        BufferedImage bufferedImage  =   new  BufferedImage(width, height,BufferedImage.TYPE_INT_RGB);


      // Soften.
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);

            bufferedImage.getGraphics().drawImage(
                    src.getScaledInstance(width, height, Image.SCALE_SMOOTH),
                     0 ,  0 ,  null );
            
            ImageIO.write(bufferedImage, ext, imgOutputStream); 
        }
         catch  (IOException e)
        {
            e.printStackTrace();
        }
         finally{
        if(imgInputStream !=null)
try {
imgInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
        if(imgOutputStream !=null)
try {
imgOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
         }
    }



2、图片按坐标及高宽裁剪

 /** 
     *  
     * 对图片裁剪,并把裁剪完蛋新图片保存 。
     *  @param  is 要裁剪的文件流

     * @param x  x坐标

     * @param y y坐标

     * @param width 宽

     * @param  height  高

     *  @param thumbOutstream  新图片的输出流

     * @param  ext 裁剪格式
     */  
  
    public static void cut(InputStream is,int x,int y,int width,int height, OutputStream thumbOutstream,String ext) throws IOException {  
//        FileInputStream is = null;  
        ImageInputStream iis = null;  
        try {  
            // 读取图片文件  
//            is = new FileInputStream(srcpath);  
  
            /** 
             *  
             * 返回包含所有当前已注册 ImageReader 的 Iterator,这些 ImageReader 
             *  
             * 声称能够解码指定格式。 参数:formatName - 包含非正式格式名称 . 
             *  
             * (例如 "jpeg" 或 "tiff")等 。 
             */  
            Iterator<ImageReader> it = ImageIO  
                    .getImageReadersByFormatName(ext);  
  
            ImageReader reader = it.next();  
  
            // 获取图片流  
            iis = ImageIO.createImageInputStream(is);  
  
            /** 
             *  
             * <p> 
             * iis:读取源。true:只向前搜索 
             * </p> 
             * .将它标记为 ‘只向前搜索’。 
             *  
             * 此设置意味着包含在输入源中的图像将只按顺序读取,可能允许 reader 
             *  
             * 避免缓存包含与以前已经读取的图像关联的数据的那些输入部分。 
             */  
            reader.setInput(iis, true);  
  
            /** 
             *  
             * <p> 
             * 描述如何对流进行解码的类 
             * <p> 
             * .用于指定如何在输入时从 Java Image I/O 
             *  
             * 框架的上下文中的流转换一幅图像或一组图像。用于特定图像格式的插件 
             *  
             * 将从其 ImageReader 实现的 getDefaultReadParam 方法中返回 
             *  
             * ImageReadParam 的实例。 
             */  
            ImageReadParam param = reader.getDefaultReadParam();  
  
            /** 
             *  
             * 图片裁剪区域。Rectangle 指定了坐标空间中的一个区域,通过 Rectangle 对象 
             *  
             * 的左上顶点的坐标(x,y)、宽度和高度可以定义这个区域。 
             */  
            Rectangle rect = new Rectangle(x, y, width, height);  
  
            // 提供一个 BufferedImage,将其用作解码像素数据的目标。  
            param.setSourceRegion(rect);  
  
            /** 
             *  
             * 使用所提供的 ImageReadParam 读取通过索引 imageIndex 指定的对象,并将 
             *  
             * 它作为一个完整的 BufferedImage 返回。 
             */  
            BufferedImage bi = reader.read(0, param);
  
            // 保存新图片  
            ImageIO.write(bi, ext, thumbOutstream); 
            
        } finally {  
            if (is != null)  
                is.close();  
            if (iis != null)  
                iis.close();  
        }  
  
    }  



注:获取图片真实的文件格式通过  

BufferedInputStream is = new BufferedInputStream(file.getInputStream());
String type = URLConnection.guessContentTypeFromStream(is);
   if(type == null) {
 throw new IOException("can't get mime type of image");
}
is.close();

获取;不能通过String type =file.getContentType();  或 通过源文件名的扩展名,不然用户随意更改文件的扩展名,会导致裁剪不成功。

String ext = type.substring(type.indexOf("/")+1, type.length());

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值