侧边栏壁纸
博主头像
落叶人生博主等级

走进秋风,寻找秋天的落叶

  • 累计撰写 130562 篇文章
  • 累计创建 28 个标签
  • 累计收到 9 条评论
标签搜索

目 录CONTENT

文章目录

jquery.Jcrop结合JAVA后台实现图片裁剪上传

2024-05-14 星期二 / 0 评论 / 0 点赞 / 76 阅读 / 15901 字

第一步:引入相关文件 jQuery主文件:<script src="jquery-1.9.1.min.js" type="text/javascript"></script> Jcrop主文件<scr

第一步:引入相关文件

jQuery主文件:<script src="jquery-1.9.1.min.js" type="text/javascript"></script>
Jcrop主文件<script src="jquery.Jcrop.js" type="text/javascript"></script><link rel="stylesheet" href="jquery.Jcrop.css" type="text/css" />文件异步上传JS,用于不刷新页面上传图片<script src="ajaxfileupload.js" type="text/javascript"></script>第二步:图片处理流程及HTML页面组织处理流程如下:先把原图异步上传(ajaxFileUpload)至服务器某临时目录(我是放在tomcat的webapps某目录下,方便删除),保证该原图可以通过http访问到;将该原图展示在页面上,通过jcrop进行裁剪,点击“裁剪上传”按钮,把裁剪的尺寸信息提交给后台,后台程序根据裁剪的尺寸及原图(webapps某目录下)进行图片的裁剪(ImageReader和Rectangle等);裁剪后的图片上传至图片服务器,原图(webapps某目录下)删除。
图片上传输入框:<input type="file" name="img_poster" id="img_poster" onchange="ajaxFileUpload()"/>
裁剪框:<div class="cutDiv">    <p id="cutInfo"></p>    <img id="img1" alt="" src="" />    <input type="hidden" id="x1" name="x1" value="0" />    <input type="hidden" id="y1" name="y1" value="0" />    <input type="hidden" id="x2" name="x2" value="0" />    <input type="hidden" id="y2" name="y2" value="0" />    <input type="hidden" id="cw" name="cw" value="0" />    <input type="hidden" id="ch" name="ch" value="0" />    <input type="hidden" id="imgName" name="imgName" value="" />    <input type="hidden" id="imgType" name="imgType" value="" />    <input id="cutimg" type="button" value="裁剪上传" />    <input id="cancelimg" type="button" value="取消" /></div>第三步:js代码初始化 
<script type="text/javascript">   var _jcropApi, _boundx, _boundy, _ratio=1;//定义比例、长宽等   $(document).ready(function() {         //取消按钮事件         $("#cancelimg").click(function() {         $("#img_hotLine").attr('value','');         $(".img-group").show();         $("#cutDiv").hide();         if (_jcropApi) {             _jcropApi.destroy();         }         $("#img1").hide();      });      //裁剪上传按钮事件      $("#cutimg").click(function() {        ajaxFileCut();      });        
_ratio = 1;     //当裁剪框变动时,将左上角相对图片的X坐标与Y坐标,宽度以及高度放到<input type="hidden">中    (上传到服务器上裁剪会用到)     function showCoords(c) {       $('#x1').val(c.x * _ratio);       $('#y1').val(c.y * _ratio);       $('#x2').val(c.x2 * _ratio);       $('#y2').val(c.y2 * _ratio);       $('#cw').val(c.w * _ratio);       $('#ch').val(c.h * _ratio);       $("#cutInfo").text("已选择宽*高:" + (parseInt($('#x2').val()) - parseInt($('#x1').val())) + "*" + (parseInt($('#y2').val()) - parseInt($('#y1').val())));     }
   });
