Java+Javascript图片裁剪简单封装

在做项目的过程中,有很多时候前端的图片会出现拉伸现象,所以在上传图片的时候,图片裁剪是必不可少的。所以有了封装一个图片裁剪工具的念头,下面是实现步骤:

1.首先选择一个前台裁剪工具,我这里使用的是Jcrop-0.9.12。

2.开始编写前端js代码:

我这里把前端封装成一个函数

/**
     * 初始化裁剪工具。
     * @param divId 定义生成填充页面代码的div(函数产生的代码会填充到此div内)
     * @param imagePath 图片地址
     * @param ratio 宽长比例
     * @param callback  裁剪之后的回调
     */

function initJcrop(divId,imagePath,ratio,callback)
               {
                   var postRatio=1;
                   var jcrop_api;
                   //外边框宽度和高度
                   var divWidth=800;
                   var divHeitht=divWidth/ratio;
                   //图片最大宽度和高度
                   var imageMaxWidth = divWidth*0.8;
                   var imageMaxHeight = divHeitht*0.8;
                   if($("#tempDiv").html()==null){
                         var tempDivHtml='<div id="tempDiv" style="position: fixed; border: 1px solid #ddd; left: 50%; top: 50%; '+divWidth+'px;  margin-left: -400px; margin-top: -400px;  z-index: 3; background:#fff; border-radius: 10px; box-shadow: 0px 0px 20px 0px #000;  text-align: center;align:center">'+
                                '<h1 style="text-align: center; font-size: 20px; padding-top: 20px;">图片裁剪</h1>'+
                              '<div style="margin: 20px 50px; overflow: hidden; height:auto;">'+
                              '<img id="jcropImg" src="'+imagePath+'">'+
                              '<p>'+
                              '<input type="button" id="saveButton" value="确定" style=" 120px; height: 40px; margin: 10px 80px; background: #fff; border: 1px solid #ddd; font-size: 14px; outline: 0; cursor: pointer;">'+
                              '<input type="button" id="closeButton" value="取消" style=" 120px; height: 40px; margin: 10px 80px; background: #fff; border: 1px solid #ddd; font-size: 14px; outline: 0; cursor: pointer;" >'+
                              '</p>'+
                              '</div>'+
                              '</div>';
                      $("#"+divId).html(tempDivHtml);
                  }
                $('#jcropImg').attr("src", imagePath);
                
                  $("#saveButton").on('click',function(){
                      var width=Math.abs(jcrop_api.tellSelect().x2-jcrop_api.tellSelect().x);
                      var height=Math.abs(jcrop_api.tellSelect().y2-jcrop_api.tellSelect().y);
                      $.ajax({  
                           type : "post",  
                            url : "imagecut",  
                            data : {"imagepath":imagePath,
                                   "ratio":postRatio,
                                   "width":width,
                                  "height":height,
                                  "x":jcrop_api.tellSelect().x,
                                  "y":jcrop_api.tellSelect().y,
                                 },  
                            async : false,  
                            success : function(data){  
                                     callback(imagePath);
                                      $("#tempDiv").remove();
                            }  
                       });
                });
                  $("#closeButton").on('click',function(){
                      $("#tempDiv").remove();
                });
                  document.getElementById("jcropImg").onload = function(){
                       var imageRatio = 0;
                       // 缩放比例
                       var imageWidth = $('#jcropImg').width();
                       // 图片实际宽度
                       var imageHeight = $('#jcropImg').height();
                       // 图片实际高度
                       // 检查图片是否超宽
                       if(imageWidth > imageMaxWidth) {
                           imageRatio = imageMaxWidth / imageWidth;
                           postRatio=postRatio*imageRatio;
                           imageWidth=imageMaxWidth;
                           imageHeight = imageHeight * imageRatio;
                           $('#jcropImg').css("width", imageWidth);
                           $('#jcropImg').css("height", imageHeight);
                       }
                       // 检查图片是否超高
                       if(imageHeight > imageMaxHeight) {
                           imageRatio = imageMaxHeight / imageHeight;
                           postRatio=postRatio*imageRatio;
                           imageHeight=imageMaxHeight;
                           imageWidth = imageWidth * imageRatio;
                           $('#jcropImg').css("width", imageWidth);
                           $('#jcropImg').css("height", imageHeight);
                       }
                         $('#jcropImg').Jcrop({
                           onRelease:releaseCheck,
                           aspectRatio:ratio,                //长宽比例
                           minSize: [50,50],            //最小长宽
                         },function(){
                           jcrop_api = this;
                           jcrop_api.animateTo([0,0,50,50*ratio]);//初始化位置,大小
                         });
                  }
               };
               function releaseCheck()
               {
                 jcrop_api.setOptions({allowSelect:true});
               };

3.action层声明(我这里使用的是springMVC框架,所以使用注解方式声明):

@RequestMapping(value="/imagecut")
    @ResponseBody
    public void imagecut(String imagepath,double ratio,double width,double height,double x,double y){
        try {
            imagepath=request.getSession().getServletContext().getRealPath("/images/"+imagepath.split("/")[3]+"/"+imagepath.split("/")[4]);;
            Common.imageCut(imagepath, (int)(x/ratio), (int)(y/ratio), (int)(width/ratio), (int)(height/ratio));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

4.业务层编写(这里写的是替换原图,如果需求是另存为可以修改部分代码)

/**
     * 对图片裁剪,并把裁剪新图片保存 。
     * @param imagePath 图片路径
     * @param x 左上角x坐标
     * @param y 左上角y坐标
     * @param width 截取宽度
     * @param height 截取高度
     */  
    public static void imageCut(String imagePath,int x,int y,int width,int height) throws IOException {  
        FileInputStream is = null;  
        ImageInputStream iis = null;  
        try {  
            // 读取图片文件  
            is = new FileInputStream(imagePath);  
            /**
             * 返回包含所有当前已注册 ImageReader 的 Iterator,这些 ImageReader
             * 声称能够解码指定格式。 参数:formatName - 包含非正式格式名称 .
             * (例如 "jpeg" 或 "tiff")等 。
             */  
            Iterator<ImageReader> it = ImageIO.getImageReadersByFormatName("jpg");  
            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, "jpg", new File(imagePath));  
        } finally {  
            if (is != null)  
                is.close();  
            if (iis != null)  
                iis.close();  
        }  
    }

5.最后更新图片等操作,就可以在回调函数里自己编写

没有做过多测试,如果哪里有问题,可以联系我!

原文地址:https://www.cnblogs.com/xiaoyu123/p/5853201.html