doubleyong
管理员
管理员
  • 最后登录2026-05-10
  • 发帖数1198
  • 最爱沙发
  • 喜欢达人
  • 原创写手
  • 社区居民
  • 忠实会员
阅读:9021回复:0

使用Canvas裁剪头像并上传

楼主#
更多 发布于:2017-06-05 17:25

图片:head.png


如上图,:实现点击“上传头像”弹出,文件选择框,然后,可以移动红色框,最后,点击保存,将绝色框里的内容保存为一张图片,并保存到服务器
要实现这些功能,有几个问题,下面我们一一来解决
1. 点击,上传头像,弹出文件选择框
   html中:

<div onclick="chooseFile()">上传头像</div>
 <input type="file" name="txtUpload" id="txtUpload" style="display:none"/>


js中,实现chooseFile方法,代码如下:

function chooseFile(){
        var file = document.getElementById("txtUpload");
        file.click();
    }

2. 选择后,将选择的图片,显示到canvas中,让用户可以看到。(注:这时图片不上传到服务器,那如何实现呢)
txtfile.onchange=function(){
            var file = txtfile.files[0]; var reader = new FileReader(file);
            reader.readAsDataURL(file);
reader.onload=function(){
                img.src = this.result; //这里的this就是指reader读取出来的结果 img.onload=function(){
                    context.drawImage(img,0,0,300,400);
                    // DrawImage(img); //缩放图片
//                    context.drawImage(img,0,0,img.width,img.height); //按缩放后图片大小进行绘制
                 //   img.src = myCanvas.toDataURL("image/png");  doubleyong modify by 20190425, 加上后,图片绘制不出来

                }
            }
        }
3. 点击移动框,可以在图片区域内,可以进行移动
html 代码:
<div class="box">
    <canvas id="myCanvas" height="400px" width="300px"></canvas>
    <div id="myCut"></div>
</div>

js代码:

var cj = document.getElementById("myCut");

        cj.onmousedown=function(){
            var e=window.event||arguments[0];
            var downX= e.clientX;
            var downY= e.clientY;
            var positionX=parseInt(document.defaultView.getComputedStyle(cj,null).left);
            var positionY=parseInt(document.defaultView.getComputedStyle(cj,null).top);
            var chaX=downX-positionX;
            var chaY=downY-positionY;
            cj.onmousemove=function(){
                var e=window.event||arguments[0];
                var X= e.clientX;
                var Y= e.clientY;
                var left = parseInt(X)-chaX;
                var top = parseInt(Y)-chaY;

                if(left>0&&left<100){
                    cj.style.left=left+"px";
                    leftL=left;  //leftL 红框与显示区域左边的距离
                }
                if(top>0&&top<200){
                    cj.style.top=top+"px";
                    topL=top;
                }

            }
            cj.onmouseup=function(){
                cj.onmousemove=null;
            }
        }
4. 点击“保存”按钮,将红色框内的图片内容,保存为一张图片
  //新canvas 绘制选择的图片部分
        var newCanvas = document.createElement("canvas");
        newCanvas.height = 200; //注,这里直接写数字,不带px newCanvas.width =200;
        //将红框内的图片,绘制到新canvas中
        newCanvas.getContext("2d").drawImage(img,leftL,topL,200,200,0,0,200,200);
        var imgData = newCanvas.toDataURL("image/png"); //将图片转为base64

        console.log(imgData);
        var cutimg = document.getElementById("myCutImg");
        cutimg.src = newCanvas.toDataURL("image/png"); //直接将base64赋给img对象的src属性,可显示


5. 将base64使用ajax将截取的图片数据传到服务器端

// 1. 创建一个对象
        var httpRequest;
        if(window.XMLHttpRequest){ //DOM方式
            httpRequest = new XMLHttpRequest(); //DOM的方式
        }else if(window.ActiveXObject){
            httpRequest = new ActiveXObject("Microsoft.XMLHTTP"); //IE浏览器
        }
        //2. 打开连接(发起请求)
        // open 的三个参数 , 1个参数: 提交方式get/post 2. 提交的URL地址, 3. 同步/异步application/x-www-form-urlencoded
        httpRequest.open("post","uploadImage.do");
        //httpRequest.setRequestHeader("Content-type","application/x-www-form-urlencoded");
        //注:这里虽是post方式,但不指头类型

        //3. 接收影响回来的数据
        httpRequest.onreadystatechange=function(){
            if(httpRequest.status==200&&httpRequest.readyState==4) {
                //canvas显示图片
                var json = JSON.parse(httpRequest.responseText);

                var img = new Image();
                img.src = json.msg.url;
               }
        }

        //4.如果 提交方式为get请求,那发送为null
        //如果 提交方式 为post,那这个地方跟参数

        httpRequest.send("imgData="+imgData); // 发送信息

    或使用jquery的ajax提交

  $.ajax({
            type:"post",
            url:"upload.do",
            data:{imgData:imgDataUrl}
        })

6. 服务器商,接受数据,然后将数据保存为文件

//将裁剪后的base64格式文件,保存为图片的POST方法
app.post('/upload', function(req, res){
    //接收前台POST过来的base64
    var imgData = req.body.imgData;
    console.log(imgData);
    //过滤data:image/png;base64,
    var base64Data = imgData.replace(/data:image\/png;base64,/, "").replace(/\s/g,"+");
    //使用express接收POST值后,base64编码字符串中的“+”号被替换成空格了,
    // 引起编码出错,img.src = base64Data;直接把nodejs服务挂掉。
    //.replace(/\s/g,"+") 就是把空格还原成+号
    var dataBuffer = new Buffer(base64Data, 'base64');
    console.log(base64Data);

    var filename = new Date().getTime()+"_small.png";//文件名,加入时间,避免文件名重复
    fs.writeFile("public/image/"+filename, dataBuffer, function(err) {
        if(err){
            res.send(err);
        }else{
            res.send("保存成功!");
        }
    });
});
好了,按照以上的步骤,你就可以实现出一个裁剪头像的效果,当然,还有一些问题没有解决,如图片会变形,那可以看看图片的缩放。还有就是图片的原大小与缩放后的图片不同,这个可以做放大,镜或缩小镜,让用户自己控制,
希望,对你有所帮助,有帮助的话,帮忙顶个帖子^_^
知识需要管理,知识需要分享
游客


返回顶部

公众号

公众号