第四步:异步图片上传代码
//当AJAX上传图片操作function ajaxFileUpload() {   $.ajaxFileUpload   (      {         url: '/ajaxImageUpload', //用于文件上传的服务器端请求地址         secureuri: false, //一般设置为false,是否安全上传         fileElementId: 'img_poster', //文件上传控件的id属性  <input type="file" id="file" name="file" />         dataType: 'json', //返回值类型 一般设置为json 期望服务器传回的数据类型         success: function (data, status)  //服务器成功响应处理函数         {            var result = data.result;            if (result && result == "success") {               $("#cutDiv").show();//显示裁剪框               var _imgTemp = new Image();               _imgTemp.src = "http://localhost/images/" + data.img_urls;               _imgTemp.onload = function() {                  //上传成功后在将服务器上刚刚上传的图片显示在img1上                  $("#img1").attr("src", "http://localhost/images/" + data.img_urls).show();                  $("#imgName").val(data.img_urls);                  //同时启动裁剪操作,触发裁剪框显示,让用户选择图片区域                  $("#img1").Jcrop({                     aspectRatio: 2 / 1,                     bgOpacity: .4,                          fadeTime: 10,                     boxWidth: 500,                     boxHeight: 500,                     onChange: showCoords,   //当裁剪框变动时执行的函数                     onSelect: showCoords   //当选择完成时执行的函数                  }, function() {                     _jcropApi = this;                     _jcropApi.focus();                     var bounds = this.getBounds();                     _boundx = bounds[0];                     _boundy = bounds[1];                     _jcropApi.setImage("${ctximages}" + data.img_urls);                     _jcropApi.animateTo([0, 0, 320, 160]);                     _jcropApi.setOptions({allowSelect: false});                     _jcropApi.setOptions({                        minSize: [320, 160]                     });                  });               }            } else {               if (typeof (data.error) != 'undefined') {                  if (data.error != '') {                     alert(data.error);                  } else {                     alert(data.msg);                  }               }            }         },         error: function (data, status, e)//服务器响应失败处理函数         {                        alert("系统错误:请检查图片尺寸及大小是否符合要求");         }      }   )   return false;}

第五步:原图异步上传后台处理

/** * 异步上传源图片 * @param request 请求 * @param response 响应 */@ResponseBody@RequestMapping(value = "/ajaxImageUpload")public void ajaxImageUpload(HttpServletRequest request, HttpServletResponse response) {    response.setContentType("application/json; charset=UTF-8");    Map<String, String> result = new HashMap<>();    try {        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;        Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();        if (fileMap != null && fileMap.size() > 0) {            String img_urls = "";            Map.Entry<String, MultipartFile> entity = fileMap.entrySet().iterator().next();            // 上传文件名key对应from表单中的name值, value即为上传的文件            MultipartFile img_cover = entity.getValue();            String fileName = img_cover.getOriginalFilename();            // 获取文件扩展名            String ext = fileName.substring(fileName.lastIndexOf(".") + 1);            //如果文件不是图片,则不上传            if (!"jpg".equalsIgnoreCase(ext) && !"jpeg".equalsIgnoreCase(ext)                    && !"png".equalsIgnoreCase(ext) && !"gif".equalsIgnoreCase(ext)                    && !"bmp".equalsIgnoreCase(ext)) {                throw new Exception("文件格式错误");            }            if (img_cover.getSize() > 0) {                String pc_img_url = uploadImageToWebServer(request, img_cover);//上传图片至本机tomcat的webapps目录下,返回图片名称                if (StringUtils.isNotBlank(pc_img_url)) {                    img_urls += pc_img_url + ConstUtils.SPLIT_CHAR;                }            }            if (img_urls.length() > 0) {                img_urls = img_urls.substring(0, img_urls.length() - 1);            }            result.put("result", "success");            result.put("img_urls", img_urls);        } else {            throw new Exception("请选择要上传的文件");        }    } catch (Exception e) {        e.printStackTrace();        result.put("result", "fail");        result.put("error", "文件上传失败:" + e.getMessage());    }    try {        response.setContentType("text/html;charset=UTF-8");        response.getWriter().write(JsonMapper.getInstance().toJson(result));    }catch (IOException e) {        logger.error(e.getMessage(), e);    }}

第六步:裁剪上传JS

//AJAX上传图片裁剪function ajaxFileCut() {   $.ajax({      type: "get",      url: "/ajaxImageCut",      data: 'imgName=' + $("#imgName").val() + '&x1='+$("#x1").val() + "&y1="+$("#y1").val() + "&cw="+$("#cw").val() + "&ch="+$("#ch").val(),      datatype: "json",      success: function (data) {         if (data && data.result) {            if (data.result == "success") {               $(".img-group").show();               $("#cutDiv").hide();               $("#img1").hide();               if (_jcropApi) {                  _jcropApi.destroy();               }               //TODO 此处客户端自行控制显示后台返回的裁剪后的图片地址
data.img_url            } else {               if (typeof (data.error) != 'undefined') {                  if (data.error != '') {                     alert(data.error);                  } else {                     alert(data.msg);                  }               }            }         }      },      error: function (data, status, e)//服务器响应失败处理函数      {         alert(e);      }   });   return false;}

