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,
         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,
        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; }







原文地址:https://www.cnblogs.com/clnchanpin/p/7277800.html