W3C home > Mailing lists > Public > whatwg@whatwg.org > July 2009

[whatwg] Canvas context.drawImage clarification

From: Gregg Tavares <gman@google.com>
Date: Thu, 9 Jul 2009 15:58:57 -0700
Message-ID: <de4bd3190907091558ke863b06ub6ad95e5a2cc8d9c@mail.gmail.com>
Hello, I'm new to the list so I hope this is the right place and format.

I've been having a look at the canvas tag API specification and I noticed at

least one ambiguity. (I'm guessing those that have been on the list for a
while are laughing)

The specific ambiguity I'd like to bring up has to do with the several
versions
of a function, context.drawImage. They take width and height values.  The
spec
does not make it clear what is supposed to happen with negative values.

My personal interpretation and preference is that negative values should

(a) be legal and
(b) draw backward, flipping the image.

The specification currently says:

"The source rectangle is the rectangle whose corners are the four points
(sx, sy), (sx+sw, sy), (sx+sw, sy+sh), (sx, sy+sh).

...

The destination rectangle is the rectangle whose corners are the four
points (dx, dy), (dx+dw, dy), (dx+dw, dy+dh), (dx, dy+dh)."

Well, simple math would suggest that if sx = 10, and sw = -5 then it still
defines a valid rectangle.

Unfortunately since the spec is ambiguous the current browsers that
implement
this all do it differently. Firefox and Opera draw nothing with a negative
width or height. Safari and Chrome draw to the rectangle defined by negative

widths and heights but do not flip the image.

I'd like to make a passionate plea that the spec say "implementations must
support negative widths and negative heights and draw the image backward
effectively flipping the result".

Coming from a graphics and game development background we use the ability to

flip images all the time. I know that I can achieve similar results by using
a
transform matrix but still it would be much easier to just make negative
widths
and heights specifically part of the spec.

Also, I'd like to suggest that a widths and heights of 0 for source should
be
valid as well as rectangles outside of the source also be valid and that
this
part of the spec.

"If the source rectangle is not entirely within the source image, or if one
of
the sw or sh arguments is zero, the implementation must raise an
INDEX_SIZE_ERR
exception."

be changed to reflect that.

Coming from a graphics background I see no reason why if I let my user size
an
image in a canvas I should have to special case a width or height of zero.
Just
draw nothing if the width or height is zero. Similarly, if I was to provide
a UI
to let a user choose part of the source to copy to the dest and I let them
define
a rectangle on the source and drag it such that all or part of it is off the

source I see no reason why I should have to do extra math in my application
to
make that work when simple clipping of values in drawImage would make all
that
extra work required by each app disappear.

Another way to look at that is in OpenGL, if my texture coordinates are set
less than 0 or greater than 1 the GPU does not fail. Why should drawImage
act any differently?

The next issue related to drawImage is that the spec does not specify how to

filter an image when scaling it. Should it use bi-linear interpolation?
Nearest
Neighbor? Maybe that should stay implementation dependent? On top of that
the spec
does not say what happens at the edges and the different browsers are doing
different things. To give you an example, if you take a 2x2 pixel image and
scale it to 256x256 using drawImage. All the major browsers that currently
support the canvas tag will give you an image where the center of each pixel
is
around center of each 128x128 corner of the 256x256 result. The area inside
the
area defined by those 4 points is rendered very similar on all 4 browsers.
The
area outside though, the edge, is rendered very differently. On Safari,
Chrome
and Opera the colors of the original pixels continue to be blended all the
way to
the edge of the 256x256 area. On Firefox though, the blending happens as
though
the source image was actually 4x4 pixels instead of 2x2 where the edge
pixels
are all set to an RGBA value of 0, 0, 0, 0. It then draws that scaled image
as
as though the source rectangle was sx = 1, sy = 1, sw = 2, sh = 2 so that
you
get a progressively more and more translucent color towards the edge of the
rectangle.

I don't know which is right but with low resolution source images the 2 give

vastly different results.

Could these ambiguities be clarified in the spec?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.whatwg.org/pipermail/whatwg-whatwg.org/attachments/20090709/17c519b3/attachment-0001.htm>
Received on Thursday, 9 July 2009 15:58:57 UTC

This archive was generated by hypermail 2.4.0 : Wednesday, 22 January 2020 16:59:14 UTC