[whatwg] proposed canvas 2d API additions

Vladimir Vukicevic vladimirv at gmail.com
Mon Apr 24 15:17:36 PDT 2006

Arve's example is how I imagined putPixels working -- basically as a
potential optimization over a bunch of fillRect calls.  Even in the
presence of a higher resolution backing store, this can provide for an
optimization -- load the putPixels data into a bitmap image that's
width*height pixels and draw it to the canvas backing store with the
appropriate resolution scaling.

The use case that I'm thinking of is essentially:

pixels = c.getPixels(x, y, width, height);
/* manipulate pixels here */
c.putPixels(pixels, x, y, width, height);

That is, direct pixel manipulation, for performing some operation that
can't be done using the context API.  An example might be to perform a
desaturate on a region of the canvas to obtain a grayscale region from
a color one.  Any image-type operations (copying a region from one
place to another) should be done using the existing drawImage or other
APIs, with temporary canvases as needed.

Because of this, putPixels will end up losing quality in a
getPixels/putPixels round-trip if the backing store is higher
resolution.  I'm not sure what to do about that; one solution might be
that we specify that a pixel in the canvas backing store must map to
exactly one pixel in canvas-space; that is, that there's always a
cluster of NxN device pixels that correspond to 1 canvas pixel.  We
can then have getPixels return the actual device-resolution pixel
data, along with a resolution multiplier or somesuch.  I don't really
like that, though; I'd much rather leave putPixels as the
fillRect-type optimization, and have getPixels return a simple average
of the color of all the device pixels that compose a single target
pixel.  (Again, as with the putPixels case, this can be optimized by
simply doing a downscaling of the appropriate region of the
higher-resolution backing store into a width*height pixel buffer).

    - Vlad

On 4/24/06, Arve Bersvendsen <arveb at opera.com> wrote:
> [ Ian Hickson ]
> >> I don't understand how these are supposed to work when the underlying
> >> bitmap's device pixel space does not map 1:1 to the coordinate space.
> [ Vladimir Vukicevic ]
> > I'm not sure what you mean -- the coordinates here are explicit canvas
> > pixels, and they specifically ignore the current canvas transform.
> > So, given
> >  <canvas width="100" height="200"></canvas>
> >
> > the coordinates would be 0..99, 0..199.
> Without expressing any other opinion at the moment, I'd just like to
> clarify how Opera's implementation of getPixel/setPixel currently follows
> the coordinate space, as Vlad is suggesting here, disregarding any
> translation and rotation. Given the following script snippet:
>    gc =
> document.getElementsByTagName('canvas')[0].getContext('opera-2dgame');
>    for ( var y = 50; y < 100; y++){
>      for (var x = 50; x < 100; x++){
>        gc.setPixel(x,y,"blue");
>      }
>    }
> ... with this CSS:
>    canvas  {
>      width: 200px;
>      height: 200px;
>      border: 1px solid black;
>    }
> and the following markup:
>    <canvas width="100" height="100">
> we fill the bottom-right quadrant of the canvas, with a rectangle that is
> comprised of 100x100 CSS pixels.
> --
> Arve Bersvendsen, Opera Software ASA

More information about the whatwg mailing list