Re: Reading image bytes to a PNG in a typed array

2013-01-27 Thread Florian Bösch
If we have a context we can use in a worker on which we can set the
framebuffer to which we would bind the texture and which we can readPixel
back into bytes, which we would stick into a surfaceless 2D canvas so we
can kick off the encoding to png (or just implement it in JS after
implementing zlib) then yes, it could be done in workers.

On any account, these things are all not yet available. I've meanwhile
implemented the required functionality via the long chain of clutches that
takes 6 4092x4092 textures (albed, normal, specular, specularity,
occlusion, height) and packes them into a tarfile and offers it as a
blob-url to the user. It takes about 30 seconds to pack up, during which
the page is pretty much frozen since it's 100% synchronous. The outcome is
about 50mb in size. But hey, at least it works, after a fashion.


On Sat, Jan 26, 2013 at 7:18 PM, Gregg Tavares g...@google.com wrote:

 Could this be solved in workers?

 x) Create canvas, set to desired size
 x) Create 2D context
 x) Create imageData object
 x) Create a WebGL framebuffer object
 x) Attach texture as color target to framebuffer
 x) read back pixels into canvas2d's imageData.data member
 x) ctx.putImageData into the canvas

 1) Set CanvasProxy (or whatever it's called) to the size you want
 2) Draw Texture
 3) call CanvasProxy's toDataURL('image/png')
 4) Set the CanvasProxy back to the original size
 5) snip off the mime/encoding header
 6) implement base64 decode in JS and decode to Uint8Array

 Less steps and it's now async as well.




 On Wed, Jan 16, 2013 at 8:02 AM, Florian Bösch pya...@gmail.com wrote:

 Whatever the eventual solution to this problem, it should be the user of
 the API driving the decision how to get the data.


 On Wed, Jan 16, 2013 at 4:56 PM, Kyle Huey m...@kylehuey.com wrote:


 On Wed, Jan 16, 2013 at 7:50 AM, Glenn Maynard gl...@zewt.org wrote:

 On Wed, Jan 16, 2013 at 9:40 AM, Florian Bösch pya...@gmail.comwrote:

 Perhaps we should think of a better scheme to export data than
 toFoo(). Maybe toData('url'), toData('arraybuffer') toData('blob') or
 perhaps toData(URL), toData(ArrayBuffer) or toData(Blob). I tend to think
 that if you're starting to write toA, toB, toC, toX methods on an object,
 you've not thought this really trough what's a parameter, and what's a
 method.


 We should be avoiding the need to return data in a bunch of different
 interfaces in the first place.  If the data is large, or takes a long or
 nondeterministic amount of time to create (eg. something that would be
 async in the UI thread), return a Blob; otherwise return an ArrayBuffer.
  The user can convert from there as needed.


 Well, the problem is that we fundamentally screwed up when we specced
 Blob.  It has a synchronous size getter which negates many of the
 advantages of FileReader extracing data asynchronously.  For something like
 image encoding (that involves compression), where you have to perform the
 operation to know the size, Blob and ArrayBuffer are effectively
 interchangeable from the implementation perspective, since both require you
 to perform the operation up front.

 - Kyle






Re: Reading image bytes to a PNG in a typed array

2013-01-26 Thread Gregg Tavares
Could this be solved in workers?

x) Create canvas, set to desired size
x) Create 2D context
x) Create imageData object
x) Create a WebGL framebuffer object
x) Attach texture as color target to framebuffer
x) read back pixels into canvas2d's imageData.data member
x) ctx.putImageData into the canvas

1) Set CanvasProxy (or whatever it's called) to the size you want
2) Draw Texture
3) call CanvasProxy's toDataURL('image/png')
4) Set the CanvasProxy back to the original size
5) snip off the mime/encoding header
6) implement base64 decode in JS and decode to Uint8Array

Less steps and it's now async as well.




