zoukankan      html  css  js  c++  java
  • ImgUtil.java根据长宽压缩图片 根据坐标长宽切图 生成缩率图

    ImgUtil.java根据长宽压缩图片 根据坐标长宽切图 生成缩率图

    package com.beisun.mbp.util;
    import java.awt.Color;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.Image;
    import java.awt.Rectangle;
    import java.awt.image.BufferedImage;
    import java.awt.image.ColorModel;
    import java.io.ByteArrayOutputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.util.Arrays;
    import java.util.Iterator;
    
    import javax.imageio.IIOImage;
    import javax.imageio.ImageIO;
    import javax.imageio.ImageReadParam;
    import javax.imageio.ImageReader;
    import javax.imageio.ImageTypeSpecifier;
    import javax.imageio.ImageWriteParam;
    import javax.imageio.ImageWriter;
    import javax.imageio.metadata.IIOMetadata;
    import javax.imageio.plugins.jpeg.JPEGImageWriteParam;
    import javax.imageio.stream.ImageInputStream;
    import javax.imageio.stream.ImageOutputStream;
    
    import org.w3c.dom.Element;
    
    import com.sun.imageio.plugins.jpeg.JPEGImageWriter;
     
     
    /** 此方法压缩不失真很好用
    * @author zhouqz 
    */ 
    public class ImgUtil { 
     
          /**
         * 图片压缩测试
         * @param args
         */
        public static void main(String args[]){ 
            //读文件夹所有文件进行压缩处理
    //        String f = "/var/upload_bak/"; 
    //        File file = new File(f); 
    //        
    //        if(file.exists()) 
    //        { 
    //            File[] filelist = file.listFiles(); 
    //            for(int i = 0;i<filelist.length;i++) 
    //            { 
    //                String n = filelist[i].getName(); 
    //                Tosmallerpic(f,filelist[i],"_middle",n,185,160,(float)0.7); 
    //                Tosmallerpic(f,filelist[i],"_small",n,45,45,(float)0.7); 
    //                Tosmallerpic(f,filelist[i],"_smaller",n,116,100,(float)0.7); 
    //            } 
    //        } 
             
            //对一个文件进行压缩处理
            
         /* 
        String url = "E:/cims/cimsdata/afr/20160922/"; 
          String name  =  "query_image.jpg";
          img_change(url,name);
         */    
            ImgCompress("E:/cims/cimsdata/afr/20160922/1111111111.jpg");
        }
        
     
        /**********************************好用的压缩方法开始*******************************************/
        /**
         * 图片压缩 
         * @param pathName  图片的路径 压缩图片直接替换当前图片
         */
        public static void    ImgCompress(String pathName){
            int n=pathName.lastIndexOf("/");
            String url=pathName.substring(0,n+1);
            String name=pathName.substring(n+1);
            
            Tosmallerpic(url,new File(url+name),"",name,188,165,(float)0.7); 
        }
        
        
        
        /**
         * 此方法压缩不失真很好用 举例用法
         * @param url    E:/cims/cimsdata/afr/20160922/
         * @param name    1111111.jpg
         */
        public static void img_change(String url,String name) 
        { 
                Tosmallerpic(url,new File(url+name),"_middle",name,188,165,(float)0.7); 
                Tosmallerpic(url,new File(url+name),"_small",name,45,45,(float)0.7); 
                Tosmallerpic(url,new File(url+name),"_smaller",name,116,100,(float)0.7); 
        } 
         
        /** 
        * 
        * @param f 图片所在的文件夹路径 
        * @param file 图片路径 
        * @param ext 扩展名 
        * @param n 图片名 
        * @param w 目标宽 
        * @param h 目标高 
        * @param per 百分比 
        */ 
        private static void  Tosmallerpic(String f,File file,String ext,String n,int w,int h,float per){ 
                Image src; 
                try { 
                    src  =  javax.imageio.ImageIO.read(file); //构造Image对象 
     
                   String img_midname  =  f+n.substring(0,n.indexOf("."))+ext+n.substring(n.indexOf(".")); 
                   int old_w = src.getWidth(null); //得到源图宽 
                   int old_h = src.getHeight(null); 
                   int new_w = 0; 
                   int new_h = 0; //得到源图长 
     
                   double w2 = (old_w*1.00)/(w*1.00); 
                   double h2 = (old_h*1.00)/(h*1.00); 
     
                   //图片跟据长宽留白,成一个正方形图。 
                   BufferedImage oldpic; 
                   if(old_w>old_h) 
                   { 
                       oldpic = new BufferedImage(old_w,old_w,BufferedImage.TYPE_INT_RGB); 
                   }else{if(old_w<old_h){ 
                       oldpic = new BufferedImage(old_h,old_h,BufferedImage.TYPE_INT_RGB); 
                   }else{ 
                        oldpic = new BufferedImage(old_w,old_h,BufferedImage.TYPE_INT_RGB); 
                   } 
                   } 
                    Graphics2D g  =  oldpic.createGraphics(); 
                    g.setColor(Color.white); 
                    if(old_w>old_h) 
                    { 
                        g.fillRect(0, 0, old_w, old_w); 
                        g.drawImage(src, 0, (old_w - old_h) / 2, old_w, old_h, Color.white, null); 
                    }else{ 
                        if(old_w<old_h){ 
                        g.fillRect(0,0,old_h,old_h); 
                        g.drawImage(src, (old_h - old_w) / 2, 0, old_w, old_h, Color.white, null); 
                        }else{ 
                            //g.fillRect(0,0,old_h,old_h); 
                            g.drawImage(src.getScaledInstance(old_w, old_h,  Image.SCALE_SMOOTH), 0,0,null); 
                        } 
                    }              
                    g.dispose(); 
                    src  =  oldpic; 
                    //图片调整为方形结束 
                   if(old_w>w) 
                   new_w = (int)Math.round(old_w/w2); 
                   else 
                       new_w = old_w; 
                   if(old_h>h) 
                   new_h = (int)Math.round(old_h/h2);//计算新图长宽 
                   else 
                       new_h = old_h; 
                   BufferedImage image_to_save  =  new BufferedImage(new_w,new_h,BufferedImage.TYPE_INT_RGB);        
                   image_to_save.getGraphics().drawImage(src.getScaledInstance(new_w, new_h,  Image.SCALE_SMOOTH), 0,0,null); 
                   FileOutputStream fos = new FileOutputStream(img_midname); //输出到文件流 
                    
                   //旧的使用 jpeg classes进行处理的方法
    //               JPEGImageEncoder encoder  =  JPEGCodec.createJPEGEncoder(fos); 
    //               JPEGEncodeParam jep = JPEGCodec.getDefaultJPEGEncodeParam(image_to_save); 
                    /* 压缩质量 */ 
    //               jep.setQuality(per, true); 
    //               encoder.encode(image_to_save, jep); 
                    
                   //新的方法
                   saveAsJPEG(100, image_to_save, per, fos);
                    
                   fos.close(); 
                   } catch (IOException ex) { 
                    //Logger.getLogger(Img_Middle.class.getName()).log(Level.SEVERE, null, ex); 
                } 
        } 
         
       
        /**
         * 以JPEG编码保存图片
         * @param dpi  分辨率
         * @param image_to_save  要处理的图像图片
         * @param JPEGcompression  压缩比
         * @param fos 文件输出流
         * @throws IOException
         */
        public static void saveAsJPEG(Integer dpi ,BufferedImage image_to_save, float JPEGcompression, FileOutputStream fos) throws IOException {
              
            //useful documentation at http://docs.oracle.com/javase/7/docs/api/javax/imageio/metadata/doc-files/jpeg_metadata.html
            //useful example program at http://johnbokma.com/java/obtaining-image-metadata.html to output JPEG data
          
            //old jpeg class
            //com.sun.image.codec.jpeg.JPEGImageEncoder jpegEncoder  =  com.sun.image.codec.jpeg.JPEGCodec.createJPEGEncoder(fos);
            //com.sun.image.codec.jpeg.JPEGEncodeParam jpegEncodeParam  =  jpegEncoder.getDefaultJPEGEncodeParam(image_to_save);
          
            // Image writer
            JPEGImageWriter imageWriter  =  (JPEGImageWriter) ImageIO.getImageWritersBySuffix("jpg").next();
            ImageOutputStream ios  =  ImageIO.createImageOutputStream(fos);
            imageWriter.setOutput(ios);
            //and metadata
            IIOMetadata imageMetaData  =  imageWriter.getDefaultImageMetadata(new ImageTypeSpecifier(image_to_save), null);
             
             
            if(dpi !=  null && !dpi.equals("")){
                 
                 //old metadata
                //jpegEncodeParam.setDensityUnit(com.sun.image.codec.jpeg.JPEGEncodeParam.DENSITY_UNIT_DOTS_INCH);
                //jpegEncodeParam.setXDensity(dpi);
                //jpegEncodeParam.setYDensity(dpi);
          
                //new metadata
                Element tree  =  (Element) imageMetaData.getAsTree("javax_imageio_jpeg_image_1.0");
                Element jfif  =  (Element)tree.getElementsByTagName("app0JFIF").item(0);
                jfif.setAttribute("Xdensity", Integer.toString(dpi) );
                jfif.setAttribute("Ydensity", Integer.toString(dpi));
                 
            }
          
            if(JPEGcompression >= 0 && JPEGcompression <= 1f){
          
                //old compression
                //jpegEncodeParam.setQuality(JPEGcompression,false);
          
                // new Compression
                JPEGImageWriteParam jpegParams  =  (JPEGImageWriteParam) imageWriter.getDefaultWriteParam();
                jpegParams.setCompressionMode(JPEGImageWriteParam.MODE_EXPLICIT);
                jpegParams.setCompressionQuality(JPEGcompression);
          
            }
          
            //old write and clean
            //jpegEncoder.encode(image_to_save, jpegEncodeParam);
          
            //new Write and clean up
            imageWriter.write(imageMetaData, new IIOImage(image_to_save, null, null), null);
            ios.close();
            imageWriter.dispose();
          
        }
        /**********************************好用的压缩方法结束*******************************************/
    
        /**
         * 压缩图片文件 测试发现图片压缩小了会失真 不如上面的方法好用
         * @param srcFilePath    当前图片地址
         * @param descFilePath    压缩后的地址
         * @return
         */
         public static boolean compressPic(String srcFilePath, String descFilePath)  
            {  
                File file = null;  
                BufferedImage src = null;  
                FileOutputStream out = null;  
                ImageWriter imgWrier;  
                ImageWriteParam imgWriteParams;  
          
                // 指定写图片的方式为 jpg  
                imgWrier = ImageIO.getImageWritersByFormatName("jpg").next();  
                imgWriteParams = new javax.imageio.plugins.jpeg.JPEGImageWriteParam(null);  
                // 要使用压缩,必须指定压缩方式为MODE_EXPLICIT  
                imgWriteParams.setCompressionMode(imgWriteParams.MODE_EXPLICIT);  
                // 这里指定压缩的程度,参数qality是取值0~1范围内,  
                imgWriteParams.setCompressionQuality((float)0.1);  
                imgWriteParams.setProgressiveMode(imgWriteParams.MODE_DISABLED);  
                ColorModel colorModel = ColorModel.getRGBdefault();  
                // 指定压缩时使用的色彩模式  
                imgWriteParams.setDestinationType(new javax.imageio.ImageTypeSpecifier(colorModel, colorModel  
                        .createCompatibleSampleModel(16, 16)));  
          
                try  
                {  
                    if(null==srcFilePath||"".equals(srcFilePath))  
                    {  
                        return false;  
                    }  
                    else  
                    {  
                        file = new File(srcFilePath);  
                        src = ImageIO.read(file);  
                        out = new FileOutputStream(descFilePath);  
          
                        imgWrier.reset();  
                        // 必须先指定 out值,才能调用write方法, ImageOutputStream可以通过任何 OutputStream构造  
                        imgWrier.setOutput(ImageIO.createImageOutputStream(out));  
                        // 调用write方法,就可以向输入流写图片  
                        imgWrier.write(null, new IIOImage(src, null, null), imgWriteParams);  
                        out.flush();  
                        out.close();  
                    }  
                }  
                catch(Exception e)  
                {  
                    e.printStackTrace();  
                    return false;  
                }  
                return true;  
            }  
        
         /**
          * 切图 
          * @param fileName
          * @param x
          * @param y
          * @param width
          * @param height
          * @throws IOException
          */
         public static void cutHead(String fileName,int x,int y,int width,int height) throws IOException {
    
                FileInputStream is = null;
                ImageInputStream iis = null;
                try {
                    is = new FileInputStream(fileName+".jpg");
                    Iterator<ImageReader> it = ImageIO
                            .getImageReadersByFormatName("jpg");
                    ImageReader reader = it.next();
                    iis = ImageIO.createImageInputStream(is);
                    reader.setInput(iis, true);
                    ImageReadParam param = reader.getDefaultReadParam();
                    Rectangle rect = new Rectangle(x, y, width, height);
                    param.setSourceRegion(rect);
                    BufferedImage bi = reader.read(0, param);
                    
                    ImageIO.write(bi, "jpg", new File(fileName+"-1"+".jpg"));
    
                } finally {
                    if (is != null)
                        is.close();
                    if (iis != null)
                        iis.close();
                }
    
            }
         
         
         /**缩率图
             * Title: thumbnailImage 测试发现压缩到了大部分图片2K
             * Description: 根据图片路径生成缩略图 
             * @param imagePath    原图片路径
             * @param w            缩略图宽
             * @param h            缩略图高
             * @param prevfix    生成缩略图的前缀
             * @param force        是否强制按照宽高生成缩略图(如果为false,则生成最佳比例缩略图)
             */
            public static void thumbnailImage(File imgFile, int w, int h, String prevfix, boolean force){
                byte[] data=null;
                if(imgFile.exists()){
                    try {
                        // ImageIO 支持的图片类型 : [BMP, bmp, jpg, JPG, wbmp, jpeg, png, PNG, JPEG, WBMP, GIF, gif]
                        String types = Arrays.toString(ImageIO.getReaderFormatNames());
                        String suffix = null;
                        // 获取图片后缀
                        if(imgFile.getName().indexOf(".") > -1) {
                            suffix = imgFile.getName().substring(imgFile.getName().lastIndexOf(".") + 1);
                        }// 类型和图片后缀全部小写,然后判断后缀是否合法
                        if(suffix == null || types.toLowerCase().indexOf(suffix.toLowerCase()) < 0){
                            //logger.error("Sorry, the image suffix is illegal. the standard image suffix is {}." + types);
                            //return null;
                        }
                        //logger.debug("target image's size, {}, height:{}.");
                        Image img = ImageIO.read(imgFile);
                        if(!force){
                            // 根据原图与要求的缩略图比例,找到最合适的缩略图比例
                            int width = img.getWidth(null);
                            int height = img.getHeight(null);
                            if((width*1.0)/w < (height*1.0)/h){
                                if(width > w){
                                    h = Integer.parseInt(new java.text.DecimalFormat("0").format(height * w/(width*1.0)));
                                    //logger.debug("change image's height, {}, height:{}.");
                                }
                            } else {
                                if(height > h){
                                    w = Integer.parseInt(new java.text.DecimalFormat("0").format(width * h/(height*1.0)));
                                    //logger.debug("change image's width, {}, height:{}.");
                                }
                            }
                        }
                        BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
                        
                        Graphics g = bi.getGraphics();
                        g.drawImage(img, 0, 0, w, h, Color.LIGHT_GRAY, null);
                        g.dispose();
                        String p = imgFile.getPath();
                        // 将图片保存在原目录并加上前缀
                        String str=p.substring(0,p.lastIndexOf(File.separator)) + File.separator + prevfix +imgFile.getName();
                        ByteArrayOutputStream out = new ByteArrayOutputStream();  
                        //boolean flag = ImageIO.write(bi, "gif", out);  
                        boolean flag = ImageIO.write(bi, suffix, out);  
                        //如果返回数据的话就把下面的注释打开
                        // data = out.toByteArray();
                        //return data;
                        //些图片到某个路径
                        ImageIO.write(bi, suffix, new File(p.substring(0,p.lastIndexOf(File.separator)) + File.separator + prevfix +imgFile.getName()));
                    } catch (IOException e) {
                        //logger.error("generate thumbnail image failed.",e);
                    }
                }else{
                    //logger.warn("the image is not exist.");
                }
                //return data;
            }
    
    }
  • 相关阅读:
    对虚机设备Bridge ,Vlan, VETH, TAP详细介绍
    DevStack部署Openstack环境
    Ubuntu配置 PPTP 服务器端
    Ubuntu 配置PPTP客户端
    Git学习笔记
    Mysql安装随记,整理内容来源网络
    GitHub访问慢的优化处理
    NetCore部署到Linux服务器+Supervisor的步骤及过程中踩过的坑
    JavaScript的定时器如何先触发一次再延时
    在实现文本框只能输入数字和小数点的基础上实现了价格样式(保留两位小数)
  • 原文地址:https://www.cnblogs.com/nmdzwps/p/5898692.html
Copyright © 2011-2022 走看看