不想思考 發表於 2020-6-10 23:11:00

web图片前端裁剪功能实现_利用html5 canvas技术实现图片裁剪

<p>用户上传头像然后截图的需求很常见,很多做法是把图像发送到后端,把裁剪后的结果发送给浏览器,这种方式会增加处理时延。最近正好学习了HTML5里的canvas,发现它的图片处理功能比较强大,就打算用canvas提供的API实现纯前端的剪切。这里头关键有三步:显示未经处理的图片,得到裁剪区域,显示裁剪后的区域。我们分别讨论:</p>
<p>&nbsp;</p>
<h3>1. 显示未经处理的图片</h3>
<p>&nbsp; &nbsp; &nbsp; &nbsp;创建一个canvas,用drawImage(img,0,0,canvas.width,canvas.height)就可以。主要这里的img是一个Image类的object, 用new Image创建。</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)">1</span> <span style="color: rgba(0, 0, 255, 1)">var</span> img = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Image();
</span><span style="color: rgba(0, 128, 128, 1)">2</span>   img.src = <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">./beauty.jpg</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">3</span> img.onload =<span style="color: rgba(0, 0, 0, 1)"> function(){
</span><span style="color: rgba(0, 128, 128, 1)">4</span>         cxt1.drawImage(img,<span style="color: rgba(128, 0, 128, 1)">0</span>,<span style="color: rgba(128, 0, 128, 1)">0</span>,canvas1.width,canvas1.height); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">一定要写在onload回调中,否则看不到图片</span>
<span style="color: rgba(0, 128, 128, 1)">5</span> }</pre>
</div>
<p><span style="position: relative; left: -100000px">设计坞https://www.wode007.com/sites/73738.html</span></p>
<p>&nbsp;</p>
<h3>2. 得到裁剪区域</h3>
<div>&nbsp; &nbsp; &nbsp; &nbsp; 用一个position:absolute的div框来选择裁剪区域,通过javascript提供的方法能得到该div在canvas中所处的位置(x,y),然后用getImageData(srcX,srcY,width,height)得到选择框中的像素点。 这里需要知道,通过canvas.getBoundingClientRect().left和canvas.getBoundingClientRect().top可以得到canvas相对于浏览器视图的左边和上边位置。</div>
<p>&nbsp;</p>
<h3>3. 显示裁剪后的区域</h3>
<div>&nbsp; &nbsp; &nbsp; &nbsp;这部分是最复杂的。假设getImageData得到了imgData, 需要创建一个canvas2,用canvas2.putImageData(imgData,0,0,canvas2.width,canvas2.height)将选择框里的像素绘制到这个临时的canvas2里。然后用canvas2.toDataURL("image/png")将canvas2转为dataurl类型的图片。有了dataurl后,就可以正常显示裁剪后的图片了。</div>
<div>&nbsp; &nbsp; &nbsp; &nbsp;那么问题来了。为什么不能直接把getImageData得到的imgData通过putImageData绘制到最终要显示的区域,而非要创建一个临时的canvas2(不再页面上显示)呢?其实这是我想出来的一个折中方案。用putImageData绘制的画布上,只能按照等比例或者更小比例显示imgData,如果你想把剪切出来的图片放大显示,putImageData是不能支持的(这个结论是我经过测试发现的)。所以为了看到放大后的剪切区域(即使牺牲清晰度),就要用drawImage方法了,而drawImage的第一个参数不能是一堆像素数据,就只能用一个临时的canvas来作为像素数据和dataurl之间的桥梁了。</div>
<p>&nbsp;</p>
<h3>最后,上一段测试代码(可运行):</h3>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> &lt;!DOCTYPE html&gt;
<span style="color: rgba(0, 128, 128, 1)"> 2</span> &lt;html&gt;
<span style="color: rgba(0, 128, 128, 1)"> 3</span> &lt;head lang=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">en</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;
<span style="color: rgba(0, 128, 128, 1)"> 4</span>   &lt;meta charset=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">UTF-8</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;
<span style="color: rgba(0, 128, 128, 1)"> 5</span>   &lt;title&gt;&lt;/title&gt;
<span style="color: rgba(0, 128, 128, 1)"> 6</span>   &lt;style&gt;
<span style="color: rgba(0, 128, 128, 1)"> 7</span> <span style="color: rgba(0, 0, 0, 1)">.mark{
</span><span style="color: rgba(0, 128, 128, 1)"> 8</span> <span style="color: rgba(0, 0, 0, 1)">    position:absolute;
</span><span style="color: rgba(0, 128, 128, 1)"> 9</span> <span style="color: rgba(0, 0, 0, 1)">    height:100px;
</span><span style="color: rgba(0, 128, 128, 1)">10</span> <span style="color: rgba(0, 0, 0, 1)">    width:100px;
</span><span style="color: rgba(0, 128, 128, 1)">11</span> <span style="color: rgba(0, 0, 0, 1)">    left:100px;
</span><span style="color: rgba(0, 128, 128, 1)">12</span> <span style="color: rgba(0, 0, 0, 1)">    top:180px;
</span><span style="color: rgba(0, 128, 128, 1)">13</span>   border:1px solid #<span style="color: rgba(128, 0, 128, 1)">000</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">14</span> <span style="color: rgba(0, 0, 0, 1)">    cursor:move;
</span><span style="color: rgba(0, 128, 128, 1)">15</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">16</span>   &lt;/style&gt;
<span style="color: rgba(0, 128, 128, 1)">17</span> &lt;/head&gt;
<span style="color: rgba(0, 128, 128, 1)">18</span> &lt;body&gt;
<span style="color: rgba(0, 128, 128, 1)">19</span> &lt;canvas id=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">c1</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;&lt;/canvas&gt; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">显示原图像</span>
<span style="color: rgba(0, 128, 128, 1)">20</span> &lt;div <span style="color: rgba(0, 0, 255, 1)">class</span>=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">mark</span><span style="color: rgba(128, 0, 0, 1)">"</span> id=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">mark</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;&lt;/div&gt;
<span style="color: rgba(0, 128, 128, 1)">21</span> &lt;canvas id=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">c3</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;&lt;/canvas&gt; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">显示剪切后的图像</span>
<span style="color: rgba(0, 128, 128, 1)">22</span> &lt;script&gt;
<span style="color: rgba(0, 128, 128, 1)">23</span>   <span style="color: rgba(0, 0, 255, 1)">var</span> canvas1 = document.getElementById(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">c1</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 128, 128, 1)">24</span>   <span style="color: rgba(0, 0, 255, 1)">var</span> oMark = document.getElementById(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">mark</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 128, 128, 1)">25</span>   <span style="color: rgba(0, 0, 255, 1)">var</span> canvas3= document.getElementById(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">c3</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 128, 128, 1)">26</span>   canvas1.height = <span style="color: rgba(128, 0, 128, 1)">300</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">27</span>   canvas1.width=<span style="color: rgba(128, 0, 128, 1)">300</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">28</span>   canvas3.height=<span style="color: rgba(128, 0, 128, 1)">100</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">29</span>   canvas3.width=<span style="color: rgba(128, 0, 128, 1)">100</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">30</span>   <span style="color: rgba(0, 0, 255, 1)">var</span> cxt1 = canvas1.getContext(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">2d</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 128, 128, 1)">31</span>   <span style="color: rgba(0, 0, 255, 1)">var</span> img = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Image();
</span><span style="color: rgba(0, 128, 128, 1)">32</span>   img.src = <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">./beauty.jpg</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">33</span>   <span style="color: rgba(0, 0, 255, 1)">var</span> srcX = oMark.offsetLeft-<span style="color: rgba(0, 0, 0, 1)">canvas1.getBoundingClientRect().left;
</span><span style="color: rgba(0, 128, 128, 1)">34</span>   <span style="color: rgba(0, 0, 255, 1)">var</span> srcY = oMark.offsetTop-<span style="color: rgba(0, 0, 0, 1)">canvas1.getBoundingClientRect().top;
</span><span style="color: rgba(0, 128, 128, 1)">35</span>   <span style="color: rgba(0, 0, 255, 1)">var</span> sWidth =<span style="color: rgba(0, 0, 0, 1)"> oMark.offsetWidth;
</span><span style="color: rgba(0, 128, 128, 1)">36</span>   <span style="color: rgba(0, 0, 255, 1)">var</span> sHeight =<span style="color: rgba(0, 0, 0, 1)"> oMark.offsetHeight;
</span><span style="color: rgba(0, 128, 128, 1)">37</span>
<span style="color: rgba(0, 128, 128, 1)">38</span>   <span style="color: rgba(0, 0, 255, 1)">var</span> canvas2 = document.createElement(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">canvas</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 128, 128, 1)">39</span>   <span style="color: rgba(0, 0, 255, 1)">var</span> cxt2=canvas2.getContext(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">2d</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 128, 128, 1)">40</span>   img.onload =<span style="color: rgba(0, 0, 0, 1)"> function(){
</span><span style="color: rgba(0, 128, 128, 1)">41</span>         cxt1.drawImage(img,<span style="color: rgba(128, 0, 128, 1)">0</span>,<span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">,canvas1.width,canvas1.height);
</span><span style="color: rgba(0, 128, 128, 1)">42</span>         <span style="color: rgba(0, 0, 255, 1)">var</span> dataImg =<span style="color: rgba(0, 0, 0, 1)"> cxt1.getImageData(srcX,srcY,sWidth,sHeight)
</span><span style="color: rgba(0, 128, 128, 1)">43</span>         canvas2.width =<span style="color: rgba(0, 0, 0, 1)"> sWidth;
</span><span style="color: rgba(0, 128, 128, 1)">44</span>         canvas2.height =<span style="color: rgba(0, 0, 0, 1)"> sHeight;
</span><span style="color: rgba(0, 128, 128, 1)">45</span>         cxt2.putImageData(dataImg,<span style="color: rgba(128, 0, 128, 1)">0</span>,<span style="color: rgba(128, 0, 128, 1)">0</span>,<span style="color: rgba(128, 0, 128, 1)">0</span>,<span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">,canvas2.width,canvas2.height)
</span><span style="color: rgba(0, 128, 128, 1)">46</span>         <span style="color: rgba(0, 0, 255, 1)">var</span> img2 = canvas2.toDataURL(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">image/png</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">47</span>
<span style="color: rgba(0, 128, 128, 1)">48</span>         <span style="color: rgba(0, 0, 255, 1)">var</span> cxt3=canvas3.getContext(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">2d</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 128, 128, 1)">49</span>         <span style="color: rgba(0, 0, 255, 1)">var</span> img3 = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Image();
</span><span style="color: rgba(0, 128, 128, 1)">50</span>         img3.src =<span style="color: rgba(0, 0, 0, 1)"> img2;
</span><span style="color: rgba(0, 128, 128, 1)">51</span>         img3.onload=<span style="color: rgba(0, 0, 0, 1)"> function(){
</span><span style="color: rgba(0, 128, 128, 1)">52</span>             cxt3.drawImage(img3,<span style="color: rgba(128, 0, 128, 1)">0</span>,<span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">,canvas3.width,canvas3.height)
</span><span style="color: rgba(0, 128, 128, 1)">53</span> <span style="color: rgba(0, 0, 0, 1)">      }
</span><span style="color: rgba(0, 128, 128, 1)">54</span> <span style="color: rgba(0, 0, 0, 1)">    }
</span><span style="color: rgba(0, 128, 128, 1)">55</span> &lt;/script&gt;
<span style="color: rgba(0, 128, 128, 1)">56</span> &lt;/body&gt;
<span style="color: rgba(0, 128, 128, 1)">57</span> &lt;/html&gt;</pre>
</div>
<p>&nbsp;</p><br><br>
来源:https://www.cnblogs.com/ypppt/p/13090080.html
頁: [1]
查看完整版本: web图片前端裁剪功能实现_利用html5 canvas技术实现图片裁剪