On Wed, Jan 16, 2013 at 8:02 AM, Florian Bösch pya...@gmail.com wrote:

 Whatever the eventual solution to this problem, it should be the user of
 the API driving the decision how to get the data.


 On Wed, Jan 16, 2013 at 4:56 PM, Kyle Huey m...@kylehuey.com wrote:


 On Wed, Jan 16, 2013 at 7:50 AM, Glenn Maynard gl...@zewt.org wrote:

 On Wed, Jan 16, 2013 at 9:40 AM, Florian Bösch pya...@gmail.com wrote:

 Perhaps we should think of a better scheme to export data than toFoo().
 Maybe toData('url'), toData('arraybuffer') toData('blob') or perhaps
 toData(URL), toData(ArrayBuffer) or toData(Blob). I tend to think that if
 you're starting to write toA, toB, toC, toX methods on an object, you've
 not thought this really trough what's a parameter, and what's a method.


 We should be avoiding the need to return data in a bunch of different
 interfaces in the first place.  If the data is large, or takes a long or
 nondeterministic amount of time to create (eg. something that would be
 async in the UI thread), return a Blob; otherwise return an ArrayBuffer.
  The user can convert from there as needed.


 Well, the problem is that we fundamentally screwed up when we specced
 Blob.  It has a synchronous size getter which negates many of the
 advantages of FileReader extracing data asynchronously.  For something like
 image encoding (that involves compression), where you have to perform the
 operation to know the size, Blob and ArrayBuffer are effectively
 interchangeable from the implementation perspective, since both require you
 to perform the operation up front.

 - Kyle





Re: Reading image bytes to a PNG in a typed array

2013-01-16 Thread Kyle Huey
On Mon, Jan 14, 2013 at 7:04 AM, Florian Bösch pya...@gmail.com wrote:

 On Mon, Jan 14, 2013 at 4:00 PM, Glenn Maynard gl...@zewt.org wrote:

 You want toBlob, not toDataURL.

 So how would I stick a blob into an arraybuffer?


I don't think there's any reason we can't have toArrayBuffer as well.  The
hard part from an implementation perspective is asynchronously encoding the
image, not what we stick it in.

- Kyle


Re: Reading image bytes to a PNG in a typed array

2013-01-16 Thread Glenn Maynard
On Wed, Jan 16, 2013 at 6:29 AM, Kyle Huey m...@kylehuey.com wrote:

 I don't think there's any reason we can't have toArrayBuffer as well.  The
 hard part from an implementation perspective is asynchronously encoding the
 image, not what we stick it in.


No technical reason, but I'd avoid adding yet more paths to do the same
thing unless there's a real gain.  It'd be bad to head down the path of
every single Blob-returning operation having an ArrayBuffer duplicate.

In this particular case, he wants ArrayBuffers to put the data in a ZIP,
which probably means he should be doing this from a worker anyway, to avoid
doing a bunch of CRC calculations on the UI thread.  In that case, the
current API isn't even inconvenient, since once you post the Blob to the
worker you can use FileReaderSync and not have an extra async operation to
do.

(Pass an array of Blobs to a worker and get back a Blob of a ZIP is a
generally useful operation, so maybe he wouldn't even have to write this
himself.)

-- 
Glenn Maynard


Re: Reading image bytes to a PNG in a typed array

2013-01-16 Thread Florian Bösch
Perhaps we should think of a better scheme to export data than toFoo().
Maybe toData('url'), toData('arraybuffer') toData('blob') or perhaps
toData(URL), toData(ArrayBuffer) or toData(Blob). I tend to think that if
you're starting to write toA, toB, toC, toX methods on an object, you've
not thought this really trough what's a parameter, and what's a method.


