springMVC 头像裁剪上传并等比压
第一次写头像裁剪上传,原本想着直接本地预览裁剪再上传,可是时间有限,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,
                          // 一般设置为false
                          data: data,
                          fileElementId: "userPhoto",
                          // 上传文件的id、name属性名
                          dataType: 'json',
                          // 返回值类型,一般设置为json、application/json
                          success: 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为0
      opts.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,
                         // 一般设置为false
                         data: data,
                         fileElementId: "userPhoto",
                         // 上传文件的id、name属性名
                         dataType: 'json',
                         // 返回值类型,一般设置为json、application/json
                         success: 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 block
e.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;
}
springMVC 头像裁剪上传并等比压的更多相关文章
- 第三百九十节,Django+Xadmin打造上线标准的在线教育平台—Django+cropper插件头像裁剪上传
		
第三百九十节,Django+Xadmin打造上线标准的在线教育平台—Django+cropper插件头像裁剪上传 实现原理 前台用cropper插件,将用户上传头像时裁剪图片的坐标和图片,传到逻辑处理 ...
 - jfinal头像裁剪上传服务器
		
前端页面完整代码,复制可用,记得导入库文件 <!DOCTYPE html> <html lang="en"> <head> <title& ...
 - mui+vue+photoclip做APP头像裁剪上传
		
做APP由于项目需要,需要做用户头像上传的功能,头像上传包括拍照和相册选择图片进行上传,这里使用的技术是mui封装的plus,在进行图片裁剪的时候,使用的是photoclip来进行裁剪,由于个人在使用 ...
 - springmvc+ajax文件上传
		
环境:JDK6以上,这里我是用JDK8,mysql57,maven项目 框架环境:spring+springmvc+mybaits或spring+springmvc+mybatis plus 前端代码 ...
 - 5.21学习总结——android开发实现用户头像的上传
		
最近在做个人头像的上传,具体是能调用摄像头和从相册进行选择.本篇文章参考的我的同学的博客,大家有兴趣可以去原作者那里去看看: Hi(.・∀・)ノ (cnblogs.com) 1.使用glide进行图片 ...
 - springmvc图片文件上传接口
		
springmvc图片文件上传 用MultipartFile文件方式传输 Controller package com.controller; import java.awt.image.Buffer ...
 - SpringMVC学习--文件上传
		
简介 文件上传是web开发中常见的需求之一,springMVC将文件上传进行了集成,可以方便快捷的进行开发. springmvc中对多部件类型解析 在 页面form中提交enctype="m ...
 - Spring +SpringMVC  实现文件上传功能。。。
		
要实现Spring +SpringMVC 实现文件上传功能. 第一步:下载 第二步: 新建一个web项目导入Spring 和SpringMVC的jar包(在MyEclipse里有自动生成spring ...
 - springMVC+jsp+ajax上传文件
		
工作中遇到的小问题,做个笔记 实现springMVC + jsp + ajax 上传文件 HTML <body> <form id="myform" method ...
 
随机推荐
- Electron与jQuery中$符号冲突的三种解决方法
			
在Electron工程中引用jQuery时,经常会出现以下错误: Uncaught ReferenceError: $ is not defined 解决的具体方法如下: ①.在测试的过程中(测试过1 ...
 - 客户端 localStorage, sessionStorage, cookie 的区别
			
SessionStorage, LocalStorage, Cookie这三者都可以被用来在浏览器端存储数据,而且都是字符串类型的键值对! 区别在于前两者属于WebStorage,创建它们的目的便是存 ...
 - 【SPOJ Query on a tree 】 (树链剖分)
			
http://acm.hust.edu.cn/vjudge/problem/13013 题意: 有一棵N个节点的树(1<=N<=10000),N-1条边,边的编号为1~N-1,每条边有一个 ...
 - [USACO 2018 Open Gold] Tutorial
			
Link: 传送门 A: 对于每一条分割线,设本不应在其左侧的个数为$x$ 重点要发现每次一来一回的操作恰好会将一对分别应在左/右侧的一个数从右/左移过去 这样就转直接用树状数组求出最大的$x$即可 ...
 - 【计算几何】【分类讨论】Gym - 101173C - Convex Contour
			
注意等边三角形的上顶点是卡不到边界上的. 于是整个凸包分成三部分:左边的连续的三角形.中间的.右边的连续的三角形. 套个计算几何板子求个三角形顶点到圆的切线.三角形顶点到正方形左上角距离啥的就行了,分 ...
 - 【SAM】BZOJ3998-弦论
			
[题目大意] 给出一个字符串,求第k大的子串.(输入1表示子串可重复,0表示不可重复) [思路] 显然,k大子串是后缀自动机的经典题型,可以利用后缀自动机的性质来解决.对于字符串 [前铺1]" ...
 - JavaScript之几种创建函数的区别以及优缺点。
			
工厂模式 function createPerson(name,age,job){ var o = new Object(); o.name = name; o.age = age; o.job = ...
 - AIM Tech Round (Div. 1) C. Electric Charges 二分
			
C. Electric Charges 题目连接: http://www.codeforces.com/contest/623/problem/C Description Programmer Sas ...
 - Codeforces Round #114 (Div. 1) E. Wizards and Bets 高斯消元
			
E. Wizards and Bets 题目连接: http://www.codeforces.com/contest/167/problem/E Description In some countr ...
 - CentOS 6.9/Ubuntu 16.04源码安装RabbitMQ(二进制包tar.gz)
			
说明:CentOS的安装方式同样适合在Ubuntu中,把源改成APT即可. 一.安装erlang: 下载erlang: 从Erlang的官网http://www.erlang.org/download ...