Javascript 自动将HTML5画布裁剪为内容

Javascript 自动将HTML5画布裁剪为内容,javascript,html,html5-canvas,Javascript,Html,Html5 Canvas,假设这是我的画布,上面画着一张邪恶的脸。我想使用toDataURL()将我邪恶的脸导出为PNG;然而,整个画布是光栅化的,包括邪恶的脸和画布边缘之间的“空白” +---------------+ | | | | | (.Y. ) | | /_ | | \____/ | | | | | +---------------+ 裁剪/修剪/收

假设这是我的画布,上面画着一张邪恶的脸。我想使用
toDataURL()
将我邪恶的脸导出为PNG;然而,整个画布是光栅化的,包括邪恶的脸和画布边缘之间的“空白”

+---------------+
|               |
|               |
|     (.Y. )    |
|      /_       |
|     \____/    |
|               |
|               |
+---------------+
裁剪/修剪/收缩包装画布到其内容的最佳方式是什么,这样我的PNG就不会比面部的“边界框”大,如下图所示?最好的方法似乎是缩放画布,但假设内容是动态的。。。?我相信应该有一个简单的解决办法,但我还是逃避了,谷歌搜索太多了

+------+
|(.Y. )|
| /_   |
|\____/|
+------+

谢谢

如果我理解得很好,您希望“修剪”掉图像/绘图周围的所有部分,并将画布调整到该大小(就像在Photoshop中执行“修剪”命令一样)

