首页 > 代码库 > 基于canvas和jsp的头像剪辑上传

基于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>
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过来,如果有人知道是怎么回事,希望告知下。。

 

欢迎讨论,转载请注明出处。谢谢!

基于canvas和jsp的头像剪辑上传