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;
	}
				
时间: 2024-11-03 21:48:45

springMVC 头像裁剪上传并等比压的相关文章

html5 canvas头像裁剪上传

效果: 在博客里有另一篇头像裁剪是用actionscript实现的头像裁剪上传,这里拥护html5,用canvas实现下.前两次的右键是为了说明不是用flash做的. 如果想要更严谨的,有技术支持的这个东西的话,可以用kissy的http://gallery.kissyui.com/imgcrop/2.0/guide/index.html. 原理很简单:裁剪框是用html做的,canvas的作用在于每次移动,变形后根据裁剪框的位置坐标以及大小,绘制图像的部分并缩放,还有绘制裁剪框区域外的灰色区域

java头像裁剪上传

原文:java头像裁剪上传 源代码下载地址:http://www.zuidaima.com/share/1550463771118592.htm jsp页面实现头像裁剪上传,带进度条,后台java接收 上传成功后

基于cropper和sweetalert的简单图片/头像裁剪上传

基本功能 前端基本样式: 进行图片裁剪及上传: 点击上传后,js会将截取到的数据转为图片数据利用ajax发送给后台进行存储.存储成功后,刷新前端页面,头像改变. 上传成功后:自动刷新网页,更改头像 基本工具 cropper是一个功能强大的jq插件,在指定图片img上添加裁剪框,并根据指定事件对图片按照裁剪框的大小进行裁剪. crepper还可以对定义图片翻转.放大.移动以及输出裁剪框位置的很多功能,由于此处只是用于头像上传,所以只使用了基本功能. cropper使用时需要用到jq2.0以上,所以

jfinal头像裁剪上传服务器

前端页面完整代码,复制可用,记得导入库文件 <!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" />

超少代码的头像裁剪上传

效果: as上传的好处在于裁剪工作在客户端就完成了,而用jcrop的话要记录裁剪大小,位置坐标等,传给服务端才能裁剪 代码很简单 1 package 2 { 3 import flash.display.*; 4 import flash.events.Event; 5 import flash.utils.ByteArray; 6 import flash.events.*; 7 import flash.net.*; 8 import com.adobe.images.JPGEncoder;

小议头像预览裁剪上传的实现

在做头像上传的时候,浏览器默认是无法取得本地图片的,当然 HTML5 是可以的.不过IE6-8怎么破?目前比较通用的方案都是 flash 解决. 说道头像预览和裁剪,我最熟悉的就是 Discuz 的那个了,非常方便好用.不仅可以选择本地图片,还能直接调用摄像头拍摄,当然前提是你必须有个摄像头. 于是我心血来潮的想把他剥离出来给项目用,于是有就了此文..我就不说怎么提取怎么调用,就简单的谈谈他是怎么处理图片好了,反正不是我们想的那样,和我想的出入非常大. 这个插件呢,差不多分为四步处理:1. 前台

前端插件——头像截图上传插件的使用(带后台)

效果图:实现上传头像,右边是预览,有三个大小,可以对头像进行裁剪 HTML: toParentData 和 img 返回的是图片裁剪后的base64编码.其中toParentData用于业务需求,可以忽略. <!DOCTYPE html> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html> <head> <c:set va

Extjs4 + springMVC的文件上传

用springMVC来做项目,如果遇到文件上传,那么一定要用spring自带的文件处理类来处理上传的文件,因为效率实在高过其他的. 从界面传过来的参数,如果设置了值对象,那么可以从值对象里面取出字符串类型的普通参数,如果不这样做,也可以直接从request里面获得,两种方法都可以. 问题是如果值对象里面写了其他类型的变量,妄想像Struts2那样处理,springMVC就会报出400 Bad Request的错误. 在Struts2里面,我们可以定义一个值对象为 public class Ima

SpringMVC中文件上传的客户端验证

SpringMVC中文件上传的客户端验证 客户端验证主要思想:在jsp页面中利用javascript进行对文件的判断,完成验证后允许上传 验证步骤:1.文件名称 2.获取文件的后缀名称 3.判断哪些文件类型允许上传 4.判断文件大小 5.满足条件后跳转后台实现上传 前台界面(验证上传文件是否格式满足要求): <body> <h2>文件上传</h2> <form action="upload01" method="post"