【问题标题】:How to check if a canvas is blank? [duplicate]如何检查画布是否为空白? [复制]
【发布时间】:2013-06-27 12:36:54
【问题描述】:

如何检查 HTML5 画布是否为空白或有彩色像素。有没有快速的方法?

<canvas width="200" height="200"></canvas>

【问题讨论】:

    标签: javascript html canvas


    【解决方案1】:

    更快:使用context.getImageData() 查找“彩色”像素(非零值)

    // returns true if all color channels in each pixel are 0 (or "blank")
    function isCanvasBlank(canvas) {
      return !canvas.getContext('2d')
        .getImageData(0, 0, canvas.width, canvas.height).data
        .some(channel => channel !== 0);
    }
    

    正如@Kaiido 指出的那样,您可以通过枚举Uint32Array 像素而不是每个像素中的每个颜色通道来获得更好的性能。

    // returns true if every pixel's uint32 representation is 0 (or "blank")
    function isCanvasBlank(canvas) {
      const context = canvas.getContext('2d');
    
      const pixelBuffer = new Uint32Array(
        context.getImageData(0, 0, canvas.width, canvas.height).data.buffer
      );
    
      return !pixelBuffer.some(color => color !== 0);
    }
    

    较慢:将数据 URL 与空白画布进行比较

    function isCanvasBlank(canvas) {
      const blank = document.createElement('canvas');
    
      blank.width = canvas.width;
      blank.height = canvas.height;
    
      return canvas.toDataURL() === blank.toDataURL();
    }
    

    Benchmark

    演示

    document.getElementById('check').addEventListener('click', function() {
      const blank = isCanvasBlank(document.getElementById('canvas'));
    
      alert(blank ? 'blank' : 'not blank');
    });
    
    document.getElementById('draw').addEventListener('click', function() {
      drawOnCanvas(document.getElementById('canvas'));
    });
    
    document.getElementById('clear').addEventListener('click', function() {
      const canvas = document.getElementById('canvas');
    
      canvas.getContext('2d').clearRect(0, 0, canvas.width, canvas.height);
    });
    
    function isCanvasBlank(canvas) {
      const context = canvas.getContext('2d');
    
      const pixelBuffer = new Uint32Array(
        context.getImageData(0, 0, canvas.width, canvas.height).data.buffer
      );
    
      return !pixelBuffer.some(color => color !== 0);
    }
    
    function drawOnCanvas(canvas) {
      const context = canvas.getContext('2d');
    
      context.fillStyle = '#' + Math.floor(Math.random() * 0xFFFFFF).toString(16);
    
      context.fillRect(Math.floor(Math.random() * canvas.width),
        Math.floor(Math.random() * canvas.height),
        Math.floor(Math.random() * canvas.width),
        Math.floor(Math.random() * canvas.height));
    }
    canvas {
      display: block;
      margin-top: 10px;
      border: 1px solid black;
    }
    <button id="check"> Check </button>
    <button id="draw"> Draw </button>
    <button id="clear"> Clear </button>
    <canvas id="canvas" width="200" height="200"></canvas>

    【讨论】:

    • 你有两次 canvas.width。
    • 我花了 20 分钟来弄清楚为什么会失败,因为我从 JSFiddle 复制了函数,然后回到这里并看到一切正确,JSFiddle 是错误的,它有提到的 2 个宽度由@wbt11a 提供。
    • 哎呀!对于那个很抱歉。我已经更新了答案中的链接。
    • @Devashish 我添加了一个新方法,根据基准似乎更快。
    • 您可以通过检查 Uint32Array 而不是检查 Uint8Clamped 来获得更快的速度:jsbench.me/e3jsy70r9c/1
    猜你喜欢
    • 1970-01-01
    • 2012-06-17
    • 2021-09-12
    • 1970-01-01
    • 2014-08-11
    • 1970-01-01
    • 2011-07-02
    • 2018-07-03
    相关资源
    最近更新 更多