springMVC 头像裁剪上传并等比压

时间:2023-03-09 03:59:22
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;
}