第一次写头像裁剪上传,原本想着直接本地预览裁剪再上传,可是时间有限,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 头像裁剪上传并等比压的更多相关文章

  1. 第三百九十节,Django+Xadmin打造上线标准的在线教育平台—Django+cropper插件头像裁剪上传

    第三百九十节,Django+Xadmin打造上线标准的在线教育平台—Django+cropper插件头像裁剪上传 实现原理 前台用cropper插件,将用户上传头像时裁剪图片的坐标和图片,传到逻辑处理 ...

  2. jfinal头像裁剪上传服务器

    前端页面完整代码,复制可用,记得导入库文件 <!DOCTYPE html> <html lang="en"> <head> <title& ...

  3. mui+vue+photoclip做APP头像裁剪上传

    做APP由于项目需要,需要做用户头像上传的功能,头像上传包括拍照和相册选择图片进行上传,这里使用的技术是mui封装的plus,在进行图片裁剪的时候,使用的是photoclip来进行裁剪,由于个人在使用 ...

  4. springmvc+ajax文件上传

    环境:JDK6以上,这里我是用JDK8,mysql57,maven项目 框架环境:spring+springmvc+mybaits或spring+springmvc+mybatis plus 前端代码 ...

  5. 5.21学习总结——android开发实现用户头像的上传

    最近在做个人头像的上传,具体是能调用摄像头和从相册进行选择.本篇文章参考的我的同学的博客,大家有兴趣可以去原作者那里去看看: Hi(.・∀・)ノ (cnblogs.com) 1.使用glide进行图片 ...

  6. springmvc图片文件上传接口

    springmvc图片文件上传 用MultipartFile文件方式传输 Controller package com.controller; import java.awt.image.Buffer ...

  7. SpringMVC学习--文件上传

    简介 文件上传是web开发中常见的需求之一,springMVC将文件上传进行了集成,可以方便快捷的进行开发. springmvc中对多部件类型解析 在 页面form中提交enctype="m ...

  8. Spring +SpringMVC 实现文件上传功能。。。

    要实现Spring +SpringMVC  实现文件上传功能. 第一步:下载 第二步: 新建一个web项目导入Spring 和SpringMVC的jar包(在MyEclipse里有自动生成spring ...

  9. springMVC+jsp+ajax上传文件

    工作中遇到的小问题,做个笔记 实现springMVC + jsp + ajax 上传文件 HTML <body> <form id="myform" method ...

随机推荐

  1. Electron与jQuery中$符号冲突的三种解决方法

    在Electron工程中引用jQuery时,经常会出现以下错误: Uncaught ReferenceError: $ is not defined 解决的具体方法如下: ①.在测试的过程中(测试过1 ...

  2. 客户端 localStorage, sessionStorage, cookie 的区别

    SessionStorage, LocalStorage, Cookie这三者都可以被用来在浏览器端存储数据,而且都是字符串类型的键值对! 区别在于前两者属于WebStorage,创建它们的目的便是存 ...

  3. 【SPOJ Query on a tree 】 (树链剖分)

    http://acm.hust.edu.cn/vjudge/problem/13013 题意: 有一棵N个节点的树(1<=N<=10000),N-1条边,边的编号为1~N-1,每条边有一个 ...

  4. [USACO 2018 Open Gold] Tutorial

    Link: 传送门 A: 对于每一条分割线,设本不应在其左侧的个数为$x$ 重点要发现每次一来一回的操作恰好会将一对分别应在左/右侧的一个数从右/左移过去 这样就转直接用树状数组求出最大的$x$即可 ...

  5. 【计算几何】【分类讨论】Gym - 101173C - Convex Contour

    注意等边三角形的上顶点是卡不到边界上的. 于是整个凸包分成三部分:左边的连续的三角形.中间的.右边的连续的三角形. 套个计算几何板子求个三角形顶点到圆的切线.三角形顶点到正方形左上角距离啥的就行了,分 ...

  6. 【SAM】BZOJ3998-弦论

    [题目大意] 给出一个字符串,求第k大的子串.(输入1表示子串可重复,0表示不可重复) [思路] 显然,k大子串是后缀自动机的经典题型,可以利用后缀自动机的性质来解决.对于字符串 [前铺1]" ...

  7. JavaScript之几种创建函数的区别以及优缺点。

    工厂模式 function createPerson(name,age,job){ var o = new Object(); o.name = name; o.age = age; o.job = ...

  8. AIM Tech Round (Div. 1) C. Electric Charges 二分

    C. Electric Charges 题目连接: http://www.codeforces.com/contest/623/problem/C Description Programmer Sas ...

  9. 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 ...

  10. CentOS 6.9/Ubuntu 16.04源码安装RabbitMQ(二进制包tar.gz)

    说明:CentOS的安装方式同样适合在Ubuntu中,把源改成APT即可. 一.安装erlang: 下载erlang: 从Erlang的官网http://www.erlang.org/download ...