[whatwg] I believe source rectangles for HTML5 Canvas drawImage are specified incorrectly
vladimir at pobox.com
Mon Sep 10 12:43:53 PDT 2012
This is pretty tricky to get right -- there's just a general graphics
problem in this case. There are valid use cases for both sampling outside
and not sampling outside the source rectangle, as well as implementation
issues for being able to do source rectangle clamping. For example, should
you be able to take a source image and draw it scaled up using 4 rectangles
(one for each quadrant) and have the result be equal to just doing it in
one draw? Or take any random subimage (for example, for efficient updates
of some destination) and draw it in.
I do agree that the spec needs some clarity here, but I don't think that
just stating that drawImage should always sample in the source is the right
thing. At best, I think a new mode toggle or flag would be needed to allow
you to select.
Additionally, I think there's a related bug filed from a while ago about
defining how to sample pixels that are outside of the source bounds -- do
you clamp to edge, do you sample transparent black, etc.
On Mon, Aug 20, 2012 at 10:09 AM, Justin Novosad <junov at chromium.org> wrote:
> Hi Kevin,
> The same artifact use to be present in Chrome not that long ago. When we
> fixed it, we chose to interpret "original image data" as meaning the part
> of the image data that is within the bounds of the of the source rectangle.
> Also, it makes more sense to do it that way. I agree that the spec could
> use more clarity here.
> I support your case that it is preferable for the filtering algorithm to
> clamp to the border of the source rectangle rather than to the border the
> border of the source image. This is essential for implementing sprite maps
> without having to waste pixels to pad the borders between tiles.
> -Justin Novosad
> On Mon, Aug 20, 2012 at 9:38 AM, Kevin Gadd <kevin.gadd at gmail.com> wrote:
> > Hi, I've been digging into an inconsistency between various browsers'
> > Canvas implementations and I think the spec might be allowing
> > undesirable behavior here.
> > The current version of the spec says
> > (
> > ):
> > If the original image data is a bitmap image, the value painted at a
> > point in the destination rectangle is computed by filtering the
> > original image data. The user agent may use any filtering algorithm
> > (for example bilinear interpolation or nearest-neighbor). When the
> > filtering algorithm requires a pixel value from outside the original
> > image data, it must instead use the value from the nearest edge pixel.
> > (That is, the filter uses 'clamp-to-edge' behavior.)
> > While clamp-to-edge is desirable, the way this is specified means that
> > it only ever clamps to the edges of the source bitmap, not to the
> > source rectangle. That means that attempting to do the equivalent of
> > css sprites or video game style 'tile sets' - where a single source
> > image contains many smaller images - is not possible, because the spec
> > allows implementations to read pixels from outside the source
> > rectangle.
> > Unfortunately, at present Internet Explorer and Firefox both read
> > pixels from outside the source rectangle, as demonstrated by this test
> > case:
> > https://dl.dropbox.com/u/1643240/canvas_artifacts.html
> > Worse still, in implementations with imageSmoothingEnabled available,
> > turning off image smoothing is not sufficient to eliminate the
> > artifacts.
> > Google Chrome appears to implement this the way you would probably
> > want it to work - by clamping to the edges of the source rectangle,
> > instead of the source image. I can't think of a good reason to prefer
> > the current behavior over what Chrome does, and I haven't been able to
> > find a reliable way to compensate for the current behavior.
> > Thanks,
> > -kg
More information about the whatwg