第七步:裁剪后台处理

/** * 裁剪图片,原图片已上传至工程部署目录的images文件夹下 * @param request 请求 * @param response 响应 * @param imgName 要裁剪的图片名称,即临时保存在webapps下的图片名称 * @param x1 起始点x坐标 * @param y1 起始点y坐标 * @param cw 裁剪后的宽度 * @param ch 裁剪后的高度 */@ResponseBody@RequestMapping(value = "/ajaxImageCut")public void ajaxImageCut(HttpServletRequest request, HttpServletResponse response, String imgName, Double x1, Double y1, Double cw, Double ch) {    Map<String, String> result = new HashMap<>();    try {        if (StringUtils.isNotBlank(imgName)) {            String img_url = cutImage(request, imgType, imgName, x1 == null ? 0 : x1.intValue(),                    y1 == null ? 0 : y1.intValue(), cw == null ? 0 : cw.intValue(), ch == null ? 0 : ch.intValue(), 0, 0);            if (StringUtils.isBlank(img_url)) {                throw new Exception("请确认图片格式及尺寸是否正确");            }            result.put("result", "success");            result.put("img_url", img_url);        } else {            throw new Exception("请选择要裁剪的文件");        }    } catch (Exception e) {        e.printStackTrace();        result.put("result", "fail");        result.put("error", "文件裁剪失败:" + e.getMessage());    }    try {        response.setContentType("application/json;charset=UTF-8");        response.getWriter().write(JsonMapper.getInstance().toJson(result));    }catch (IOException e) {        logger.error(e.getMessage(), e);    }}

附录:图片裁剪代码参考

private File file = null; // 文件对象private String inputDir; // 输入图路径private String outputDir; // 输出图路径private String inputFileName; // 输入图文件名private String outputFileName; // 输出图文件名private int outputWidth = 100; // 默认输出图片宽private int outputHeight = 100; // 默认输出图片高private boolean proportion = true; // 是否等比缩放标记(默认为等比缩放)private boolean enlarge = false;//是否放大图片(默认否)
// ===剪切点x y坐标private int x;private int y;
/** 对图片裁剪,并把裁剪完的新图片保存 */    private boolean cut(){        FileInputStream is = null;        ImageInputStream iis = null;        try {            File file = new File(inputDir + inputFileName);            Image image = ImageIO.read(file);            int width = image.getWidth(null);            int height = image.getHeight(null);            //如果裁剪尺寸大于原图尺寸,则不裁剪            if (width <= outputWidth && height <= outputHeight) {                FileUtils.copyFileCover(inputDir + inputFileName, outputDir + outputFileName, true);                return true;            }            // 读取图片文件            is = new FileInputStream(inputDir + inputFileName);            String ext = inputFileName.substring(inputFileName.lastIndexOf(".") + 1);            /*             * 返回包含所有当前已注册 ImageReader 的 Iterator,这些 ImageReader 声称能够解码指定格式。             * 参数:formatName - 包含非正式格式名称 . (例如 "jpeg" 或 "tiff")等 。             */            Iterator<ImageReader> it = ImageIO.getImageReadersByFormatName(ext.toLowerCase());//            if (it.next() == null) {//                return false;//            }            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, outputWidth, outputHeight);            // 提供一个 BufferedImage,将其用作解码像素数据的目标。            param.setSourceRegion(rect);            /*             * 使用所提供的 ImageReadParam 读取通过索引 imageIndex 指定的对象,并将 它作为一个完整的             * BufferedImage 返回。             */            BufferedImage bi = reader.read(0, param);            // 保存新图片            ImageIO.write(bi, ext.toLowerCase(), new File(outputDir + outputFileName));            return true;        } catch (Exception e) {            e.printStackTrace();        } finally {            if (is != null) {                try {                    is.close();                } catch (Exception e) {                    e.printStackTrace();                }            }            if (iis != null) {                try {                    iis.close();                } catch (Exception e) {                    e.printStackTrace();                }            }        }        return false;    }
 

广告 广告

评论区