最近在做项目时候需要一个头像长传功能,但是现在照片动不动就几兆的,都是流量的浪费。
我只是简单想要上传一个头像而已。。。
经过几天发愤图强。。总算是略有所获。。
基本思路:
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>
jsp代码:
1 <!doctype html>
2 <html>
3 <head>
4 <style type="text/css">
5 body{background:#888;}
6 #box{left:200px;top:100px;position:absolute;}
7 #imgBox{position:absolute;left:0px;top:0px;}
8 #imgBox img{opacity:0.5;}
9 #clipBox img{clip:rect(0px,200px,200px,0px);position:absolute;}
10 #clipDiv{position:absolute;left:0px;top:0px;width:200px;height:200px;border:1px solid #fff;cursor:move;}
11 #clipDiv div{position:absolute;width:8px;height:8px;background:#FFF;margin-left:-4px;margin-top:-4px;}
12 #clipDiv :nth-child(1){left:0px;top:0px;cursor:nw-resize;}
13 #clipDiv :nth-child(2){left:50%;top:0px;cursor:n-resize;}
14 #clipDiv :nth-child(3){left:100%;top:0px;cursor:ne-resize;}
15 #clipDiv :nth-child(4){left:100%;top:50%;cursor:e-resize;}
16 #clipDiv :nth-child(5){left:100%;top:100%;cursor:se-resize;}
17 #clipDiv :nth-child(6){left:50%;top:100%;cursor:s-resize;}
18 #clipDiv :nth-child(7){left:0px;top:100%;cursor:sw-resize;}
19 #clipDiv :nth-child(8){left:0px;top:50%;cursor:w-resize;}
20 #photoBox{position:absolute;left:900px;top:100px;width:200px;height:200px;}
21 #photoBox #photo{position:absolute;}
22 #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;}
23 #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;}
24 </style>
25 </head>
26 <body>
27 <div id="submit">submit</div>
28 <div id="res"></div>
29 <div id="box">
30 <div id="imgBox"></div>
31 <div id="clipBox"></div>
32 <div id="clipDiv"><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div></div>
33 </div>
34 <div id="photoBox"><canvas id="photo" width='200' height='200' style='border:solid #000 1px;'></canvas></div>
35 <script>
36 var CLIP_WIDTH = 200 ;//头像宽度
37 var CLIP_HEIGHT = 200 ;//头像高度
38 var maxWidth = 0;//引用图片宽度
39 var maxHeight = 0 ;//引用图片高度
40
41 var box = $('clipDiv') ;//选取框层
42 var clipImg = $('clipBox') ; //选取图片层
43 var canvas = $('photo') ;//canvas层
44 var photo = canvas.getContext('2d') ;
45
46 var elem = -1 ; //当前选择元素
47 var boxLeft = 0 ;
48 var boxTop = 0 ;
49 var boxWidth = 0 ;
50 var boxHeight = 0 ;
51 var mouseX = 0 ;
52 var mouseY = 0 ;
53
54 var img = new Image() ;
55 img.src = '1.jpg' ;//原始图片
56 img.onload = funInit ;
57 $('submit').onclick = funUpdateImg ;
58
59 //图片剪辑
60
61 for(var i = 0 ; i < box.childNodes.length ; i ){
62 box.childNodes[i].index = i ;
63 box.childNodes[i].onmousedown = function(e){
64 elem = this.index ;
65 mouseX = e.clientX ;
66 mouseY = e.clientY ;
67 boxWidth = box.offsetWidth-2 ;
68 boxHeight = box.offsetHeight-2 ;
69 boxLeft = box.offsetLeft ;
70 boxTop = box.offsetTop ;
71 e.cancelBubble = true;
72 }
73 }
74 box.onmousedown = function(e){
75 elem = 8 ;
76 mouseX = e.clientX ;
77 mouseY = e.clientY ;
78 boxWidth = box.offsetWidth-2 ;
79 boxHeight = box.offsetHeight-2 ;
80 boxLeft = box.offsetLeft ;
81 boxTop = box.offsetTop ;
82 }
83
84 window.onmousemove = function(e){
85 if(elem == -1)return ;
86 var x = e.clientX ;
87 var y = e.clientY ;
88 var curLeft = boxLeft ;
89 var curTop = boxTop ;
90 var curWidth = boxWidth ;
91 var curHeight = boxHeight ;
92 switch(elem){
93 case 0:
94 curLeft = Math.max(0,Math.min(boxLeft x - mouseX,boxLeft boxWidth)) ;
95 curTop = Math.max(0,Math.min(boxTop y - mouseY,boxTop boxHeight)) ;
96 curWidth = boxLeft boxWidth-curLeft ;
97 curHeight = boxTop boxHeight-curTop ;
98 break;
99 case 1:
100 curTop = Math.max(0,Math.min(boxTop y - mouseY,boxTop boxHeight)) ;
101 curHeight = boxTop boxHeight-curTop ;
102 break;
103 case 2:
104 curTop = Math.max(0,Math.min(boxTop y - mouseY,boxTop boxHeight)) ;
105 curHeight = boxTop boxHeight-curTop ;
106 curWidth = Math.max(0,Math.min(boxWidth x-mouseX,maxWidth));
107 break;
108 case 3:
109 curWidth = Math.max(0,Math.min(boxWidth x-mouseX,maxWidth));
110 break;
111 case 4:
112 curWidth = Math.max(0,Math.min(boxWidth x-mouseX,maxWidth));
113 curHeight = Math.max(0,Math.min(boxHeight y-mouseY,maxHeight));
114 break;
115 case 5:
116 curHeight = Math.max(0,Math.min(boxHeight y-mouseY,maxHeight));
117 break;
118 case 6:
119 curLeft = Math.max(0,Math.min(boxLeft x - mouseX,boxLeft boxWidth)) ;
120 curWidth = boxLeft boxWidth-curLeft ;
121 curHeight = Math.max(0,Math.min(boxHeight y-mouseY,maxHeight));
122 break;
123 case 7:
124 curLeft = Math.max(0,Math.min(boxLeft x - mouseX,boxLeft boxWidth)) ;
125 curWidth = boxLeft boxWidth-curLeft ;
126 break;
127 case 8:
128 curLeft = Math.max(0,Math.min(boxLeft x - mouseX,maxWidth-boxWidth)) ;
129 curTop = Math.max(0,Math.min(boxTop y - mouseY,maxHeight-boxHeight)) ;
130 break;
131 }
132 box.style.left = curLeft 'px' ;
133 box.style.top = curTop 'px' ;
134 box.style.width = curWidth 'px' ;
135 box.style.height = curHeight 'px' ;
136 clipImg.childNodes[0].style.clip = "rect(" curTop "px," (curLeft curWidth) "px," (curTop curHeight) "px," (curLeft) "px)" ;
137 showPhoto(curLeft,curTop,curWidth,curHeight) ;
138 }
139 window.onmouseup = function(){
140 elem = -1 ;
141 }
142
143 //将选中的图片画在canvas上
144 function showPhoto(left,top,width,height){
145 photo.clearRect(0,0,CLIP_WIDTH,CLIP_HEIGHT) ;
146 photo.drawImage(img,-left*CLIP_WIDTH/width,-top*CLIP_HEIGHT/height,maxWidth*CLIP_WIDTH/width,maxHeight*CLIP_HEIGHT/height);
147 }
148 //获取base64格式的png图片内容
149 function funGetImg(){
150 var data = canvas.toDataURL("image/png") ;
151 data = data.replace(/\ /g,"#") ;//后台java代码中加号出问题
152 return data ;
153 }
154 //post方式将内容传给后台
155 function ajaxSendImg(str,callback){
156 var xmlhttp = new XMLHttpRequest() ;
157 xmlhttp.open("post","base64toimg.jsp",false);
158 xmlhttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
159 xmlhttp.send(str);
160 callback.call(null,xmlhttp.responseText) ;
161 }
162
163 function funUpdateImg(){
164 var data = funGetImg() ;
165 var url = "imgStr=" data.substring(22) ;
166 ajaxSendImg(url,log);
167 }
168
169 function $(id){
170 return document.getElementById(id) ;
171 }
172
173 function log(){
174 $('res').innerHTML = arguments[0] ;
175 }
176
177 function funInit(){
178 maxWidth = this.width ;
179 maxHeight= this.height ;
180 $('clipBox').appendChild(img) ;
181 var newImg = new Image() ;
182 newImg.src = this.src ;
183 $('imgBox').appendChild(newImg);
184 showPhoto(0,0,CLIP_WIDTH,CLIP_HEIGHT);
185 }
186 </script>
187 </body>
188 </html
1 <%@page contentType="text/html;charset=utf-8"%>
2 <%@page import="java.io.*,sun.misc.BASE64Decoder,sun.misc.BASE64Encoder"%>
3 <%
4 String imgStr = request.getParameter("imgStr");
5 imgStr = imgStr.replaceAll("#"," ");
6 BASE64Decoder decoder = new BASE64Decoder();
7 try{
8 byte[] b = decoder.decodeBuffer(imgStr);
9 String relPath = application.getRealPath("/") ;
10 String path = "/upload/photo.png" ;
11 File f = new File(relPath path);
12 OutputStream os = new FileOutputStream(f);
13 os.write(b);
14 os.flush();
15 os.close();
16 out.println(path);
17 }
18 catch (Exception e)
19 {
20 out.println("error");
21 }
22 %>
将base64图片内容传给jsp时候。老是会出错。发现是因为“ ”传过去就解析成其他符号了。。一直想不明白。。
只能暂时将“ ”缓存“#”,到jsp之后在repalce过来,如果有人知道是怎么回事,希望告知下。。
欢迎讨论,转载请注明出处。谢谢!