【问题标题】:How to check if something is drawn on canvas如何检查是否在画布上绘制了某些东西
【发布时间】:2011-06-06 09:11:20
【问题描述】:

如何检查画布上是否有数据或绘制的东西?

我有这个<canvas id="my-canvas"></canvas> 元素,我想检查我的画布上是否画了一些东西。

【问题讨论】:

  • 你的画布在哪里?在页面上?在小程序上?在手机上?
  • 我编辑了我的帖子。基本上我只是想检查我的 HTML 页面上的元素,如果它上面有东西。
  • 画布中是否有需要监控的原生绘图功能?人们如何在画布上绘画?

标签: javascript html canvas


【解决方案1】:

我发现的一个好方法是使用toDataURL() 函数并将其与另一个空白画布进行比较。如果它们不同,则与您要与之比较的那个不同。像这样的:

canvas = document.getElementById('editor');
ctx = canvas.getContext('2d');

canvas.addEventListener('mousemove',function(e){
    ctx.lineTo(e.pageX,e.pageY);
    ctx.stroke();
});

document.getElementById('save').addEventListener('click',function(){
    if(canvas.toDataURL() == document.getElementById('blank').toDataURL())
        alert('It is blank');
    else
        alert('Save it!');
});

这是fiddle

我对此不以为然,我只是偶然发现了它,它解决了我同样的问题。也许这会在某个时候对某人有所帮助。

【讨论】:

  • 当我得到空白画布的 .toDataURL() 时,它也会返回数据 url,所以我无法比较你的方式。
【解决方案2】:

与其检查每一个像素,不如只记录画布每次被填充或描边时的效率。

一旦发生填充或描边,那么您就知道已经绘制了一些东西。

当然,“如何”是特定于应用程序的,因为我们一开始并不知道您的画布是如何绘制的。