On Wed, Jan 16, 2013 at 4:26 PM, Glenn Maynard gl...@zewt.org wrote:

 On Wed, Jan 16, 2013 at 6:29 AM, Kyle Huey m...@kylehuey.com wrote:

 I don't think there's any reason we can't have toArrayBuffer as well.
 The hard part from an implementation perspective is asynchronously encoding
 the image, not what we stick it in.


 No technical reason, but I'd avoid adding yet more paths to do the same
 thing unless there's a real gain.  It'd be bad to head down the path of
 every single Blob-returning operation having an ArrayBuffer duplicate.

 In this particular case, he wants ArrayBuffers to put the data in a ZIP,
 which probably means he should be doing this from a worker anyway, to avoid
 doing a bunch of CRC calculations on the UI thread.  In that case, the
 current API isn't even inconvenient, since once you post the Blob to the
 worker you can use FileReaderSync and not have an extra async operation to
 do.

 (Pass an array of Blobs to a worker and get back a Blob of a ZIP is a
 generally useful operation, so maybe he wouldn't even have to write this
 himself.)

 --
 Glenn Maynard




Re: Reading image bytes to a PNG in a typed array

2013-01-16 Thread Glenn Maynard
On Wed, Jan 16, 2013 at 9:40 AM, Florian Bösch pya...@gmail.com wrote:

 Perhaps we should think of a better scheme to export data than toFoo().
 Maybe toData('url'), toData('arraybuffer') toData('blob') or perhaps
 toData(URL), toData(ArrayBuffer) or toData(Blob). I tend to think that if
 you're starting to write toA, toB, toC, toX methods on an object, you've
 not thought this really trough what's a parameter, and what's a method.


We should be avoiding the need to return data in a bunch of different
interfaces in the first place.  If the data is large, or takes a long or
nondeterministic amount of time to create (eg. something that would be
async in the UI thread), return a Blob; otherwise return an ArrayBuffer.
 The user can convert from there as needed.

-- 
Glenn Maynard


Re: Reading image bytes to a PNG in a typed array

2013-01-16 Thread Kyle Huey
On Wed, Jan 16, 2013 at 7:50 AM, Glenn Maynard gl...@zewt.org wrote:

 On Wed, Jan 16, 2013 at 9:40 AM, Florian Bösch pya...@gmail.com wrote:

 Perhaps we should think of a better scheme to export data than toFoo().
 Maybe toData('url'), toData('arraybuffer') toData('blob') or perhaps
 toData(URL), toData(ArrayBuffer) or toData(Blob). I tend to think that if
 you're starting to write toA, toB, toC, toX methods on an object, you've
 not thought this really trough what's a parameter, and what's a method.


 We should be avoiding the need to return data in a bunch of different
 interfaces in the first place.  If the data is large, or takes a long or
 nondeterministic amount of time to create (eg. something that would be
 async in the UI thread), return a Blob; otherwise return an ArrayBuffer.
  The user can convert from there as needed.


Well, the problem is that we fundamentally screwed up when we specced
Blob.  It has a synchronous size getter which negates many of the
advantages of FileReader extracing data asynchronously.  For something like
image encoding (that involves compression), where you have to perform the
operation to know the size, Blob and ArrayBuffer are effectively
interchangeable from the implementation perspective, since both require you
to perform the operation up front.

- Kyle


Re: Reading image bytes to a PNG in a typed array

2013-01-16 Thread Florian Bösch
Whatever the eventual solution to this problem, it should be the user of
the API driving the decision how to get the data.


On Wed, Jan 16, 2013 at 4:56 PM, Kyle Huey m...@kylehuey.com wrote:


 On Wed, Jan 16, 2013 at 7:50 AM, Glenn Maynard gl...@zewt.org wrote:

 On Wed, Jan 16, 2013 at 9:40 AM, Florian Bösch pya...@gmail.com wrote:

 Perhaps we should think of a better scheme to export data than toFoo().
 Maybe toData('url'), toData('arraybuffer') toData('blob') or perhaps
 toData(URL), toData(ArrayBuffer) or toData(Blob). I tend to think that if
 you're starting to write toA, toB, toC, toX methods on an object, you've
 not thought this really trough what's a parameter, and what's a method.


 We should be avoiding the need to return data in a bunch of different
 interfaces in the first place.  If the data is large, or takes a long or
 nondeterministic amount of time to create (eg. something that would be
 async in the UI thread), return a Blob; otherwise return an ArrayBuffer.
  The user can convert from there as needed.


 Well, the problem is that we fundamentally screwed up when we specced
 Blob.  It has a synchronous size getter which negates many of the
 advantages of FileReader extracing data asynchronously.  For something like
 image encoding (that involves compression), where you have to perform the
 operation to know the size, Blob and ArrayBuffer are effectively
 interchangeable from the implementation perspective, since both require you
 to perform the operation up front.

 - Kyle



