Closed
Bug 558188
Opened 14 years ago
Closed 14 years ago
context.drawImage with a image source from a data: uri sometimes don't work
Categories
(Core :: Graphics: Canvas2D, defect)
Tracking
()
VERIFIED
INVALID
People
(Reporter: alexl, Unassigned)
References
()
Details
User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.8) Gecko/20100216 Fedora/3.5.8-1.fc12 Firefox/3.5.8 Build Identifier: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.8) Gecko/20100216 Fedora/3.5.8-1.fc12 Firefox/3.5.8 The example does basically: var img = new Image(); img.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAIAAAD91JpzAAAAHklEQVR4AQAHAPj/AP////8AAAEHAPj/AP8A/wD/ADnUBvq4wRz/AAAAAElFTkSuQmCC"; context.drawImage(img, 0, 0); And I expect this to always work because no network i/o is necessary to load the data: uri. However, sometimes it fails with an exception like: [Exception... "Component returned failure code: 0x80040111 (NS_ERROR_NOT_AVAILABLE) [nsIDOMCanvasRenderingContext2D.drawImage]" nsresult: "0x80040111 (NS_ERROR_NOT_AVAILABLE)" location: "JS frame :: http://people.gnome.org/~alexl/canvas-bug.html :: anonymous :: line 17" data: no] This mostly happens the first time. Once its worked once, it will keep working. But if you restart firefox it will happen again the first time. If you check img.completed the failing time it will return false, and if it succeeds it is true. Reproducible: Sometimes Steps to Reproduce: 1. Load uri Actual Results: Alert with exception Expected Results: no alert, image drawn
Reporter | ||
Comment 2•14 years ago
|
||
So, i think it sometimes "working" is cache related. It fails first time, then works on every reload, but shift-reload makes it break again.
Comment 3•14 years ago
|
||
Wait for the onload event on the image before trying to use it.
Comment 4•14 years ago
|
||
Yeah, this is one of the icky parts of the web. We load all images asynchronously, even data: urls, so what you're going to have to do is: var img = new Image(); img.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAIAAAD91JpzAAAAHklEQVR4AQAHAPj/AP////8AAAEHAPj/AP8A/wD/ADnUBvq4wRz/AAAAAElFTkSuQmCC"; image.onload = function() { context.drawImage(img, 0, 0); } (untested) Basically, you just have to wait until the image is loaded. Once it's loaded, it will be in the cache forever (since you're holding a reference to it in |img|), but until onload is fired you can't be sure it's loaded.
Status: UNCONFIRMED → RESOLVED
Closed: 14 years ago
Resolution: --- → INVALID
Comment 5•14 years ago
|
||
> And I expect this to always work because no network i/o is necessary to load
> the data: uri.
Neither is it needed for file:// URIs, but we don't synchronously load those for obvious reasons.
To keep the processing model simple, all URI loads are always async, period. Otherwise you could never tell when a load is done.
Status: RESOLVED → VERIFIED
Reporter | ||
Comment 6•14 years ago
|
||
You can tell when a load is done by reading image.completed. I don't expect file:/// uris to be loaded sync, as they do i/o. But decoding data: uris is pure computation and should be possible to do sync. But whatever, i can deal with this pain too, as with all other web development pain.
Reporter | ||
Comment 7•14 years ago
|
||
Additionally i'll add what a gigantic pain this is for canvas developers. The canvas is an immediate mode rendering API, so the order you do matters a lot. In normal web stuff the html engine handles the async out of order loading of an image and putting it in place possible under other stuff when its finally loaded. However in the canvas you have to suspend all other canvas drawing operation until you get the onload callback, or you cannot guarantee the correct ordering of the drawing primitives. Not having a way to do this synchronously is a pretty big obstacle for canvas rendering.
Comment 8•14 years ago
|
||
> You can tell when a load is done by reading image.completed.
For the special case of images, yes, but not for loads in general. So all loads are async and you watch load events. While decoding a data: URI is possible to do sync, sending the various resulting notifications sync is NOT expected by either gecko internals or the web at large, for what it's worth.
I'd be fine with having a canvas API that takes image-format data and draws it into the canvas without sticking it into an HTMLImageElement first. That seems to be the right way to address your use case; I suggest bringing it up with whatwg or public-html.
You need to log in
before you can comment on or make changes to this bug.
Description
•