基于canvas和jsp的头像剪辑上传
最近在做项目时候需要一个头像长传功能,但是现在照片动不动就几兆的,都是流量的浪费。
我只是简单想要上传一个头像而已。。。
经过几天发愤图强。。总算是略有所获。。
基本思路:
1、html部分,图片剪辑功能。主要就是整个图片选择一块,可以选取某一块,调整大小等
2、将选择的图片画在canvas中。当点击上传时候,将图片转化成base64格式,传给后台jsp页面
3、jsp将base64的格式的图片转化成文件格式存在服务器里(当然,直接将字符串存入数据库也可以)
效果如下:

生成图片:

html代码如下:
<!doctype html>
<html>
<head>
<style type="text/css">
body{background:#888;}
#box{left:200px;top:100px;position:absolute;}
#imgBox{position:absolute;left:0px;top:0px;}
#imgBox img{opacity:0.5;}
#clipBox img{clip:rect(0px,200px,200px,0px);position:absolute;}
#clipDiv{position:absolute;left:0px;top:0px;width:200px;height:200px;border:1px solid #fff;cursor:move;}
#clipDiv div{position:absolute;width:8px;height:8px;background:#FFF;margin-left:-4px;margin-top:-4px;}
#clipDiv :nth-child(1){left:0px;top:0px;cursor:nw-resize;}
#clipDiv :nth-child(2){left:50%;top:0px;cursor:n-resize;}
#clipDiv :nth-child(3){left:100%;top:0px;cursor:ne-resize;}
#clipDiv :nth-child(4){left:100%;top:50%;cursor:e-resize;}
#clipDiv :nth-child(5){left:100%;top:100%;cursor:se-resize;}
#clipDiv :nth-child(6){left:50%;top:100%;cursor:s-resize;}
#clipDiv :nth-child(7){left:0px;top:100%;cursor:sw-resize;}
#clipDiv :nth-child(8){left:0px;top:50%;cursor:w-resize;}
#photoBox{position:absolute;left:900px;top:100px;width:200px;height:200px;}
#photoBox #photo{position:absolute;}
#submit{position:absolute;left:200px;top:40px;width:100px;height:40px;line-height:40px;text-align:center;border:solid 1px #000;cursor:pointer;border-radius:4px;}
#res{position:absolute;left:320px;top:40px;width:500px;height:40px;line-height:40px;text-align:center;border:solid 1px #000;cursor:pointer;border-radius:4px;}
</style>
</head>
<body>
<div id="submit">submit</div>
<div id="res"></div>
<div id="box">
<div id="imgBox"></div>
<div id="clipBox"></div>
<div id="clipDiv"><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div></div>
</div>
<div id="photoBox"><canvas id="photo" width='200' height='200' style='border:solid #000 1px;'></canvas></div>
<script>
var CLIP_WIDTH = 200 ;//头像宽度
var CLIP_HEIGHT = 200 ;//头像高度
var maxWidth = 0;//引用图片宽度
var maxHeight = 0 ;//引用图片高度 var box = $('clipDiv') ;//选取框层
var clipImg = $('clipBox') ; //选取图片层
var canvas = $('photo') ;//canvas层
var photo = canvas.getContext('2d') ; var elem = -1 ; //当前选择元素
var boxLeft = 0 ;
var boxTop = 0 ;
var boxWidth = 0 ;
var boxHeight = 0 ;
var mouseX = 0 ;
var mouseY = 0 ; var img = new Image() ;
img.src = '1.jpg' ;//原始图片
img.onload = funInit ;
$('submit').onclick = funUpdateImg ; //图片剪辑 for(var i = 0 ; i < box.childNodes.length ; i ++){
box.childNodes[i].index = i ;
box.childNodes[i].onmousedown = function(e){
elem = this.index ;
mouseX = e.clientX ;
mouseY = e.clientY ;
boxWidth = box.offsetWidth-2 ;
boxHeight = box.offsetHeight-2 ;
boxLeft = box.offsetLeft ;
boxTop = box.offsetTop ;
e.cancelBubble = true;
}
}
box.onmousedown = function(e){
elem = 8 ;
mouseX = e.clientX ;
mouseY = e.clientY ;
boxWidth = box.offsetWidth-2 ;
boxHeight = box.offsetHeight-2 ;
boxLeft = box.offsetLeft ;
boxTop = box.offsetTop ;
} window.onmousemove = function(e){
if(elem == -1)return ;
var x = e.clientX ;
var y = e.clientY ;
var curLeft = boxLeft ;
var curTop = boxTop ;
var curWidth = boxWidth ;
var curHeight = boxHeight ;
switch(elem){
case 0:
curLeft = Math.max(0,Math.min(boxLeft + x - mouseX,boxLeft+boxWidth)) ;
curTop = Math.max(0,Math.min(boxTop + y - mouseY,boxTop+boxHeight)) ;
curWidth = boxLeft+boxWidth-curLeft ;
curHeight = boxTop +boxHeight-curTop ;
break;
case 1:
curTop = Math.max(0,Math.min(boxTop + y - mouseY,boxTop+boxHeight)) ;
curHeight = boxTop +boxHeight-curTop ;
break;
case 2:
curTop = Math.max(0,Math.min(boxTop + y - mouseY,boxTop+boxHeight)) ;
curHeight = boxTop +boxHeight-curTop ;
curWidth = Math.max(0,Math.min(boxWidth+x-mouseX,maxWidth));
break;
case 3:
curWidth = Math.max(0,Math.min(boxWidth+x-mouseX,maxWidth));
break;
case 4:
curWidth = Math.max(0,Math.min(boxWidth+x-mouseX,maxWidth));
curHeight = Math.max(0,Math.min(boxHeight+y-mouseY,maxHeight));
break;
case 5:
curHeight = Math.max(0,Math.min(boxHeight+y-mouseY,maxHeight));
break;
case 6:
curLeft = Math.max(0,Math.min(boxLeft + x - mouseX,boxLeft+boxWidth)) ;
curWidth = boxLeft+boxWidth-curLeft ;
curHeight = Math.max(0,Math.min(boxHeight+y-mouseY,maxHeight));
break;
case 7:
curLeft = Math.max(0,Math.min(boxLeft + x - mouseX,boxLeft+boxWidth)) ;
curWidth = boxLeft+boxWidth-curLeft ;
break;
case 8:
curLeft = Math.max(0,Math.min(boxLeft + x - mouseX,maxWidth-boxWidth)) ;
curTop = Math.max(0,Math.min(boxTop + y - mouseY,maxHeight-boxHeight)) ;
break;
}
box.style.left = curLeft + 'px' ;
box.style.top = curTop + 'px' ;
box.style.width = curWidth + 'px' ;
box.style.height = curHeight + 'px' ;
clipImg.childNodes[0].style.clip = "rect("+curTop+"px,"+(curLeft+curWidth)+"px,"+(curTop+curHeight)+"px,"+(curLeft)+"px)" ;
showPhoto(curLeft,curTop,curWidth,curHeight) ;
}
window.onmouseup = function(){
elem = -1 ;
} //将选中的图片画在canvas上
function showPhoto(left,top,width,height){
photo.clearRect(0,0,CLIP_WIDTH,CLIP_HEIGHT) ;
photo.drawImage(img,-left*CLIP_WIDTH/width,-top*CLIP_HEIGHT/height,maxWidth*CLIP_WIDTH/width,maxHeight*CLIP_HEIGHT/height);
}
//获取base64格式的png图片内容
function funGetImg(){
var data = canvas.toDataURL("image/png") ;
data = data.replace(/\+/g,"#") ;//后台java代码中加号出问题
return data ;
}
//post方式将内容传给后台
function ajaxSendImg(str,callback){
var xmlhttp = new XMLHttpRequest() ;
xmlhttp.open("post","base64toimg.jsp",false);
xmlhttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
xmlhttp.send(str);
callback.call(null,xmlhttp.responseText) ;
} function funUpdateImg(){
var data = funGetImg() ;
var url = "imgStr="+data.substring(22) ;
ajaxSendImg(url,log);
} function $(id){
return document.getElementById(id) ;
} function log(){
$('res').innerHTML = arguments[0] ;
} function funInit(){
maxWidth = this.width ;
maxHeight= this.height ;
$('clipBox').appendChild(img) ;
var newImg = new Image() ;
newImg.src = this.src ;
$('imgBox').appendChild(newImg);
showPhoto(0,0,CLIP_WIDTH,CLIP_HEIGHT);
}
</script>
</body>
</html>
<!doctype html>
<html>
<head>
<style type="text/css">
body{background:#888;}
#box{left:200px;top:100px;position:absolute;}
#imgBox{position:absolute;left:0px;top:0px;}
#imgBox img{opacity:0.5;}
#clipBox img{clip:rect(0px,200px,200px,0px);position:absolute;}
#clipDiv{position:absolute;left:0px;top:0px;width:200px;height:200px;border:1px solid #fff;cursor:move;}
#clipDiv div{position:absolute;width:8px;height:8px;background:#FFF;margin-left:-4px;margin-top:-4px;}
#clipDiv :nth-child(1){left:0px;top:0px;cursor:nw-resize;}
#clipDiv :nth-child(2){left:50%;top:0px;cursor:n-resize;}
#clipDiv :nth-child(3){left:100%;top:0px;cursor:ne-resize;}
#clipDiv :nth-child(4){left:100%;top:50%;cursor:e-resize;}
#clipDiv :nth-child(5){left:100%;top:100%;cursor:se-resize;}
#clipDiv :nth-child(6){left:50%;top:100%;cursor:s-resize;}
#clipDiv :nth-child(7){left:0px;top:100%;cursor:sw-resize;}
#clipDiv :nth-child(8){left:0px;top:50%;cursor:w-resize;}
#photoBox{position:absolute;left:900px;top:100px;width:200px;height:200px;}
#photoBox #photo{position:absolute;}
#submit{position:absolute;left:200px;top:40px;width:100px;height:40px;line-height:40px;text-align:center;border:solid 1px #000;cursor:pointer;border-radius:4px;}
#res{position:absolute;left:320px;top:40px;width:500px;height:40px;line-height:40px;text-align:center;border:solid 1px #000;cursor:pointer;border-radius:4px;}
</style>
</head>
<body>
<div id="submit">submit</div>
<div id="res"></div>
<div id="box">
<div id="imgBox"></div>
<div id="clipBox"></div>
<div id="clipDiv"><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div></div>
</div>
<div id="photoBox"><canvas id="photo" width='200' height='200' style='border:solid #000 1px;'></canvas></div>
<script>
var CLIP_WIDTH = 200 ;//头像宽度
var CLIP_HEIGHT = 200 ;//头像高度
var maxWidth = 0;//引用图片宽度
var maxHeight = 0 ;//引用图片高度 var box = $('clipDiv') ;//选取框层
var clipImg = $('clipBox') ; //选取图片层
var canvas = $('photo') ;//canvas层
var photo = canvas.getContext('2d') ; var elem = -1 ; //当前选择元素
var boxLeft = 0 ;
var boxTop = 0 ;
var boxWidth = 0 ;
var boxHeight = 0 ;
var mouseX = 0 ;
var mouseY = 0 ; var img = new Image() ;
img.src = '1.jpg' ;//原始图片
img.onload = funInit ;
$('submit').onclick = funUpdateImg ; //图片剪辑 for(var i = 0 ; i < box.childNodes.length ; i ++){
box.childNodes[i].index = i ;
box.childNodes[i].onmousedown = function(e){
elem = this.index ;
mouseX = e.clientX ;
mouseY = e.clientY ;
boxWidth = box.offsetWidth-2 ;
boxHeight = box.offsetHeight-2 ;
boxLeft = box.offsetLeft ;
boxTop = box.offsetTop ;
e.cancelBubble = true;
}
}
box.onmousedown = function(e){
elem = 8 ;
mouseX = e.clientX ;
mouseY = e.clientY ;
boxWidth = box.offsetWidth-2 ;
boxHeight = box.offsetHeight-2 ;
boxLeft = box.offsetLeft ;
boxTop = box.offsetTop ;
} window.onmousemove = function(e){
if(elem == -1)return ;
var x = e.clientX ;
var y = e.clientY ;
var curLeft = boxLeft ;
var curTop = boxTop ;
var curWidth = boxWidth ;
var curHeight = boxHeight ;
switch(elem){
case 0:
curLeft = Math.max(0,Math.min(boxLeft + x - mouseX,boxLeft+boxWidth)) ;
curTop = Math.max(0,Math.min(boxTop + y - mouseY,boxTop+boxHeight)) ;
curWidth = boxLeft+boxWidth-curLeft ;
curHeight = boxTop +boxHeight-curTop ;
break;
case 1:
curTop = Math.max(0,Math.min(boxTop + y - mouseY,boxTop+boxHeight)) ;
curHeight = boxTop +boxHeight-curTop ;
break;
case 2:
curTop = Math.max(0,Math.min(boxTop + y - mouseY,boxTop+boxHeight)) ;
curHeight = boxTop +boxHeight-curTop ;
curWidth = Math.max(0,Math.min(boxWidth+x-mouseX,maxWidth));
break;
case 3:
curWidth = Math.max(0,Math.min(boxWidth+x-mouseX,maxWidth));
break;
case 4:
curWidth = Math.max(0,Math.min(boxWidth+x-mouseX,maxWidth));
curHeight = Math.max(0,Math.min(boxHeight+y-mouseY,maxHeight));
break;
case 5:
curHeight = Math.max(0,Math.min(boxHeight+y-mouseY,maxHeight));
break;
case 6:
curLeft = Math.max(0,Math.min(boxLeft + x - mouseX,boxLeft+boxWidth)) ;
curWidth = boxLeft+boxWidth-curLeft ;
curHeight = Math.max(0,Math.min(boxHeight+y-mouseY,maxHeight));
break;
case 7:
curLeft = Math.max(0,Math.min(boxLeft + x - mouseX,boxLeft+boxWidth)) ;
curWidth = boxLeft+boxWidth-curLeft ;
break;
case 8:
curLeft = Math.max(0,Math.min(boxLeft + x - mouseX,maxWidth-boxWidth)) ;
curTop = Math.max(0,Math.min(boxTop + y - mouseY,maxHeight-boxHeight)) ;
break;
}
box.style.left = curLeft + 'px' ;
box.style.top = curTop + 'px' ;
box.style.width = curWidth + 'px' ;
box.style.height = curHeight + 'px' ;
clipImg.childNodes[0].style.clip = "rect("+curTop+"px,"+(curLeft+curWidth)+"px,"+(curTop+curHeight)+"px,"+(curLeft)+"px)" ;
showPhoto(curLeft,curTop,curWidth,curHeight) ;
}
window.onmouseup = function(){
elem = -1 ;
} //将选中的图片画在canvas上
function showPhoto(left,top,width,height){
photo.clearRect(0,0,CLIP_WIDTH,CLIP_HEIGHT) ;
photo.drawImage(img,-left*CLIP_WIDTH/width,-top*CLIP_HEIGHT/height,maxWidth*CLIP_WIDTH/width,maxHeight*CLIP_HEIGHT/height);
}
//获取base64格式的png图片内容
function funGetImg(){
var data = canvas.toDataURL("image/png") ;
data = data.replace(/\+/g,"#") ;//后台java代码中加号出问题
return data ;
}
//post方式将内容传给后台
function ajaxSendImg(str,callback){
var xmlhttp = new XMLHttpRequest() ;
xmlhttp.open("post","base64toimg.jsp",false);
xmlhttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
xmlhttp.send(str);
callback.call(null,xmlhttp.responseText) ;
} function funUpdateImg(){
var data = funGetImg() ;
var url = "imgStr="+data.substring(22) ;
ajaxSendImg(url,log);
} function $(id){
return document.getElementById(id) ;
} function log(){
$('res').innerHTML = arguments[0] ;
} function funInit(){
maxWidth = this.width ;
maxHeight= this.height ;
$('clipBox').appendChild(img) ;
var newImg = new Image() ;
newImg.src = this.src ;
$('imgBox').appendChild(newImg);
showPhoto(0,0,CLIP_WIDTH,CLIP_HEIGHT);
}
</script>
</body>
</html
<%@page contentType="text/html;charset=utf-8"%>
<%@page import="java.io.*,sun.misc.BASE64Decoder,sun.misc.BASE64Encoder"%>
<%
String imgStr = request.getParameter("imgStr");
imgStr = imgStr.replaceAll("#","+");
BASE64Decoder decoder = new BASE64Decoder();
try{
byte[] b = decoder.decodeBuffer(imgStr);
String relPath = application.getRealPath("/") ;
String path = "/upload/photo.png" ;
File f = new File(relPath + path);
OutputStream os = new FileOutputStream(f);
os.write(b);
os.flush();
os.close();
out.println(path);
}
catch (Exception e)
{
out.println("error");
}
%>
将base64图片内容传给jsp时候。老是会出错。发现是因为“+”传过去就解析成其他符号了。。一直想不明白。。
只能暂时将“+”缓存“#”,到jsp之后在repalce过来,如果有人知道是怎么回事,希望告知下。。
欢迎讨论,转载请注明出处。谢谢!
基于canvas和jsp的头像剪辑上传的更多相关文章
- 头像截图上传三种方式之一(一个简单易用的flash插件)(asp.net版本)
flash中有版权声明,不适合商业开发.这是官网地址:http://www.hdfu.net/ 本文参考了http://blog.csdn.net/yafei450225664/article/det ...
- JSP实现大文件上传和下载
javaweb上传文件 上传文件的jsp中的部分 上传文件同样可以使用form表单向后端发请求,也可以使用 ajax向后端发请求 1.通过form表单向后端发送请求 <form id=" ...
- RPC基于http协议通过netty支持文件上传下载
本人在中间件研发组(主要开发RPC),近期遇到一个需求:RPC基于http协议通过netty支持文件上传下载 经过一系列的资料查找学习,终于实现了该功能 通过netty实现文件上传下载,主要在编解码时 ...
- 第三百九十节,Django+Xadmin打造上线标准的在线教育平台—Django+cropper插件头像裁剪上传
第三百九十节,Django+Xadmin打造上线标准的在线教育平台—Django+cropper插件头像裁剪上传 实现原理 前台用cropper插件,将用户上传头像时裁剪图片的坐标和图片,传到逻辑处理 ...
- springMVC 头像裁剪上传并等比压
第一次写头像裁剪上传,原本想着直接本地预览裁剪再上传,可是时间有限,jquery.jcrop貌似并没有对 假设是ie下图片预览效果是滤镜做的 做出对应处理,也没有时间去改;仅仅好将就一下先把图片上传 ...
- jsp+servlet实现文件上传下载
相关素材下载 01.jsp <%@ page language="java" contentType="text/html; charset=UTF-8" ...
- 5.21学习总结——android开发实现用户头像的上传
最近在做个人头像的上传,具体是能调用摄像头和从相册进行选择.本篇文章参考的我的同学的博客,大家有兴趣可以去原作者那里去看看: Hi(.・∀・)ノ (cnblogs.com) 1.使用glide进行图片 ...
- CANVAS运用-对图片的压缩上传(仅针对移动浏览器)
最近在移动端设计头像上传功能时,原本是以<input type="file">直接通过formData上传,然而实际使用情况是:对于过大的图片(高像素手机所拍摄的照片等 ...
- html5,js插件实现手机端实现头像剪切上传
思路:先打开相册,选取图片,在剪切图片,转化为base64格式,然后上传到七牛存储,返回url,再传给后端,整个流程就是这样.用的是angular框架,图像插件用到imagecropper.js,废话 ...
随机推荐
- chart.js在html中画曲线图
http://www.bootcss.com/p/chart.js/docs/ http://www.chartjs.org/docs/ 中有详细讲解 一.简介 Chart.js是一个基于HTML ...
- Xcode遇到couldn’t be opened because you don’t have permission to view it.解决方法
今天删除app里面第三方类库的之后,xcode在编译的时候出现了这个问题. (无法打开,因为您没有权限查看它) 问题刚出现的时候,可以尝试一下在xcode上方product选项clean一下. cle ...
- OI队内测试——石门一
T1: 题目大意: 给你一个立方体,每个面上有些数字,给你一个数字K,你可以玩K轮游戏, 每轮你会将每个面上的数均分为4份,分给相邻的面,求K轮游戏后,上面的数字是 依次给你前.后.上.下.左.右的起 ...
- CentOS搭建jdk
一.检查是否安装JDK 一般安装好的CentOS会自带jdk, java -version rpm -qa | grep java 显示如下信息: java-1.4.2-gcj-compat-1.4. ...
- django学习——url的name
html中的地址可以用写死的,也可以用生成的,如:<a href="{% url 'app-url' param1 param2 ... %}">link</a& ...
- imageX批量安裝windows7
以一臺電腦爲sample,安裝完成windows os及其全部update,安裝全部常用軟件,打印機驅動,網絡磁碟機等. 關閉安全控制"UAC"和"維護解決方案" ...
- iOS 之 设置横竖屏及ViewWillAppear及视图与导航控制器嵌套时的不同反应
设置横竖屏不成功,可能跟所在导航控制器有关 视图没有导航控制器时,又有可能不调用ViewWillAppear,这是我遇到的问题.
- 导航栏项目滑过时子菜单显示/隐藏jquery代码
;(function(window){ $('.menuitem').hover(function(){ $('>a',this).css('background-color ...
- nmp install 异常
由于网络的原因,需要多试几次才可以的: -g参数 不会安装在当前目录的:
- Flex回声消除的最佳方法
Adobe Flash Player 已经成为音频和视频播放的非常流行的工具.实际上,目前大多数因特网视频均使用 Flash Player观看. Flash Player 通过将许多技术进行组合可以提 ...