Re: Reading image bytes to a PNG in a typed array

2013-01-14 Thread Anne van Kesteren
On Mon, Jan 14, 2013 at 1:20 PM, Florian Bösch pya...@gmail.com wrote:
 Having a texture in WebGL and wanting to encode it into a typed array as
 PNG, I have found that the only way to do it is the following convoluted
 method.

Could you list the use cases?
http://wiki.whatwg.org/wiki/FAQ#Is_there_a_process_for_adding_new_features_to_a_specification.3F
is relevant in particular.


-- 
http://annevankesteren.nl/



Re: Reading image bytes to a PNG in a typed array

2013-01-14 Thread Florian Bösch
The usecase is that I write a productivity application using WebGL which
has a need to bundle images residing in computed textures into one archive
(tar, zip etc.).

- The images belong together (such as normal, height, tangent, specular
color, specular power, albedo etc.)
- The archive has to land in a typed array so it can efficiently be put
into a blob url, put into an XHR for upload to cloud storage, etc.
- Which means the images encoded have to land in a typed array
- Which means the described process is currently the best on offer by
browsers.
- Which should be rectified.


On Mon, Jan 14, 2013 at 1:46 PM, Anne van Kesteren ann...@annevk.nl wrote:

 On Mon, Jan 14, 2013 at 1:20 PM, Florian Bösch pya...@gmail.com wrote:
  Having a texture in WebGL and wanting to encode it into a typed array as
  PNG, I have found that the only way to do it is the following convoluted
  method.

 Could you list the use cases?

 http://wiki.whatwg.org/wiki/FAQ#Is_there_a_process_for_adding_new_features_to_a_specification.3F
 is relevant in particular.


 --
 http://annevankesteren.nl/



Re: Reading image bytes to a PNG in a typed array

2013-01-14 Thread Glenn Maynard
On Mon, Jan 14, 2013 at 6:20 AM, Florian Bösch pya...@gmail.com wrote:

 1) Create canvas, set to desired size
 2) Create 2D context
 3) Create imageData object
 4) Create a WebGL framebuffer object
 5) Attach texture as color target to framebuffer
 6) read back pixels into canvas2d's imageData.data member
 7) ctx.putImageData into the canvas


You want to be rendering to a WebGL canvas, not a 2D canvas.  There's the
limitation of not being able to draw to anything except the displayed
canvas, but I think that's being worked on within WebGL.

8) call canvases toDataURL('image/png')
 9) snip off the mime/encoding header
 10) implement base64 decode in JS and decode to Uint8Array


You want toBlob, not toDataURL.

-- 
Glenn Maynard


Re: Reading image bytes to a PNG in a typed array

2013-01-14 Thread Florian Bösch
On Mon, Jan 14, 2013 at 4:00 PM, Glenn Maynard gl...@zewt.org wrote:

 You want toBlob, not toDataURL.

So how would I stick a blob into an arraybuffer?


Re: Reading image bytes to a PNG in a typed array

2013-01-14 Thread Glenn Maynard
On Mon, Jan 14, 2013 at 9:04 AM, Florian Bösch pya...@gmail.com wrote:

 On Mon, Jan 14, 2013 at 4:00 PM, Glenn Maynard gl...@zewt.org wrote:

 You want toBlob, not toDataURL.

 So how would I stick a blob into an arraybuffer?


http://dev.w3.org/2006/webapi/FileAPI/#dfn-filereader

-- 
Glenn Maynard