前端页面完整代码,复制可用,记得导入库文件
<!DOCTYPE html> <html lang="en"> <head> <title>Aspect Ratio with Preview Pane | Jcrop Demo</title> <meta http-equiv="Content-type" content="text/html;charset=UTF-8" /> <script src="/Jcrop-0.9.12/js/jquery.min.js"></script> <script src="/Jcrop-0.9.12/js/jquery.Jcrop.js"></script> <script src="/Jcrop-0.9.12/js/imgCropUpload.js"></script> <link rel="stylesheet" href="/Jcrop-0.9.12/css/jquery.Jcrop.css" type="text/css" /> <style type="text/css"> body { font-size: 16px; font-family: "Microsoft YaHei", Arial, Helvetica, sans-serif } *, *:before, *:after { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; -ms-box-sizing: border-box; box-sizing: border-box; } .crop-picker-wrap { position: relative; width: 100px; height: 30px; overflow: hidden; } .crop-picker { width: 100%; height: 100%; line-height: 1; -webkit-appearance: none; margin: 0; border: none; border-radius: 5px; padding: 9px 0; background-color: #1ab2ff; color: #fff; cursor: pointer; } .crop-picker-file { position: absolute; top: 0; right: 0; height: 100%; opacity: 0; cursor: pointer; filter: alpha(opacity = 0); } .crop-wrapper { display: inline-block; min-width: 750px; margin: 10px 0; padding: 10px; border: 1px solid #ccc; border-radius: 5px; box-shadow: 0 0 5px 2px #ccc; } .crop-container { font-size: 0; } .crop-container img[src=""] { visibility: hidden; } .crop-area-wrapper, .crop-preview-wrapper { display: inline-block; vertical-align: top; } .crop-area-wrapper { width: 500px; height: 400px; } .crop-preview-wrapper { width: 200px; height: 200px; margin-left: 28px; overflow: hidden; } .crop-preview-container { position: relative; overflow: hidden; } .crop-operate { text-align: center; margin: 10px 0; } .crop-save, .crop-cancel { display: inline-block; vertical-align: middle; width: 150px; height: 50px; line-height: 50px; -webkit-appearance: none; margin: 0 5px; border: none; border-radius: 5px; background-color: #1ab2ff; color: #fff; cursor: pointer; } #uploadIfr { display: none; } .crop-picker-wrap { position: relative; width: 100px; height: 30px; overflow: hidden; margin-top: 10px; } </style> </head> <body> <form id="coords" class="coords" onsubmit="return false;" action=""> <div class="inline-labels"> <label>X1 <input type="text" size="4" id="x1" name="x1" /></label> <label>Y1 <input type="text" size="4" id="y1" name="y1" /> </label> <label>X2 <input type="text" size="4" id="x2" name="x2" /></label> <label>Y2 <input type="text" size="4" id="y2" name="y2" /></label> <label>W <input type="text" size="4" id="w" name="w" /> </label> <label>H <input type="text" size="4" id="h" name="h" /></label> </div> </form> <div id="TCrop"></div> <button id="btn">上传头像</button> <script type="text/javascript"> $(function() { Crop.init({ id: ‘TCrop‘, /* 上传路径 */ url: ‘‘, /* 允许上传的图片的后缀 */ allowsuf: [‘jpg‘, ‘jpeg‘, ‘png‘, ‘gif‘], /* JCrop参数设置 */ cropParam: { minSize: [100, 100], // 选框最小尺寸 maxSize: [300, 300], // 选框最大尺寸 allowSelect: true, // 允许新选框 allowMove: true, // 允许选框移动 allowResize: true, // 允许选框缩放 dragEdges: true, // 允许拖动边框 onChange: function(c) { $(‘#x1‘).val(c.x); $(‘#y1‘).val(c.y); $(‘#x2‘).val(c.x2); $(‘#y2‘).val(c.y2); $(‘#w‘).val(c.w); $(‘#h‘).val(c.h); }, // 选框改变时的事件,参数c={x, y, x1, y1, w, h} onSelect: function(c) { $(‘#x1‘).val(c.x); $(‘#y1‘).val(c.y); $(‘#x2‘).val(c.x2); $(‘#y2‘).val(c.y2); $(‘#w‘).val(c.w); $(‘#h‘).val(c.h); } // 选框选定时的事件,参数c={x, y, x1, y1, w, h} }, /* 是否进行裁剪,不裁剪则按原图上传,默认进行裁剪 */ isCrop: true, /* 图片上传完成之后的回调,无论是否成功上传 */ onComplete: function(data) { console.log(‘upload complete!‘); } }); }); /* 上传头像 */ $(function(){ $("#btn").click(function(){ var form = document.getElementById("coords");//获取到form表单 var formData = new FormData(form);//创建一个formData对象,将表单中的数据放进去 //for(var i=0; i<$(‘#file‘)[0].files.length;i++){//使用for循环将选择的文件一个一个添加(append)到formData对象中 formData.append(‘img0‘, $(‘#file‘)[0].files[0]);//注意:如果你使用的是jfinal框架这里的key(img)必须是不同的,如果相同的话文件能上传但是拿上传文件名的时候只能拿到一个 //} var x1 = $(‘#x1‘).val(), x2 = $(‘#x2‘).val(), y1 = $(‘#y1‘).val(), y2 = $(‘#y2‘).val(); formData.append(‘x11‘,x1 ); formData.append(‘y11‘,y1 ); formData.append(‘x22‘,x2 ); formData.append(‘y22‘,y2 ); formData.append(‘tw‘,$(".jcrop-holder").css("width") ); formData.append(‘ty‘,$(".jcrop-holder").css("height") ); $.ajax({//ajax url: "/upload/uploadHeaderPic", type: "POST", processData : false,//不处理数据,必须为false contentType : false,//不设置内容类型,必须为false data: formData, dataType:"json", success: function(data){ //layer.msg(data.msg) alert(data.msg); console.log("msg",data.msg) }, error:function(e){ console.log("msg","ajax调用出现错误") } }); }); }); </script> </body> </html>
这个js文件网上找的,经过同事帮助改动。目前可用,有些地方看不懂,不过这个js,我主要用的地方就是图片的预览。参数传递还是自己写方法进行传的
;(function(global, $, Crop) { var defaultOpt = { /* 整个图片选择、裁剪、上传区域的最外围包裹元素id,默认TCrop */ id: ‘TCrop‘, /* 上传路径 */ url: ‘‘, /* 允许上传的图片的后缀,暂时支持以下四种,其余格式图片未测试 */ allowsuf: [‘jpg‘, ‘jpeg‘, ‘png‘, ‘gif‘], /* JCrop参数设置 */ cropParam: { minSize: [50, 50], // 选框最小尺寸 maxSize: [300, 300], // 选框最大尺寸 allowSelect: true, // 允许新选框 allowMove: true, // 允许选框移动 allowResize: true, // 允许选框缩放 dragEdges: true, // 允许拖动边框 onChange: function(c) {}, // 选框改变时的事件 onSelect: function(c) {} // 选框选定时的事件,参数c={x, y, x1, y1, w, h} }, /* 是否进行裁剪,不裁剪则按原图上传,默认进行裁剪 */ isCrop: true, /* 图片上传完成之后的回调,无论是否成功上传 */ onComplete: function(data) { console.log(‘upload complete!‘); } }; /* 记录jcrop实例 */ var jcropApi; /* 创建Dom结构 */ /* 完整DOM结构 --s-- */ /* <iframe id="uploadIfr" name="uploadIfr" class="crop-upload-ifr"></iframe> <form action="index.html" enctype="multipart/form-data" method="post" target="uploadIfr"> <input type="hidden" name="cropData"> <div class="crop-picker-wrap"> <button class="crop-picker" type="button">选择图片</button> <input type="file" id="file" class="crop-picker-file"> </div> <div class="crop-wrapper"> <div class="crop-container clearfix"> <div class="crop-area-wrapper"><img src="" ></div> <div class="crop-preview-wrapper"><img src="" ></div> </div> <div class="crop-operate"> <div class="crop-save">上传原图</div> <div class="crop-save">保存截图</div> <div class="crop-cancel">取消</div> </div> </div> </form> */ /* 完整DOM结构 --e-- */ function _createDom($wrap, opt) { var accept = ‘image/‘ + opt.allowsuf.join(‘, image/‘); var $ifr = $(‘<iframe id="uploadIfr" name="uploadIfr" class="crop-hidden"></iframe>‘); var $form = $(‘<form action="‘ + opt.url + ‘" enctype="multipart/form-data" method="post" target="uploadIfr"/>‘); var $cropDataInp = $(‘<input type="hidden" name="cropData">‘); var $picker = $(‘<div class="crop-picker-wrap"><button class="crop-picker" type="button">选择图片</button></div>‘); var $fileInp = $(‘<input type="file" id="file" accept="‘ + accept + ‘" class="crop-picker-file">‘); $picker.append($fileInp); $form.append($cropDataInp).append($picker); var $cropWrap = $(‘<div class="crop-wrapper crop-hidden"/>‘); var $cropArea = $(‘<div class="crop-area-wrapper"></div>‘); var $cropPreviewWrap = $(‘<div class="crop-preview-wrapper"></div>‘); var $cropPreview = $(‘<div class="crop-preview-container"/>‘); $cropPreviewWrap.append($cropPreview); var $cropContainer = $(‘<div class="crop-container"/>‘).append($cropArea).append($cropPreviewWrap); $cropWrap.append($cropContainer); // var $saveSource = $(‘<div class="crop-save">上传原图</div>‘); //var $save = $(‘<div class="crop-save">保存</div>‘); // var $cropCancel = $(‘<div class="crop-cancel">取消</div>‘); // var $cropOpe = $(‘<div class="crop-operate"/>‘).append($save).append($cropCancel); if(!opt.isCrop) { $cropPreviewWrap.addClass(‘crop-hidden‘); } // $cropWrap.append($cropOpe); $form.append($cropWrap); $wrap.append($ifr).append($form); return { $ifr: $ifr, $form: $form, $cropDataInp: $cropDataInp, $cropPicker: $picker, $fileInp: $fileInp, $cropWrap: $cropWrap, $cropArea: $cropArea, $cropPreview: $cropPreview, // $saveSource: $saveSource, // $save: $save, //$cancel: $cropCancel }; }; /* * 绑定事件 * */ function _bind($cropObj, opt) { var $cropPicker = $cropObj.$cropPicker; var $fileInp = $cropObj.$fileInp; var $save = $cropObj.$save; var $cancel = $cropObj.$cancel; var $ifr = $cropObj.$ifr; $fileInp.change(function(eve) { if(!this.value) {return ;} var fileSuf = this.value.substring(this.value.lastIndexOf(‘.‘) + 1); if(!_checkSuf(fileSuf, opt.allowsuf)) { alert(‘只允许上传后缀名为‘ + opt.allowsuf.join(‘,‘) + ‘的图片‘); return ; } /* 进入裁剪流程 */ _crop($cropObj, this); $cropPicker.addClass(‘crop-hidden‘).next().removeClass(‘crop-hidden‘); }); /* $save.click(function(eve) { eve.preventDefault(); Crop.upload(); });*/ /*$cancel.click(function(eve) { eve.preventDefault(); Crop.cancel(); }); */ /* iframe的load应该延迟绑定,避免首次插入文档中加载完毕时触发load事件 */ window.setTimeout(function() { $ifr.load(function() { var body = this.contentWindow.document.body; var text = body.innerText; opt.onComplete(text); }); }, 100); }; /* 检查文件是否符合上传条件 */ function _checkSuf(fileSuf, suffixs) { for(var i = 0, j = suffixs.length;i < j; i ++) { if(fileSuf.toLowerCase() == suffixs[i].toLowerCase()) { return true; } } return false; }; /* 主要裁剪流程 */ function _crop($cropObj, fileInp) { var cropArea = $cropObj.$cropArea.get(0); var cropPreview = $cropObj.$cropPreview.get(0); var opt = _getOpt(); var jcropOpt = opt.cropParam; cropArea.innerHTML = ‘‘; if(fileInp.files && fileInp.files[0]) { var img = document.createElement(‘img‘); img.style.visibility = ‘hidden‘; cropArea.appendChild(img); img.onload = function() { /* 在图片加载完成之后便可以获取原图的大小,根据原图大小和预览区域大小获取图片的缩放比例以及原图在预览时所展现的大小 */ var scaleOpt = _getScale(cropArea.clientWidth, cropArea.clientHeight, img.offsetWidth, img.offsetHeight); img.setAttribute(‘style‘, ‘position: absolute;visibility: visible;width: ‘ + scaleOpt.w + ‘px;height: ‘ + scaleOpt.h + ‘px‘); if(!opt.isCrop) {return ;} var cropPreviewImg = img.cloneNode(true); cropPreview.appendChild(cropPreviewImg); _startCrop(img, jcropOpt); /* 记录原始比例,上传数据需要还原实际裁剪尺寸 */ Crop.ratio = scaleOpt.scale; /* 记录裁剪图片及裁剪预览图像对象,更新预览图时需要使用 */ Crop.cropPreview = { cropAreaImg: img, cropPreviewImg: cropPreviewImg }; }; var fr = new FileReader(); fr.onload = function(eve) { img.src = eve.target.result; } fr.readAsDataURL(fileInp.files[0]); } else { var img = document.createElement(‘div‘); img.style.visibility = ‘hidden‘; img.style.width = ‘100%‘; img.style.height = ‘100%‘; cropArea.appendChild(img); fileInp.select(); var src = document.selection.createRange().text; // console.log(document.selection.createRange()); var img_filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=‘image‘,src=‘" + src + "‘)"; img.style.filter = img_filter; /* 需等待滤镜加载完毕之后才能进行下一步操作 */ window.setTimeout(function() { _loadFiter(cropArea, img); }, 100); } }; /* 加载滤镜,等待两秒,超时则判定加载失败 */ function _loadFiter(cropArea, img) { var time = 0; if(img.offsetWidth != cropArea.clientWidth) { /* 滤镜加载成功,进入裁剪流程 */ _filterCrop(cropArea, img); } else { time ++; if(time < 20) { window.setTimeout(function() { _loadFiter(cropArea, img); }, 100); } else { alert(‘图片加载失败,请重试!‘); } } }; /* 使用滤镜的裁剪 */ function _filterCrop(cropArea, img) { var scaleOpt = _getScale(cropArea.clientWidth, cropArea.clientHeight, img.offsetWidth, img.offsetHeight); /* 更改滤镜设置 */ var s_filter = img.style.filter.replace(/sizingMethod=‘image‘/g, "sizingMethod=‘scale‘"); var jcropOpt = _getOpt().cropParam; img.setAttribute(‘style‘, ‘position: absolute;visibility: visible;width: ‘ + scaleOpt.w + ‘px;height: ‘ + scaleOpt.h + ‘px;filter: ‘ + s_filter); if(!_getOpt().isCrop) {return ;} var cropPreview = cropArea.nextSibling.firstChild; var cropPreviewImg = img.cloneNode(true); cropPreview.appendChild(cropPreviewImg); _startCrop(img, jcropOpt); /* 记录原始比例,上传数据需要还原实际裁剪尺寸 */ Crop.ratio = scaleOpt.scale; /* 记录裁剪图片及裁剪预览图像对象,更新预览图时需要使用 */ Crop.cropPreview = { cropAreaImg: img, cropPreviewImg: cropPreviewImg }; }; /* 开始裁剪,初始化裁剪插件 */ function _startCrop(img, jcropOpt) { var imgW = img.offsetWidth; var imgH = img.offsetHeight; var minW = jcropOpt.minSize[0], minH = jcropOpt.minSize[1]; var offsetWidth = (imgW / 2) - (minW / 2); var offsetHeight = (imgH / 2) - (minH / 2); var obj = { x: offsetWidth, y: offsetHeight, x2: offsetWidth + minW, y2: offsetHeight + minH, w: minW, h: minH }; $(img).Jcrop(jcropOpt, function() { jcropApi = this; this.animateTo([obj.x, obj.y, obj.x2, obj.y2]); }); }; /* 获取配置参数opt */ function _getOpt() { var id = Crop.crop.id; var cropDom = document.getElementById(id); var opt = $.data(cropDom, ‘crop‘).opt; return opt; }; /* * 获取缩放比例 * * 原始宽高vw,vh * 实际显示宽高sw,sh * 返回: * {w,h,scale:max(sw/vw,sh/vh)} * w,h均为缩放到sw、sh后的宽高 */ function _getScale(vw, vh, sw, sh) { vw = Number(vw); vh = Number(vh); sw = Number(sw); sh = Number(sh); if(vw <= 0 || vh <= 0) { console.log(‘参数不能为0‘); return false; } var wScale = sw / vw; var hScale = sh / vh; var scale = 1, w, h; if(wScale > hScale) { scale = wScale; w = vw; h = sh / scale; } else { scale = hScale; h = vh; w = sw / scale; } return { scale: scale, w: w, h: h }; }; /* 更新裁剪预览图 */ function _updatePreview(c) { var cropAreaImg = Crop.cropPreview.cropAreaImg; var cropPreviewImg = Crop.cropPreview.cropPreviewImg; var $cropObj = $.data(document.getElementById(Crop.crop.id), ‘crop‘).$cropObj; var $cropDataInp = $cropObj.$cropDataInp; var $cropPreview = $cropObj.$cropPreview; var $previewParent = $cropPreview.parent(); var vw = $previewParent.width(), vh = $previewParent.height(); var scaleOpt = _getScale(vw, vh, c.w, c.h); $cropPreview.width(scaleOpt.w); $cropPreview.height(scaleOpt.h); var width = $(cropAreaImg).width() / scaleOpt.scale; var height = $(cropAreaImg).height() / scaleOpt.scale; var top = -(c.y / scaleOpt.scale); var left = -(c.x / scaleOpt.scale); cropPreviewImg.style.width = width + ‘px‘; cropPreviewImg.style.height = height + ‘px‘; cropPreviewImg.style.top = top + ‘px‘; cropPreviewImg.style.left = left + ‘px‘; _setCropData($cropDataInp, c); }; /* 设置裁剪数据 */ function _setCropData($cropDataInp, c) { var ratio = Crop.ratio; var data = { x: c.x * ratio, y: c.y * ratio, w: c.w * ratio, h: c.h * ratio }; var dataJson = JSON.stringify(data); $cropDataInp.val(dataJson); }; /* 扩展配置参数,尤其是Jcrop裁剪参数中的onSelect,onChange参数 */ function _extendOpt(opt) { opt = $.extend(true, {}, defaultOpt, opt); var select = opt.cropParam.onSelect; var change = opt.cropParam.onChange; if(Object.prototype.toString.call(select) == ‘[object Function]‘) { opt.cropParam.onSelect = function(c) { _updatePreview.call(jcropApi, c); select.call(jcropApi, c); }; } else { opt.cropParam.onSelect = _updatePreview; } if(Object.prototype.toString.call(change) == ‘[object Function]‘) { opt.cropParam.onChange = function(c) { _updatePreview.call(jcropApi, c); change.call(jcropApi, c); } } else { opt.cropParam.onChange = _updatePreview; } return opt; }; /* 初始化上传裁剪区域 */ function init(opt) { var opt = _extendOpt(opt); var $uploadCropWrap = $(‘#‘ + opt.id); var hasDom = true; if($uploadCropWrap.length == 0) { $uploadCropWrap = $(‘<div id="‘ + opt.id + ‘" />‘); hasDom = false; } /* 清空Dom原有内部结构 */ $uploadCropWrap.html(‘‘); var $cropObj = _createDom($uploadCropWrap, opt); $.data($uploadCropWrap.get(0), ‘crop‘, {opt: opt, $cropObj: $cropObj}); hasDom || $(‘body‘).append($uploadCropWrap); _bind($cropObj, opt); Crop.crop = {id: opt.id, hasDom: hasDom}; }; /* 上传 */ function upload() { var id = (Crop.crop && Crop.crop.id) || ‘‘; var dom = document.getElementById(id); if(!dom) { return ; } var form = $.data(dom, ‘crop‘).$cropObj.$form.get(0); form.submit(); }; /* 取消裁剪 */ function cancel() { var id = (Crop.crop && Crop.crop.id) || ""; var dom = document.getElementById(id); if(!dom) { return ; } var $cropObj = $.data(dom, ‘crop‘).$cropObj; $cropObj.$cropWrap.addClass(‘crop-hidden‘); $cropObj.$cropPicker.removeClass(‘crop-hidden‘); }; /* 销毁上传裁剪区域 */ function destroy() { var crop = Crop.crop || {}; var $cropWrap = $(‘#‘ + crop.id); if(crop.hasDom === true) { $cropWrap.html(‘‘); } else { $cropWrap.remove(); } }; if($.isEmptyObject(Crop)) { global.Crop = Crop = { init: init, upload: upload, cancel: cancel, destroy: destroy, crop: {} }; } else { Crop = $.extend(Crop, { init: init, upload: upload, cancel: cancel, destroy: destroy, crop: {} }); } })(window, jQuery, window.Crop || {});
前端就这两个是主要的文件,网上找不到的,其他的文件都是可以找到的,贴出来文件图
主要文件就两个,jquery.Jcrop.css,jquery.Jcrop.js
都可以找到自己去下载就可以。
前端好了就是后台代码了,使用jfinal做的
工具类主要用到了裁剪和缩放 package cn.rjj.common.tools; import java.awt.Rectangle; import java.awt.image.BufferedImage; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.util.Iterator; import javax.imageio.ImageIO; import javax.imageio.ImageReadParam; import javax.imageio.ImageReader; import javax.imageio.stream.ImageInputStream; public class ImageTool { /** * 对图片进行剪裁,只保存选中的区域 * * @param img * 原图路径 * @param dest * 目标路径 * @param top * 裁剪图片的开始位置,距离顶部的高度 * @param left * 裁剪图片的开始位置,距离左边部的距离 * @param width * 目标图片的宽度 * @param height * 目标图片高度 * @param tw * 原图页面显示宽度 * @param ty * 原图页面显示高度 * * @return * @throws IOException */ public static boolean saveImage(File img, String dest, int top, int left, int width, int height, int tw, int ty) { try { File fileDest = new File(dest); if (!fileDest.getParentFile().exists()) fileDest.getParentFile().mkdirs(); // 读取原图 BufferedImage bfi = (BufferedImage) ImageIO.read(img); // 获得原图片的大小,并且按照前端页面中设置的图片的大小,缩放宽高 BufferedImage bi = resizeImage(bfi, BufferedImage.TYPE_INT_ARGB, tw, ty); // 下边是裁剪,要裁剪的图片,目标宽高大于实际宽高就取实际宽高,小于,就拿到目标宽高 height = Math.min(height, bi.getHeight()); width = Math.min(width, bi.getWidth()); // 如果截取的宽高小于等于0,那么就保留实际宽高 if (height <= 0) height = bi.getHeight(); if (width <= 0) width = bi.getWidth(); top = Math.min(Math.max(0, top), bi.getHeight() - height); left = Math.min(Math.max(0, left), bi.getWidth() - width); // 截取图片,.getSubimage(left(左边位置), top(上边位置), width(要截图的宽), // height(要截取图片的高度)); BufferedImage bi_cropper = bi.getSubimage(left, top, width, height); return ImageIO.write(bi_cropper, "jpeg", fileDest); } catch (IOException e) { e.printStackTrace(); } return false; } /** * 缩小后的图片 * * @author * @time 2018年8月3日下午9:13:23 * @param originalImage * @param type * @param targetWidth * @param targetHeught * @return * @throws FileNotFoundException * BufferedImage */ private static BufferedImage resizeImage(BufferedImage originalImage, int type, int targetWidth, int targetHeught) throws FileNotFoundException { /* * 这个出来的像素很差,有兴趣的可以自己研究下 BufferedImage resizedImage = new * BufferedImage(IMG_WIDTH, IMG_HEIGHT, type); Graphics2D g = * resizedImage.createGraphics(); g.drawImage(originalImage, 0, 0, * IMG_WIDTH, IMG_HEIGHT, null); g.dispose(); */ // 构建图片流 BufferedImage tag = new BufferedImage(targetWidth, targetHeught, BufferedImage.TYPE_INT_RGB); // 绘制改变尺寸后的图 tag.getGraphics().drawImage(originalImage, 0, 0, targetWidth, targetHeught, null); // 输出流 // 这里是测试,为了看下这个图片缩放后的样子 /* * try { ImageIO.write(tag, "jpeg", new * FileOutputStream("E:/copy.jpg")); } catch (IOException e) { // TODO * Auto-generated catch block e.printStackTrace(); } */ return tag; } /** * 对图片裁剪,并把裁剪新图片保存 * * @param srcPath * 读取源图片路径 * @param toPath * 写入图片路径 * @param x * 剪切起始点x坐标 * @param y * 剪切起始点y坐标 * @param width * 剪切宽度 * @param height * 剪切高度 * @param readImageFormat * 读取图片格式 * @param writeImageFormat * 写入图片格式 * @return * @throws IOException */ public boolean cropImage(String srcPath, String toPath, int x, int y, int width, int height, String readImageFormat, String writeImageFormat) { try { FileInputStream fis = null; ImageInputStream iis = null; try { // 读取图片文件 fis = new FileInputStream(srcPath); Iterator<?> it = ImageIO.getImageReadersByFormatName(readImageFormat); ImageReader reader = (ImageReader) it.next(); // 获取图片流 iis = ImageIO.createImageInputStream(fis); reader.setInput(iis, true); ImageReadParam param = reader.getDefaultReadParam(); // 定义一个矩形 Rectangle rect = new Rectangle(x, y, width, height); // 提供一个 BufferedImage,将其用作解码像素数据的目标。 param.setSourceRegion(rect); BufferedImage bi = reader.read(0, param); // 保存新图片 ImageIO.write(bi, writeImageFormat, new File(toPath)); return true; } finally { if (fis != null) fis.close(); if (iis != null) iis.close(); } } catch (FileNotFoundException e) { e.printStackTrace(); return false; } catch (IOException e) { e.printStackTrace(); return false; } } }
最后就是主要代码,controller中的操作。这里只是上传的操作做了,可以根据自己的业务,把图片保存的时候把路径保留到,使得图片路径和用户关联,这样显示用户头像的时候,直接拿到路径,就可以显示图片了 package cn.rjj.common.upload; import java.io.File; import java.util.Date; import java.util.List; import com.alibaba.fastjson.JSONObject; import com.jfinal.core.Controller; import com.jfinal.kit.PathKit; import com.jfinal.upload.UploadFile; import cn.rjj.common.tools.ImageTool; /** * * @author * url:/upload */ public class UploadHeardPicture extends Controller { public void index(){ redirect("/upload/toUploadHeadPicture"); } /** * 上传头像页面 * url:/upload/toUploadHeadPicture */ public void toUploadHeadPicture(){ render("headUpload.html"); } /** * 头像上传 * url:/upload/uploadHeaderPic * * 先把图片上传到服务其上,根据参数进行裁剪,然后把原来的那张图片删除,就可以了。把资源也省下来了 */ public void uploadHeaderPic() { File file = new File("/upload/head"); if(!file.exists()){ file.mkdirs(); } //设置图片上传位置 List<UploadFile> files = getFiles("head"); //获得参数 int left= (int) Math.round(Double.parseDouble(getPara("x11"))); int top= (int) Math.round(Double.parseDouble(getPara("y11"))); int width= (int) Math.round(Double.parseDouble(getPara("w"))) ; int height= (int) Math.round(Double.parseDouble(getPara("h"))) ; String para = getPara("tw"); String para2 = getPara("ty"); String substring = para.substring(0,para.length()-2); int tw= (int) Math.round(Double.parseDouble(substring)) ; String substring2 = para2.substring(0,para2.length()-2); int ty= (int) Math.round(Double.parseDouble(substring2)) ; JSONObject json= new JSONObject(); UploadFile uploadFile = getFile("img0"); //for (UploadFile uploadFile : files) { File source = uploadFile.getFile(); String fileName = source.getName(); // boolean isSave = cropImage(source.getPath(),PathKit.getWebRootPath()+"/upload/head/" + new Date().getTime()+fileName,top,left,width,height,"jpg","jpg"); //这个是对图片进行缩放后在裁剪的 boolean isSave = ImageTool.saveImage(source,PathKit.getWebRootPath()+"/upload/head/" + new Date().getTime()+fileName,top,left,width,height,tw,ty); //删除原来的图片, source.delete(); if(isSave){ json.put("msg", "头像更新成功!"); }else{ json.put("msg", "头像更新失败!"); } // } renderJson(json); } }
我把完整项目放到https://download.csdn.net/download/qq_20359393/10584618
可以去下载实验效果。项目可以再次优化。目前只是实现了需要的功能。
原文地址:https://www.cnblogs.com/renjianjun/p/9426048.html
时间: 2024-10-12 17:44:30