这是我要怎么做的

  • 运行所有画布像素,检查其alpha分量是否大于0(这意味着在该像素中绘制了某些内容)。或者,你可以检查r,g,b值,例如,如果你的画布背景是用纯色填充的

  • 获取最左上角像素的te坐标非空,最右下角像素的te坐标相同。因此,您将获得包含画布区域的ImageAy“矩形”的坐标,该区域不是空的

  • 存储该区域的像素数据

  • 将画布调整为新的尺寸(我们在第2步得到的区域尺寸)

  • 将保存的区域粘贴回画布

  • 等等,瞧:)

    根据画布的大小,访问像素数据的速度相当慢(如果它很大,可能需要一段时间)。使用原始画布像素数据有一些优化(我想MDN上有一篇关于这个主题的文章),我建议你去谷歌看看

    我在JSFIDLE中准备了一个小草图,您可以将其用作代码的起点

    希望我帮了你。
    c:.

    编辑(请参阅)

    函数cropImageFromCanvas(ctx){
    var canvas=ctx.canvas,
    w=画布宽度,h=画布高度,
    pix={x:[],y:[]},
    imageData=ctx.getImageData(0,0,canvas.width,canvas.height),
    x、 y,指数;
    对于(y=0;y0){
    pix.x.push(x);
    pix.y.push(y);
    } 
    }
    }
    sort(函数(a,b){返回a-b});
    排序(函数(a,b){返回a-b});
    var n=pix.x.length-1;
    w=1+pix.x[n]-pix.x[0];
    h=1+pix.y[n]-pix.y[0];
    var cut=ctx.getImageData(pix.x[0],pix.y[0],w,h);
    画布宽度=w;
    canvas.height=h;
    ctx.putImageData(切割,0,0);
    var image=canvas.toDataURL();//在新窗口中打开裁剪过的图像
    var win=window.open(图像“U blank”);
    win.focus();
    }
    
    这里投票最多的答案,以及我在网上发现的多修剪一个像素的实现,这在尝试从画布中修剪文本时非常明显。我自己写了一本对我更有用的书:

    var img=新图像;
    img.onload=()=>{
    var canvas=document.getElementById('canvas');
    canvas.width=img.width;
    canvas.height=img.height;
    var ctx=canvas.getContext('2d');
    ctx.drawImage(img,0,0);
    document.getElementById('button')。addEventListener('click',()=>{
    autoCropCanvas(画布,ctx);
    document.getElementById('button').remove();
    });
    };
    img.src='数据:image/png;base64,IVBORW0KGGOAAAANSUHEUGAABOOAAA2CAYAAADWOSSPAAAF/0lEQVR4nO3dTagdZx3H8W+SXQGGQGRWBAHEQLOP60IQI2I7EEPGL6EEPGL6EEPGUKGVJ+AOOUASWXLZWOGYSXLZFE5UMZKBK7N3N3NZ3Z3ZI3F4W4W0GBUM//N95ZLF86ZPWAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF1SG3Z7KBAAAC5PZ60+VT5+1+2+nt1V/XWEE4/hVM66t+BFF4/HV6/HV6/HV6+1+1个VV4/HV1/VVV6/HV6/HV6/HV6+BFFQ4/HV6/HV6+1+6+1+1+1+1+1+1+1+1+1+1+1+1+1+4+6+6+4+6+6+6+6+6+6+6+6+6+6+6+6+6+6+6+6+6+6+6+6+6+6+6+6+6+6+6+6+6+6+6+6+6+6+6+6+6+6+6+6+6+6+6+6+6+6+6+6+6+6+6+6+6+6+6+6+6+6+6+6+6+XXVEVHD9C003GZESCDWAU53VUQMHTHPAXHQDHSL85FPWR5LI992 ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ92ZG0AAAAAWAZDTNB+RfXjhqbs68drB6p/N3zjf9GB6n8N4.C/C/C/C/C/C/C/C/C/C/C/C/C/C/C/C/C/C/C/C(4)C/C/C/C/C/C/C/C/C/C/C/C(4 4)是一个C(4)是一个C(4)是一个C(8)是一个中国的一个中国的一个中国的一个中国的一个中国的一个中国的一个中国的一个中国的一个中国的一个中国的一个中国的一个中国的一个中国的一个中国的一个中国的中国的一个中国的中国的一个中国的一个中国的一个中国的一个中国的一个中国的一个中国的一个中国的一个中国的一个中国的一个中国的一个中国的一个中国的一个中国的一个中国的一个中国的中国的中国的一个中国的一个中国的中国的中国的中国的中国的IEW0B3R+RRMPO0P5QANCEM6BUP+28X9Pjcep6qbx79nxOFU9u这一研究结果是一家中国政府的一家中国政府的一家中国政府的一家中国政府的一家中国政府的一家中国政府的一家中国政府的一家中国政府的一家中国政府的一家中国政府的一家中国政府的一家中国政府的一家中国政府的一家中国政府的一家中国政府的一家中国政府的一家中国政府的一家中国政府的一家中国政府的一家中国政府在一家中国的一家中国政府的一家中国的一家中国政府的一家中国的一家中国政府的一家中国政府的一家中国政府的一家中国的一家中国政府的一家中国政府的一家中国政府在一家中国的一家在一家在一家中国政府的一家中国的一家中国的一家中国的一家中国的一家中国的一家中国的一家中国的一家中国政府的一家中国的一家中国的一家中国的一家在一家在一家在一家在一家中国的一家中国的aaaaaaaaaaacxrv8D9CS03XV5TWUAAASUVORK5CYII=';
    功能autoCropCanvas(canvas,ctx){
    变量界限={
    左:0,,
    右:canvas.width,
    排名:0,
    底部:画布高度
    };
    var行=[];
    var cols=[];
    var imageData=ctx.getImageData(0,0,canvas.width,canvas.height);
    对于(var x=0;xfunction cropImageFromCanvas(ctx) {
      var canvas = ctx.canvas, 
        w = canvas.width, h = canvas.height,
        pix = {x:[], y:[]},
        imageData = ctx.getImageData(0,0,canvas.width,canvas.height),
        x, y, index;
    
      for (y = 0; y < h; y++) {
        for (x = 0; x < w; x++) {
          index = (y * w + x) * 4;
          if (imageData.data[index+3] > 0) {
            pix.x.push(x);
            pix.y.push(y);
          } 
        }
      }
      pix.x.sort(function(a,b){return a-b});
      pix.y.sort(function(a,b){return a-b});
      var n = pix.x.length-1;
    
      w = 1 + pix.x[n] - pix.x[0];
      h = 1 + pix.y[n] - pix.y[0];
      var cut = ctx.getImageData(pix.x[0], pix.y[0], w, h);
    
      canvas.width = w;
      canvas.height = h;
      ctx.putImageData(cut, 0, 0);
    
      var image = canvas.toDataURL();  //open cropped image in a new window
      var win=window.open(image, '_blank');
      win.focus();
    }