【讨论】:

    【解决方案3】:

    到目前为止,我还没有在 Stackoverflow 中看到过这样的问题..但是一个有趣的答案..

    唯一的方法(我猜)是逐个像素检查,即检查每个像素的R, G, B, A
    如果这些值等于零,那么我们可以说该像素是空的..
    这是我用来编写以下代码sn-p的技术..只需通过它

    window.onload = function() {
      var canvas  = document.getElementById('canvas');
      if(!canvas.getContext) return;
      var ctx     = canvas.getContext('2d');
      var w       = canvas.width = canvas.height = 100;
      var drawn   = null;
      var d       = ctx.getImageData(0, 0, w, w); //image data 
      var len     = d.data.length;
      for(var i =0; i< len; i++) {
        if(!d.data[i]) {
          drawn = false;
        }else if(d.data[i]) {
          drawn = true;
          alert('Something drawn on Canvas');
          break;
        }
      }
      if(!drawn) {
        alert('Nothing drawn on canvas.. AKA, Canvas is Empty');
      }
    }
    

    Test it Here

    【讨论】:

    • 感谢这看起来合乎逻辑但似乎不切实际(该代码可能对某些人有用),我确实尝试了此代码,但它大大减慢了页面速度。我经常从 Firefox 收到停止脚本消息。也许问题是我的画布很大(575px x 500px)?
    • 我在 (1280 X 580) jsbin.com/ofoto4/5 测试时没有发现问题。在 Firefox 3.6.13 上测试
    • 我的代码的其他部分可能存在一些问题。无论如何感谢这个。我仍然会考虑这一点并注意这一点。 :)
    • 1) 设置 draw=false,如果遇到 !0 则设置为 true 2) 从图像中分离数据:var imgData = d.data 但更好:3) 樱桃:使用 Int32Array一次性测试 4 个组件: var arr32 = new Int32Array(d.data.buffer); len = arr32.length;你会快 4 倍以上。 ( while ((i
    【解决方案4】:

    嘿,这可能是一个迟到的答案,但我有点害怕需要额外的画布进行比较。所以这是我的解决方案:

    if (canvas.toJSON().objects.length === 0) {
        console.log('canvas is empty');
    }
    

    我希望这会有所帮助,你可以用它来做一个功能,但解决方案比我看到的要干净得多。

    【讨论】:

      【解决方案5】:

      要获取画布的像素,您必须使用 getImageData();方法 -> getImageData() reference

      并检查 imageData 的每个像素是 0 还是 255。

      您的 ImageData 每个像素将有 4 个单元格,r g b a 并且您可以通过将计数增加 4 并查看每 4 个下一个数字来访问每个像素以获取您的 rgba 值。

      您还可以获取一个空图像的 DataURL 并将您的画布的 DataURL 与它进行比较以查看它是否为空;)

      【讨论】:

        【解决方案6】:

        这里有来自 Phrogz 的提示:https://stackoverflow.com/a/4649358

        function eventOnDraw( ctx, eventName ){
          var fireEvent = function(){
            var evt = document.createEvent("Events");
            evt.initEvent(eventName, true, true);
            ctx.canvas.dispatchEvent( evt );
          }
          var stroke = ctx.stroke;
          ctx.stroke = function(){
            stroke.call(this);
            fireEvent();
          };
          var fillRect = ctx.fillRect;
          ctx.fillRect = function(x,y,w,h){
            fillRect.call(this,x,y,w,h);
            fireEvent();
          };
          var fill = ctx.fill;
          ctx.fill = function(){
            fill.call(this);
            fireEvent();
          };
        }
        ...
        var myContext = someCanvasElement.getContext('2d');
        someCanvasElement.addEventListener( 'blargle', myHandler, false );
        eventOnDraw( myContext, 'blargle' );
        

        【讨论】:

          【解决方案7】:

          HTML 代码:

          <canvas id='mainCanvas' style='border:solid'></canvas>
          <canvas id='blankCanvas' style='display:none'></canvas>
          

          JS代码:

          var mainCanvas= new SignaturePad(document.getElementById("mainCanvas"));
          if (mainCanvas.toDataURL() == document.getElementById('blankCanvas').toDataURL()) {
                          // Canvas is blank
          }
          

          注意:如果您为主画布提供高度和宽度,那么同样的高度和宽度也适用于空白画布。

          【讨论】:

          • 这为我节省了很多时间。事实证明,例如,对于 PC 和移动浏览器中的空白画布,.toDataURL() 函数不会返回相同的结果。我正在将 PC 上空画布的硬编码“data:image/...”blob 与实际画布 .toDataURL() 进行比较,但是在移动(电话)上,它的行为与 PC 中的行为不一样。创建一个隐藏的画布并将其与正在显示的画布进行比较就可以了。谢谢!
          【解决方案8】:

          我知道这可能是一个迟到的答案,但试试这个解决方案:

          西蒙·萨里斯说:

          与其检查每一个像素,不如只记录画布每次被填充或描边时的效率。

          虽然这会更有效,但我确实设法找到了一种方法来检测画布,通过检查每个像素来查看它是否被绘制/绘制。我玩了一下,看看当画布为空时以及在画布上绘制时像素数据会返回什么结果。我发现当画布为空时,所有像素数据在数组的所有索引位置都返回0。所以我用它来检测是否有任何0's,结果我做了它,所以它返回一个布尔值。如果画布已绘制,则返回true,如果尚未绘制,则返回false

          你可以在 JSfiddle 上测试Here

          代码:

          function isDrawnOn() {
                      var imageData = context.getImageData(0, 0, canvas.width, canvas.height);
                      var data = imageData.data;
                      var result = null;
                      var counter = 0;
                      var last = data.length - 1;
                      for (var i = 0; i < data.length; i++) {
                          if (i === last && counter !== 0 && counter === last) {
                              result = false;
                              break;
                          } else if (data[i] !== 0 && data[i] > 0) {
                              result = true;
                              break;
                          } else {
                              counter++;
                              continue;
                          }
                      }
                      return result;
                  }
          
          

          我希望这会有所帮助:)

          【讨论】:

          • 如果将相同的颜色数据绘制到相同的颜色背景上会怎样..
          猜你喜欢
          • 2022-11-29
          • 2012-06-04
          • 1970-01-01
          • 2014-05-12
          • 1970-01-01
          • 2012-03-12
          • 2010-12-18
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多