Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Html5 Canvas Limitations

I have been unsuccessfully trying to find documentation that details the limitations regarding the Html5 Canvas Element such as what is the largest image file size it can load etc. The reason I ask is that I have been trying to resize image sizes ranging from 50kb to 2.0mb through ctx.scale(), yet it has been horribly inconsistent in that for the same image sometimes ctx.drawImage() will be successful and other times unsuccessful (unsuccessful being no re-scaled image appears in the canvas).

I have also placed console.log(base64) to monitor the result of var base64 = canvas.toDataURL() and have noticed that when successfully resized the resized base64 will be quite a long string as expected and when unsuccessfully resized a string will still appear yet be relatively short and outputs a blank image.

Does this have something to do with memory limitations and the unsuccessful strings wrapping around themselves? If so, what are the memory limitations imposed on the canvas element?

like image 224
John Lo Avatar asked Nov 23 '12 10:11

John Lo


1 Answers

First:
Hard limitations would depend on the browser, not the canvas API.
Even then, browsers are always trying to improve that performance, so that number would always be changing.
But with WebGL and Canvas being used to make games, texture atlases / sprite atlases are HUGE .jpg/.png files.
Chances are very, very good that your images are smaller, and I've frequently used 4MB/5MB/16MB images in canvas for demonstrations.
A huge image (or dozens of them) might crash the tab, if it's big enough, but until that time, canvas hasn't really complained to me.

Second:
There are security-limitations.
Editing photos in canvas comes down to what browser you're on, and whether the file is on the same domain as your website or not.

Third:
When you say that "large files don't work, but they do sometimes..."
...that leads me to believe that your image-loading method is faulty.

If you do something like this:

var canvas = document.createElement("canvas"),
    context = canvas.getContext("2d"),
    img = new Image();

img.src = "//mydomain.com/myimg.png";
context.drawImage(img, 0, 0, img.width, img.height);

...or anything else which isn't either event-based or callback-based,
then your problem has nothing to do with canvas and has everything to do with callbacks, and that you're trying to draw the image to the canvas before the image is done loading.

If your browser has already cached a copy of the large image, or if a small image only takes a fraction of a second to download, then there's no problem.

If you try downloading an 18MB image, and draw it to the canvas as soon as you set the url for the image, then you're going to get a blank screen, because it hasn't finished loading.

Instead, you need to wait for the image to finish loading, and then draw it to the canvas when it's ready.

var canvas = document.createElement("canvas"),
    context = canvas.getContext("2d"),
    image = new Image();

image.onload = function () {
    var img = this,
        width = img.width,
        height = img.height;

    canvas.width = width;
    canvas.height = height;
    context.drawImage(img, 0, 0, width, height);

    document.body.appendChild(canvas);
};

image.src = "//mydomain.com/path-to-really-huge-image.png";

Now it could be a 16MP image. Nothing will happen until the file is done loading.
Then, the onload event fires, and does the rest of the setup.

You could make it more abstract, and turn it into a nifty program, but it feels like this is the key piece you might be missing.

like image 197
Norguard Avatar answered Oct 15 '22 11:10

Norguard