第一次写头像裁剪上传,原本想着直接本地预览裁剪再上传,可是时间有限,jquery.jcrop貌似并没有对 假设是ie下图片预览效果是滤镜做的 做出对应处理,也没有时间去改;仅仅好将就一下先把图片上传上去再预览
1.先看一下我引入的js
<script src="${adminBasePath}resources/js/jquery.1.8.3.js"></script>
<script src="${adminBasePath}resources/js/layer.js"></script>
<script src="${adminBasePath}resources/js/jquery.jcrop.js"></script>
<script src="${adminBasePath}resources/js/ajaxfileupload.js"></script>
<script src="${adminBasePath}resources/js/perview-image.js"></script>
2.当中perview-image.js是从一位友友哪里粘贴过去的,名字忘了不好意思;(由于我用的是require。所以这里没拆出来)
define(function() {return {timers : [],closeImg : {before : "",after : ""},loading : "",fileImg : "",// 获取预览元素getElementObject : function(elem) {if (elem.nodeType && elem.nodeType === 1) {return elem;} else {return document.getElementById(elem);}},// 開始图片预览beginPerview : function(/* 文件上传控件实例 */file, /* 须要显示的元素id或元素实例 */perviewElemId,/* 上传页面所在的document对象 */dcmt,/* 文件后缀名 */fileSuf) {var imgSufs = ",jpg,jpeg,bmp,png,gif,";var isImage = imgSufs.indexOf("," + fileSuf.toLowerCase() + ",") > -1;// 检查是否为图片if (isImage) {this.imageOperation(file, perviewElemId, dcmt);} else {this.fileOperation(perviewElemId, fileSuf);}},// 一般文件显示操作fileOperation : function(/* 须要显示的元素id或元素实例 */perviewElemId,/* 文件后缀名 */fileSuf) {var that=this;var preview_div = this.getElementObject(perviewElemId);var MAXWIDTH = preview_div.clientWidth;var MAXHEIGHT = preview_div.clientHeight;var img = document.createElement("img");preview_div.appendChild(img);img.style.visibility = "hidden";img.src = this.fileImg;img.onload = function() {var rect = that.clacImgZoomParam(MAXWIDTH, MAXHEIGHT,img.offsetWidth, img.offsetHeight);img.style.width = rect.width + 'px';img.style.height = rect.height + 'px';img.style.marginLeft = rect.left + 'px';img.style.marginTop = rect.top + 'px';img.style.visibility = "visible";}var txtTop = 0 - (MAXHEIGHT * 2 / 3);$('<div style="text-align:center; position:relative; z-index:100; color:#404040;font: 13px/27px Arial,sans-serif;"></div>').text(fileSuf + "文件").css("top", txtTop + "px").appendTo(preview_div);},// 图片预览操作imageOperation : function(/* 文件上传控件实例 */file, /* 须要显示的元素id或元素实例 */perviewElemId,/* 上传页面所在的document对象 */dcmt) {var that=this;for (var t = 0; t < this.timers.length; t++) {window.clearInterval(this.timers[t]);}this.timers.length = 0;var preview_div = this.getElementObject(perviewElemId);var MAXWIDTH = preview_div.clientWidth;var MAXHEIGHT = preview_div.clientHeight;if (file.files && file.files[0]) { // 此处为Firefox。Chrome以及IE10的操作preview_div.innerHTML = "";var img = document.createElement("img");preview_div.appendChild(img);img.style.visibility = "hidden";img.onload = function() {var rect = that.clacImgZoomParam(MAXWIDTH,MAXHEIGHT, img.offsetWidth, img.offsetHeight);img.style.width = rect.width + 'px';img.style.height = rect.height + 'px';img.style.marginLeft = rect.left + 'px';img.style.marginTop = rect.top + 'px';img.style.visibility = "visible";}if(file.isURL){img.src=file.files[0];return false;}var reader = new FileReader();reader.onload = function(evt) {img.src = evt.target.result;}reader.readAsDataURL(file.files[0]);} else {// 此处为IE6,7。8,9的操作file.select();file.blur();var src = dcmt.selection.createRange().text;var div_sFilter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod='scale',src='"+ src + "')";var img_sFilter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod='image',src='"+ src + "')";preview_div.innerHTML = "";var img = document.createElement("div");preview_div.appendChild(img);img.style.filter = img_sFilter;img.style.visibility = "hidden";img.style.width = "100%";img.style.height = "100%";function setImageDisplay() {var rect = that.clacImgZoomParam(MAXWIDTH,MAXHEIGHT, img.offsetWidth, img.offsetHeight);preview_div.innerHTML = "";var div = document.createElement("div");div.style.width = rect.width + 'px';div.style.height = rect.height + 'px';div.style.marginLeft = rect.left + 'px';div.style.marginTop = rect.top + 'px';div.style.filter = div_sFilter;preview_div.appendChild(div);}// 图片载入计数var tally = 0;var timer = window.setInterval(function() {if (img.offsetHeight != MAXHEIGHT) {window.clearInterval(timer);setImageDisplay();} else {tally++;}// 假设超过两秒钟图片还不能载入,就停止当前的轮询if (tally > 20) {window.clearInterval(timer);setImageDisplay();}}, 100);this.timers.push(timer);}},// 按比例缩放图片clacImgZoomParam : function(maxWidth, maxHeight, width, height) {var param = {width : width,height : height};if (width > maxWidth || height > maxHeight) {var rateWidth = width / maxWidth;var rateHeight = height / maxHeight;if (rateWidth > rateHeight) {param.width = maxWidth;param.height = Math.round(height / rateWidth);} else {param.width = Math.round(width / rateHeight);param.height = maxHeight;}}param.left = Math.round((maxWidth - param.width) / 2);param.top = Math.round((maxHeight - param.height) / 2);return param;},// 创建图片预览元素createPreviewElement : function(/* 关闭图片名称 */name,/* 上传时的文件名称 */file, /* 预览时的样式 */style) {var img = document.createElement("div");img.title = file;img.style.overflow = "hidden";for ( var s in style) {img.style[s] = style[s];}var text = document.createElement("div");text.style.width = style.width;text.style.overflow = "hidden";text.style.textOverflow = "ellipsis";text.style.whiteSpace = "nowrap";text.innerHTML = file;var top = 0 - window.parseInt(style.width) - 15;var right = 0 - window.parseInt(style.width) + 14;var close = document.createElement("img");close.setAttribute("name", name);close.src = this.closeImg.before;close.style.position = "relative";close.style.top = top + "px";close.style.right = right + "px";close.style.cursor = "pointer";var loadtop = (0 - window.parseInt(style.height)) / 2 - 26;var loadright = (0 - window.parseInt(style.width)) / 2 + 22;var imgloading = document.createElement("img");imgloading.src = this.loading;imgloading.style.position = "relative";imgloading.style.top = loadtop + "px";imgloading.style.right = loadright + "px";imgloading.style.display = "none";var main = document.createElement("div");main.appendChild(img);main.appendChild(text);main.appendChild(close);main.appendChild(imgloading);return main;},// 获取预览区域getPerviewRegion : function(elem) {var perview = $(this.getElementObject(elem));if (!perview.find("ul").length) {var ul = document.createElement("ul");ul.style.listStyleType = "none";ul.style.margin = "0px";ul.style.padding = "0px";var div = document.createElement("div");div.style.clear = "both";perview.append(ul).append(div);return ul;} else {return perview.children("ul").get(0);}},// 获取上传文件大小getFileSize : function(/* 上传控件dom对象 */file, /* 上传控件所在的document对象 */dcmt) {var fileSize;if (file.files && file.files[0]) {fileSize = file.files[0].size;} else {file.select();var src = dcmt.selection.createRange().text;try {var fso = new ActiveXObject("Scripting.FileSystemObject");var fileObj = fso.getFile(src);fileSize = fileObj.size;} catch (e) {return "error";}}fileSize = ((fileSize / 1024) + "").split(".")[0];return fileSize;}}
});
3.然后先看我前端的代码<script type="text/html" id="upload_photo_tml">
<div class="upload-photo"><div class="photo-lg-pre pre-img"><div class="img-border" id="img-border"></div></div><div class="photo-up-op"><div class="photo-sm-pre" id="preview-pane"><img src="${imgPath}header-img2.png" class="headimg-top" /><div class="preview-container"></div></div><div class="photo-up-btn" align="center"><input type="file" name="userPhoto" id="userPhoto" /> <span class="file-button" id="upload-file-btn" data-id="userPhoto">选择图片</span></div></div>
</div>
</script>
$(document).on("click","#headImage",function(){
var index=layer.confirm($("#upload_photo_tml").html(), {title:"上传头像",btn: ['确定','取消'] //button}, function(){if(opts.selectData.w==undefined)return false;//确定上传 type 为1 opts.uploadType=1;var data={type:opts.uploadType,x:opts.selectData.x,y:opts.selectData.y,width:opts.selectData.w,height:opts.selectData.h};if(opts.uploadData!=null){data.paramString=encodeURI(JSON.stringify(opts.uploadData));}ajaxfileupload.ajaxFileUpload({url: opts.uploadPhotoURL,type: 'post',secureuri: false,// 一般设置为falsedata: data,fileElementId: "userPhoto",// 上传文件的id、name属性名dataType: 'json',// 返回值类型,一般设置为json、application/jsonsuccess: function(data, status) {if(data.responseCode&&data.responseCode==200){$(opts.userHeadPhoto).attr("src",adminBasePath+data.fileURL+data.fileName);layer.alert("上传成功!",{icon:1});}else{layer.alert("上传失败!",{icon:2});}},error: function(data, status, e) {console.log(e);}});});});$(document).on("change",'#userPhoto',function(e) {//假设仅仅是预览 type为0opts.uploadType=0;$(".preview-container").html("");var data={type:opts.uploadType,x:0,y:0,width:0,height:0};if(opts.uploadData!=null){data.paramString=encodeURI(JSON.stringify(opts.uploadData));}var loadingIndex=layer.load(0, {shade: false});var userPhotoHTML=$("#userPhoto").prop("outerHTML");ajaxfileupload.ajaxFileUpload({url: opts.uploadPhotoURL,type: 'post',secureuri: false,// 一般设置为falsedata: data,fileElementId: "userPhoto",// 上传文件的id、name属性名dataType: 'json',// 返回值类型,一般设置为json、application/jsonsuccess: function(data, status) {opts.uploadType=1;opts.uploadData=data;perviewImage.imageOperation({files:[adminBasePath+data.fileURL+data.fileName+"?date="+ (new Date()).getTime()],isURL:true},"img-border",document);layer.close(loadingIndex);if(opts.jcrop_api!=null)opts.jcrop_api.destroy();opts.xsize = $(opts.pcnt).width();opts.ysize = $(opts.pcnt).height();$('#img-border>img').Jcrop({bgColor: "#ffffff",onChange: that._updatePreview,onSelect: that._updatePreview,aspectRatio: opts.xsize / opts.ysize},function(){
// var _w=$(".jcrop-holder>img").width(),
// _h=$(".jcrop-holder>img").height(),
// _wh=0;
// if(_w>=_h)
// _wh=_w;
// else
// _wh=_h;var bounds = this.getBounds();opts.boundx = bounds[0];opts.boundy = bounds[1];opts.jcrop_api = this;//opts.jcrop_api.setSelect([0,0,_wh,_wh]);$(".preview-container").html($("#img-border").html());$(".photo-up-btn").prepend(userPhotoHTML);});},error: function(data, status, e) {console.log(e);}});
});
//绘制选框
that._updatePreview = function(c) {
var opts=that.opts;
opts.selectData=c;
if (parseInt(c.w) > 0) {
var rx = opts.xsize / c.w;
var ry = opts.ysize / c.h;
$(opts.pimg).css({
width : Math.round(rx * opts.boundx) + 'px',
height : Math.round(ry * opts.boundy) + 'px',
marginLeft : '-' + Math.round(rx * c.x) + 'px',
marginTop : '-' + Math.round(ry * c.y) + 'px'
});
}
};
4.然后是Controller层以及图片上传方法的代码
/*** 用户上传头像* * @param type* 0表示暂时预览,1表示上传确认头像* @return*/@ResponseBody@RequestMapping(value = "upload/userphoto", method = RequestMethod.POST)public void uploadUserphoto(Integer type, double x, double y, double width,double height) {JSONObject obj = new JSONObject();try {String paramString = "";JSONObject paj = null;if (null != getRequest().getParameter("paramString")) {paramString = URLDecoder.decode(getRequest().getParameter("paramString"), "UTF-8");paj = (JSONObject) JSON.parse(paramString);}if (type == 1) {String url = getRequest().getSession().getServletContext().getRealPath(paj.getString("fileURL"));String isOK = UploadImgUtil.cutImage(url + "\\" + paj.getString("fileName"),paj.getString("fileURL"), paj.getString("fileName"), x,y, width, height);if (isOK.equals("y")) {String params = HttpRequestUtil.sendPost("updateUserAvatar", "loginToken="+ getCookieUtil().getCookieValue("L_TOKEN")+ "&userAvatar=" + paj.getString("fileURL")+ paj.getString("fileName"));obj.put("responseCode", ((JSONObject) JSONObject.parse(params)).get("responseCode"));obj.put("fileURL", paj.getString("fileURL"));obj.put("fileName", paj.getString("fileName"));} else {obj.put("responseCode", "402");obj.put("responseText", "上传失败");}} else {obj = UploadImgUtil.uploadPhotoImgUrls(getRequest(), super.getUser().getId().toString(), paramString == "" ? "": paj.getString("fileURL"), paramString == "" ? "": paj.getString("fileName"));}} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();obj.put("responseCode", "402");obj.put("responseText", "上传失败");}writeHtml(obj.toJSONString());}
<pre name="code" class="java">/*** 图片裁剪通用接口* * @param src* 原图地址* @param path* 存放路径* @param name* 存放名称* @param x* @param y* @param w* @param h* @throws IOException*/public static String cutImage(String src, String path, String name,double x, double y, double w, double h) throws IOException {Image img;ImageFilter cropFilter;String ext = getExtension(name);if (ext == null)ext = "jpg";BufferedImage bi = ImageIO.read(new File(src));double rate1 = ((double) bi.getWidth()) / (double) UPLOADPHOTOWIDTH+ 0.1;double rate2 = ((double) bi.getHeight()) / (double) UPLOADPHOTOWIDTH+ 0.1;// 依据缩放比率大的进行缩放控制double rate = 0d;if (bi.getWidth() > UPLOADPHOTOWIDTH|| bi.getHeight() > UPLOADPHOTOWIDTH)rate = rate1 > rate2 ?
rate1 : rate2; else rate = rate1 < rate2 ? rate1 : rate2; BufferedImage tag; Image image = bi.getScaledInstance(bi.getWidth(), bi.getHeight(), Image.SCALE_DEFAULT); // 四个參数分别为图像起点坐标和宽高 // 即: CropImageFilter(int x,int y,int width,int height) cropFilter = new CropImageFilter( rate1 > 1 ?
(int) (x * rate) : (int) x, rate2 > 1 ?
(int) (y * rate) : (int) y, rate1 > 1 ? (int) (w * rate) : (int) w, rate2 > 1 ? (int) (h * rate) : (int) h); img = Toolkit.getDefaultToolkit().createImage( new FilteredImageSource(image.getSource(), cropFilter)); int type = BufferedImage.TYPE_INT_RGB; if ("gif".equalsIgnoreCase(ext) || "png".equalsIgnoreCase(ext)) { type = BufferedImage.TYPE_INT_ARGB; } int newWidth; int newHeight; // 推断是否是等比缩放 if ((w * rate) > 640 || (h * rate) > 640) { // 为等比缩放计算输出的图片宽度及高度 double rate3 = (w * rate) / (double) OUTPUTWIDTH + 0.1; double rate4 = (h * rate) / (double) OUTPUTWIDTH + 0.1; // 依据缩放比率大的进行缩放控制 double nrate = rate3 > rate4 ? rate3 : rate4; newWidth = (int) ((w * rate) / nrate); newHeight = (int) ((h * rate) / nrate); } else { newWidth = rate1 > 1 ? (int) (w * rate) : (int) w; // 输出的图片宽度 newHeight = rate2 > 1 ?
(int) (h * rate) : (int) h; // 输出的图片高度 } tag = new BufferedImage(newWidth, newHeight, type); Graphics2D g = (Graphics2D) tag.getGraphics(); g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); g.dispose(); g = tag.createGraphics(); tag = g.getDeviceConfiguration().createCompatibleImage(newWidth, newHeight, Transparency.TRANSLUCENT); g.dispose(); g = tag.createGraphics(); img = img.getScaledInstance(newWidth, newHeight, img.SCALE_AREA_AVERAGING); g.drawImage(img, 0, 0, null); // 绘制剪切后的图 g.dispose(); ImageIO.write(tag, "png", new File(src)); return "y"; } public static String getExtension(String srcImageFile) { String ext = null; if (srcImageFile != null && srcImageFile.lastIndexOf(".") > -1) { ext = srcImageFile.substring(srcImageFile.lastIndexOf(".") + 1); } return ext; }