简体   繁体   中英

How to check if something is drawn on canvas

How do I check if there is data or something drawn on a canvas?

I have this <canvas id="my-canvas"></canvas> element, and I want to check if my canvas has something drawn on it.

A good way I have found is to use the toDataURL() function and compare it with another, blank canvas. If they are different, than the one you are comparing it to has something on it. Something like this:

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!');
});

Here is a fiddle

I can't take credit for this, I just stumbled upon it and it fixed my same issue. Maybe this will help somebody at some point.

Instead of checking every single pixel, it may be much more efficient to merely record every time the canvas gets filled or stroked.

Once a fill or stroke or has happened, then you know that something has been drawn.

Of course 'how' is very application specific, since we don't know how your canvas is getting drawn on in the first place.

I haven't seen this kind of question in Stackoverflow till now.. but an interesting One to answer..

The only way(I guess) is to check through pixel by pixel, ie, check the R, G, B, A of each pixel,
if those values are equal to zero then we can say that the pixel is empty..
This is the technique I used to write the below code snippet.. just go through it

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

To get the pixels of the canvas you have to use the getImageData(); method -> getImageData() reference

And to check if every pixels of your imageData are at 0 or 255.

Your ImageData will have 4 cells per pixels, rgba and you cn access every pixels by incrementing your count by 4 and looking each 4 next numbers to hve your rgba value.

You can also get an empty image's DataURL and compare your canvas's DataURL to it to see if it's empty ;)

Here a tips from 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' );

Hey might be a late answer for this but I was kind of horrified to have the need of an extra canvas for comparing. So here is my solution:

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

I hope this helps, you can do a function with it but the solution is way cleaner than what I have seen around.

I know it might be a late answer but try this solution:

Simon Sarris says that:

Instead of checking every single pixel, it may be much more efficient to merely record every time the canvas gets filled or stroked.

While that would be more efficient, however I did manage to find a way to detect the canvas to see if it is drawn/painted on by checking every pixel. I had a play around to see what results does the pixel data returns when the canvas is empty and when it is been painted on. I found out that when the canvas is empty all of the pixel data returns 0 in all index positions of the array. So I used that to detect if there is any 0 's or not and as the result I made it so it returns a boolean. If the canvas has been drawn on then it returns true and if it hasn't then it returns false .

You can test it Here on JSfiddle

code:

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;
        }

I hope this helps :)

HTML Code:

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

JS Code:

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

Note: If your provide height and width to main canvas then same height and width to apply on blank canvas also.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM