[whatwg] putImageData
I was just doing some putImageData tests last night, and found that firefox does not allow putImageData to specify a target that extends beyond the bounds of the canvas. Given that getImageData can request bounds that extend beyond the canvas region (3.14.11.1.10) I would expect to be able to use putImageData in a similar manner, eg. canvas.putImageData(canvas.getImageData(-50,-50,200,200), -50, -50) should succeed. I'd just like the spec to state clearly that this should (or, i suppose, should not :( ) work as Expected, and allow putImageData to work as getImageData does. --Oliver
Re: [whatwg] putImageData() and getImageData()
Anne van Kesteren wrote: On Sat, 12 May 2007 17:54:25 +0200, Anne van Kesteren [EMAIL PROTECTED] wrote: These features are nice but I don't think authors will understand that imagedata.height != canvas.height (likewise for width). Authors will just make something that works in their browser and then assume it will work everywhere else. Which would horribly break. Even the more experienced canvas developers playing with these features have already made these mistakes. I'm not quite sure what a good solution to this problem would be. The best way forward would probably be to get rid of canvas device pixels and just make such a pixel map a canvas pixel. This means that getImageData() and putImageData() work similarly to toDataURL() and drawImage(). This will save JS developers some brain twisting sessions. If people really want high resolution canvas they could just make it high resolution and scale it down for display using CSS. Incidentally such an approach might get us rid of all the floats currently in the API... -- Mathieu 'p01' HENRI JavaScript developer, Opera Software ASA
[whatwg] putImageData() and getImageData()
These features are nice but I don't think authors will understand that imagedata.height != canvas.height (likewise for width). Authors will just make something that works in their browser and then assume it will work everywhere else. Which would horribly break. Even the more experienced canvas developers playing with these features have already made these mistakes. I'm not quite sure what a good solution to this problem would be. -- Anne van Kesteren http://annevankesteren.nl/ http://www.opera.com/
Re: [whatwg] putImageData() and getImageData()
On 12/05/07, Anne van Kesteren [EMAIL PROTECTED] wrote: These features are nice but I don't think authors will understand that imagedata.height != canvas.height (likewise for width). Authors will just make something that works in their browser and then assume it will work everywhere else. Which would horribly break. Even the more experienced canvas developers playing with these features have already made these mistakes. Looking for people using getImageData already, I find: http://canvaspaint.org/paint.js - incorrect (though commented out) http://svn.sourceforge.net/viewvc/jsmsx/trunk/msx.js?view=markup - incorrect http://www.thescripts.com/forum/thread521112.html - incorrect http://tech.groups.yahoo.com/group/canvas-developers/files/buttons.html (or maybe http://f1.grp.yahoofs.com/v1/gORFRoOLlxuXtJddXwdSyravD-aFfgNuYoSzjI8vUevuBxus3V1sXs5xckiHKd1osiUpDE_bku-vtGMFPV_M-2JZkLKXTqc/buttons.html) - correct I couldn't find any others doing anything with the ImageData.width/height, but three of those four will break when somebody implements getImageData with imagedata.width != canvas.width. -- Philip Taylor [EMAIL PROTECTED]
Re: [whatwg] putImageData() and getImageData()
On 12/05/07, Philip Taylor [EMAIL PROTECTED] wrote: On 12/05/07, Anne van Kesteren [EMAIL PROTECTED] wrote: These features are nice but I don't think authors will understand that imagedata.height != canvas.height (likewise for width). Authors will just make something that works in their browser and then assume it will work everywhere else. Which would horribly break. Even the more experienced canvas developers playing with these features have already made these mistakes. Looking for people using getImageData already, I find: [...] three of those four will break when somebody implements getImageData with imagedata.width != canvas.width. It may also be worth noting that it looks (as far as I can tell) like nearly everyone (in those examples and elsewhere) is working from the concept that a 'pixel' in the canvas coordinate space really is an actual pixel with a single colour value, and that fillRect(x, y, 1, 1) will draw one pixel (assuming a sensible transformation matrix and integer coordinates). I believe there's the same problematic assumption when you do img.src = ctx.toDataURL(); ...; ctx.drawImage(img) that pixels are pixels and it's not going to change size, but toDataURL saves each device pixel as an image pixel (though actually that seems unspecified) whereas drawImage draws each image pixel as one canvas pixel. I think it would make much more sense (and be much less error-prone) if canvas acted like a dynamic bitmap img and the browser just scaled up the bitmap before rendering to the screen, rather than optionally using a higher-resolution buffer for all the intermediate drawing. That matches the behaviour when you change the canvas's size with CSS - ... the element can be sized arbitrarily by a style sheet. During rendering, the image is scaled to fit this layout size. It would reduce the quality of the output to some extent, but in the current situation it seems likely that people will write code that simply doesn't work at all when the canvas has more device pixels than expected. Browsers already have to do as-nice-as-possible scaling for static bitmap images on high-res/zoomed displays, so it wouldn't be any worse than that. For people who really do want high quality output and know what they're doing, there could be some way to query the current canvas-display scaling factor (taking account of high-res displays, zoomed pages, CSS scaling, etc) and they can manually change the canvas's width/height to get a 1:1 match between device pixels and canvas pixels. Then they can even update the size of the bitmap every frame, so it continues looking good if the user has zoomed in on the page. Or they could use SVG. -- Philip Taylor [EMAIL PROTECTED]
Re: [whatwg] putImageData() and getImageData()
On Sat, 12 May 2007 17:54:25 +0200, Anne van Kesteren [EMAIL PROTECTED] wrote: These features are nice but I don't think authors will understand that imagedata.height != canvas.height (likewise for width). Authors will just make something that works in their browser and then assume it will work everywhere else. Which would horribly break. Even the more experienced canvas developers playing with these features have already made these mistakes. I'm not quite sure what a good solution to this problem would be. The best way forward would probably be to get rid of canvas device pixels and just make such a pixel map a canvas pixel. This means that getImageData() and putImageData() work similarly to toDataURL() and drawImage(). If people really want high resolution canvas they could just make it high resolution and scale it down for display using CSS. Incidentally such an approach might get us rid of all the floats currently in the API... -- Anne van Kesteren http://annevankesteren.nl/ http://www.opera.com/
Re: [whatwg] putImageData() and getImageData()
On 12/05/07, Anne van Kesteren [EMAIL PROTECTED] wrote: The best way forward would probably be to get rid of canvas device pixels and just make such a pixel map a canvas pixel. This means that getImageData() and putImageData() work similarly to toDataURL() and drawImage(). If people really want high resolution canvas they could just make it high resolution and scale it down for display using CSS. Incidentally such an approach might get us rid of all the floats currently in the API... With those pixels being the same (i.e. a canvas width=100 height=100 will always make the browser create a 100*100*4 byte array to store the data and to work in, regardless of what size it's finally going to be drawn to the screen), then it would be helpful to get rid of floats only in getImageData/putImageData. It's still sensible and useful to e.g. draw rectangles at float coordinates, because of antialiasing - if you do fillStyle='white'; fillRect(0, 0, 0.5, 0.5) so one pixel is 25% covered, then it will be approximated by setting one canvas pixel ( = one canvas device pixel, i.e. 4 bytes in the canvas's backing bitmap) to rgba(255, 255, 255, 0.25). This is how existing browsers handle it, e.g. http://canvex.lazyilluminati.com/misc/subpixel.html - they approximate subpixel rendering by doing antialiasing into a 3x3 bitmap, and then eventually scale the 3x3 bitmap up just before drawing to the screen. (Opera does that final scaling by repeating each pixel, Firefox does it more smoothly with some interpolation, but in both cases the canvas is originally drawing onto a 3x3 pixel bitmap.) This would disallow people from implementing antialiasing via supersampling, e.g. storing 8x8 subpixel values per canvas pixel and then scaling downwards when rendering, because putPixelData(getPixelData()) would require only one colour value to exist for each canvas pixel. But it seems nobody implements it with supersampling now, probably because it uses far too much memory and normal antialiasing is a good enough approximation - I currently think the predictability and simplicity of requiring one storage pixel per canvas pixel is worth that theoretical limitation. (And if somebody wants higher-resolution output, they can still do canvas width=800 height=800 style=width:100px; height:100px.) -- Philip Taylor [EMAIL PROTECTED]