W3C home > Mailing lists > Public > whatwg@whatwg.org > March 2013

Re: [whatwg] Proposal: ImageData constructor or factory method with preexisting data

From: Rik Cabanier <cabanier@gmail.com>
Date: Tue, 12 Mar 2013 15:49:57 -0700
Message-ID: <CAGN7qDA=2nfWzE0vBS4grGaEDGLhbr4YuwTp3KhHcU2t8A9kWg@mail.gmail.com>
To: Kenneth Russell <kbr@google.com>
Cc: WHAT Working Group <whatwg@whatwg.org>
On Tue, Mar 12, 2013 at 3:03 PM, Kenneth Russell <kbr@google.com> wrote:

> On Tue, Mar 12, 2013 at 2:04 PM, Rik Cabanier <cabanier@gmail.com> wrote:
> >
> >
> > On Tue, Mar 12, 2013 at 11:40 AM, Kenneth Russell <kbr@google.com>
> wrote:
> >>
> >> On Tue, Mar 12, 2013 at 11:15 AM, Rik Cabanier <cabanier@gmail.com>
> wrote:
> >> > sounds good!
> >> > I think this is a convenient and useful addition.
> >>
> >> Great.
> >>
> >> > do you want to keep doubles to define the dimensions instead of
> >> > integers? If
> >> > so, the size should probably  4 * ceil(sw) * ceil(sh)
> >>
> >> I would prefer to use integers, and only used doubles to be consistent
> >> with the other APIs like getImageData and createImageData. In this
> >> case it would make more sense to use integers, since the width and
> >> height are simply being used to interpret preexisting data in the
> >> Uint8ClampedArray.
> >
> >
> > The current canvas spec doesn't specifically state what happens with
> partial
> > pixels. What happens today?
> > (Also is there a definition somewhere that states when a pixel is
> considered
> > filled?)
>
> Safari, Firefox and Chrome all round the double arguments to
> putImageData to integers using the "truncate" rounding mode and then
> draw the source ImageData pixel-for-pixel. For example, passing 64.5
> or 64.99 for the dx or dy arguments is equivalent to passing 64.
> Here's a test case.
>
> <canvas id="canvas" width="256" height="256"></canvas>
> <script>
> var canvas = document.getElementById("canvas");
> var ctx = canvas.getContext("2d");
> var width = canvas.width;
> var height = canvas.height;
> ctx.fillRect(0, 0, width, height);
> var imageData = ctx.createImageData(width / 2, height / 2);
> for (var ii = 0; ii < imageData.data.length; ii += 4) {
>   imageData.data[ii + 0] = 0;
>   imageData.data[ii + 1] = 255;
>   imageData.data[ii + 2] = 0;
>   imageData.data[ii + 3] = 255;
> }
> // Try passing 64.5, 64.99, or 65 for one or both of these arguments
> and see the results
> ctx.putImageData(imageData, 64, 64);
> </script>
>
> In other words, the source ImageData would not be rendered into the
> canvas at a half-pixel offset if ctx.putImageData(imageData, 64.5,
> 64.5) were called.
>

Thanks for investigating this. The fact that 'truncate' is called, should
probably go in the spec.
Maybe we should change the IDL to integer.


>
>
> >> I don't think it is necessary to provide a createImageDataHD in this
> >> interface. The caller will know the devicePixelRatio and determine
> >> whether to generate high-DPI data.
> >
> > That probably won't work since it results in code that executes
> differently
> > on devices that are HD.
>
> I think it works. The application will call the new ImageData
> constructor and pass it to either putImageData or putImageDataHD.
> These interpret the incoming ImageData differently depending on the
> devicePixelRatio.
>
> In contrast, CanvasRenderingContext2D's existing createImageDataHD and
> getImageDataHD methods will create an ImageData that may have a
> different width and height from those passed in. The reason for this
> is that these methods are referring to the canvas's backing store. For
> this new constructor which simply wraps existing pixel data, the
> application knows exactly how many pixels are contained in the array,
> so it makes the most sense to take the incoming width and height
> verbatim. I don't see any advantage to having an alternate "high-DPI"
> constructor which would multiply the width and height by the
> devicePixelRatio behind the scenes.
>
>
Your proposal is:

createImageData would throw an exception if the length of the
Uint8ClampedArray was not equal to 4 * floor(sw) * floor(sh), or at
least, if the length of the array was less than this value.


So, if you create an imageData that is going to be used in putImageDataHD,
the bounds checking happens when you pass it into putImageDataHD?
It seems the imageData object should know if it was meant for an HD call.
There is no real reason why you could use it in both HD and non-HD APIs.


> >>
> >>
> >> > On Tue, Mar 12, 2013 at 10:50 AM, Kenneth Russell <kbr@google.com>
> >> > wrote:
> >> >>
> >> >> It should simply reference the Uint8ClampedArray, not copy it or do
> >> >> anything else esoteric. The only way to display an ImageData in the
> 2D
> >> >> canvas context is via the putImageData API. I am not proposing
> >> >> changing those semantics.
> >> >>
> >> >> -Ken
> >> >>
> >> >>
> >> >>
> >> >> On Mon, Mar 11, 2013 at 5:00 PM, Rik Cabanier <cabanier@gmail.com>
> >> >> wrote:
> >> >> > Do you expect that createImageData creates an internal copy of the
> >> >> > Uint8ClampedArray object or is it live?
> >> >> >
> >> >> >
> >> >> > On Mon, Mar 11, 2013 at 4:28 PM, Kenneth Russell <kbr@google.com>
> >> >> > wrote:
> >> >> >>
> >> >> >> It would be useful to be able to create an ImageData [1] object
> with
> >> >> >> preexisting data. The main use case is to display arbitrary data
> in
> >> >> >> the 2D canvas context with no data copies.
> >> >> >>
> >> >> >> Proposed IDL:
> >> >> >>
> >> >> >> [NoInterfaceObject]
> >> >> >> interface ImageDataFactories {
> >> >> >>   ImageData createImageData(Uint8ClampedArray data, double sw,
> >> >> >> double
> >> >> >> sh);
> >> >> >> };
> >> >> >> Window implements ImageDataFactories;
> >> >> >> WorkerGlobalScope implements ImageDataFactories;
> >> >> >>
> >> >> >> createImageData would throw an exception if the length of the
> >> >> >> Uint8ClampedArray was not equal to 4 * floor(sw) * floor(sh), or
> at
> >> >> >> least, if the length of the array was less than this value.
> (Similar
> >> >> >> wording would be used to that of CanvasRenderingContext2D's
> >> >> >> createImageData.)
> >> >> >>
> >> >> >> I don't think it is necessary to provide a createImageDataHD in
> this
> >> >> >> interface. The caller will know the devicePixelRatio and determine
> >> >> >> whether to generate high-DPI data.
> >> >> >>
> >> >> >> [1]
> >> >> >>
> >> >> >>
> >> >> >>
> http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#imagedata
> >> >> >>
> >> >> >> Comments?
> >> >> >>
> >> >> >> Thanks,
> >> >> >>
> >> >> >> -Ken
> >> >> >
> >> >> >
> >> >
> >> >
> >
> >
>
Received on Tuesday, 12 March 2013 22:50:32 GMT

This archive was generated by hypermail 2.3.1 : Tuesday, 12 March 2013 22:50:33 GMT