|
阅读:9021回复:0
使用Canvas裁剪头像并上传图片: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("保存成功!"); } }); }); 好了,按照以上的步骤,你就可以实现出一个裁剪头像的效果,当然,还有一些问题没有解决,如图片会变形,那可以看看图片的缩放。还有就是图片的原大小与缩放后的图片不同,这个可以做放大,镜或缩小镜,让用户自己控制, 希望,对你有所帮助,有帮助的话,帮忙顶个帖子^_^ |
|
|
