putPixels is just a cover for drawing a bunch of 1 x 1 rects. And in general it won't be much more efficient than that, due to possible device scaling. Is drawing a bunch of 1x1 rects a common enough use case to be worth it? Seems like it would almost always be better solved by drawing an image or using other drawing calls.

getPixels, as others have mentioned, is hard to define sensibly when the canvas backing store is higher resolution than the canvas coordinate space.

Calling these "pixels" also seems misleading since they are neither device pixels nor CSS px units.

Proposed alternate design:

1) Add a call to allow copying a rect from one canvas to another. You may want to be able to control the compositing mode for this. Then you can use an offscreen canvas to store a bitmap for later drawing into your visible canvas. If this involves a change of size the implementation has the opportunity to apply intelligent scaling.

2) Add an averageColorInRect call for the benefit of "eyedropper" type tools.

I'm actually not sure how people intend to use getPixels / putPixels so I'm not 100% sure this covers the use cases.

Regards
Maciej



On Apr 21, 2006, at 12:10 PM, Vladimir Vukicevic wrote:

Hi folks,

I'd like to suggest extending the HTML canvas 2d context with a few
additions.  These are variations on some of the methods added to
Opera's "opera-2dgame" context.  The methods are intended to give
content authors direct pixel access to the canvas, as well as provide
some basic point-in-path testing functionality.

    float [] getPixels (in integer x, in integer y, in integer width,
in integer height);

Returns an array of floats representing the color values in the region
of pixels in the canvas whose upper left corner is at (x,y) and which
extends for width,height pixels.  These coordinates are in canvas
pixel space (that is, the same space that the canvas width and height
attributes are specified in).  The color values for each pixel are
returned as 4 floats, each in the range of 0.0 to 1.0, in R,G,B,A
order.  That is, given the paramters (0,0,2,2), the returned array
will be [R00 G00 B00 A00 R10 G10 B10 A10 R01 G01 B01 A01 R11 B11 G11
A11].

Note: we could return the pixels as integers in the range of 0..255,
as 8-bit color is most likely what canvases will be dealing with.
However, using floats allow us to easily extend into a 16-bit
colorspace without any API changes.  In addition, any computation
using these pixels is often done in normalized colors, so the division
by 255 would need to happen anyway.

    void putPixels (in float [] pixels, in integer x, in integer y, in
integer width, in integer height);

Does the opposite of getPixels; the given array must be exactly width
* height * 4 elements in length.  The values are to be clamped to
0.0..1.0.

    boolean pointInPathFill(in float x, in float y);

pointInPathFill returns true if the given point would be inside the
region filled by the current path, and false otherwise.  The x,y
coordinates are in the current space of the canvas; that is, they are
transformed by the CTM and do not necessarily map directly to pixels.

I'd suggest that these three functions be added directly to the "2d"
context; content authors can test for their presence by checking the
function is not null on the 2d context object.  We might want a more
comprehensive way of letting authors test whether particular features
are supported, e.g. "shadows", "pixel-access", etc, but maybe it's not
necessary.

How's this sound?

    - Vlad

Reply via email to