• 豌豆资源网
  • 开引网企业服务
  • 服务外包网
  • web图片前端裁剪功能实现_利用html5 canvas技术实现图片裁剪

    用户上传头像然后截图的需求很常见,很多做法是把图像发送到后端,把裁剪后的结果发送给浏览器,这种方式会增加处理时延。最近正好学习了HTML5里的canvas,发现它的图片处理功能比较强大,就打算用canvas提供的API实现纯前端的剪切。这里头关键有三步:显示未经处理的图片,得到裁剪区域,显示裁剪后的区域。我们分别讨论:

     

    1. 显示未经处理的图片

           创建一个canvas,用drawImage(img,0,0,canvas.width,canvas.height)就可以。主要这里的img是一个Image类的object, 用new Image创建。

    1 var img = new Image();
    2     img.src = "./beauty.jpg";
    3 img.onload = function(){
    4         cxt1.drawImage(img,0,0,canvas1.width,canvas1.height); //一定要写在onload回调中,否则看不到图片
    5 }

    设计坞https://www.wode007.com/sites/73738.html

     

    2. 得到裁剪区域

            用一个position:absolute的div框来选择裁剪区域,通过javascript提供的方法能得到该div在canvas中所处的位置(x,y),然后用getImageData(srcX,srcY,width,height)得到选择框中的像素点。 这里需要知道,通过canvas.getBoundingClientRect().left和canvas.getBoundingClientRect().top可以得到canvas相对于浏览器视图的左边和上边位置。

     

    3. 显示裁剪后的区域

           这部分是最复杂的。假设getImageData得到了imgData, 需要创建一个canvas2,用canvas2.putImageData(imgData,0,0,canvas2.width,canvas2.height)将选择框里的像素绘制到这个临时的canvas2里。然后用canvas2.toDataURL("image/png")将canvas2转为dataurl类型的图片。有了dataurl后,就可以正常显示裁剪后的图片了。
           那么问题来了。为什么不能直接把getImageData得到的imgData通过putImageData绘制到最终要显示的区域,而非要创建一个临时的canvas2(不再页面上显示)呢?其实这是我想出来的一个折中方案。用putImageData绘制的画布上,只能按照等比例或者更小比例显示imgData,如果你想把剪切出来的图片放大显示,putImageData是不能支持的(这个结论是我经过测试发现的)。所以为了看到放大后的剪切区域(即使牺牲清晰度),就要用drawImage方法了,而drawImage的第一个参数不能是一堆像素数据,就只能用一个临时的canvas来作为像素数据和dataurl之间的桥梁了。

     

    最后,上一段测试代码(可运行):

     1 <!DOCTYPE html>
     2 <html>
     3 <head lang="en">
     4     <meta charset="UTF-8">
     5     <title></title>
     6     <style>
     7 .mark{
     8     position:absolute;
     9     height:100px;
    10     width:100px;
    11     left:100px;
    12     top:180px;
    13     border:1px solid #000;
    14     cursor:move;
    15 }
    16     </style>
    17 </head>
    18 <body>
    19 <canvas id="c1"></canvas> //显示原图像
    20 <div class="mark" id="mark"></div>
    21 <canvas id="c3"></canvas> //显示剪切后的图像
    22 <script>
    23     var canvas1 = document.getElementById("c1")
    24     var oMark = document.getElementById("mark")
    25     var canvas3= document.getElementById("c3")
    26     canvas1.height = 300;
    27     canvas1.width=300;
    28     canvas3.height=100;
    29     canvas3.width=100;
    30     var cxt1 = canvas1.getContext("2d")
    31     var img = new Image();
    32     img.src = "./beauty.jpg";
    33     var srcX = oMark.offsetLeft-canvas1.getBoundingClientRect().left;
    34     var srcY = oMark.offsetTop-canvas1.getBoundingClientRect().top;
    35     var sWidth = oMark.offsetWidth;
    36     var sHeight = oMark.offsetHeight;
    37 
    38     var canvas2 = document.createElement("canvas")
    39     var cxt2=canvas2.getContext("2d")
    40     img.onload = function(){
    41         cxt1.drawImage(img,0,0,canvas1.width,canvas1.height);
    42         var dataImg = cxt1.getImageData(srcX,srcY,sWidth,sHeight)
    43         canvas2.width = sWidth;
    44         canvas2.height = sHeight;
    45         cxt2.putImageData(dataImg,0,0,0,0,canvas2.width,canvas2.height)
    46         var img2 = canvas2.toDataURL("image/png");
    47 
    48         var cxt3=canvas3.getContext("2d")
    49         var img3 = new Image();
    50         img3.src = img2;
    51         img3.onload  = function(){
    52             cxt3.drawImage(img3,0,0,canvas3.width,canvas3.height)
    53         }
    54     }
    55 </script>
    56 </body>
    57 </html>

     

    posted @ 2020-06-10 23:11  前端一点红  阅读(4626)  评论(0编辑  收藏  举报
  • 乐游资源网
  • 热爱资源网
  • 灵活用工代发薪平台
  • 企服知识
  • 355软件知识