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

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

  • 相关阅读:
    布局
    面向对象....(概况)
    下拉城市列表
    下拉列表
    内容窗体
    《面向对象》-继承
    《面向对象》--类
    《面向对象》第一讲
    常用的正则表达式
    正则表达式
  • 原文地址:https://www.cnblogs.com/shb190802/p/4050098.html
Copyright © 2020-2023  润新知