WICG / canvas-color-space

Proposed web platform feature to add color management, wide gamut and high bit-depth support to the <canvas> element.
Other
81 stars 19 forks source link

Allow colorSpace attributes in getImageData and toDataURL #19

Open bensyverson opened 7 years ago

bensyverson commented 7 years ago

It would be a very useful convenience if users could request image data in a target color space / configuration. This impacts both getImageData and toDataURL.

Example use cases:

Currently the workflow would be to use the drawImage method to draw the canvas into another canvas in the destination colorspace, but that's rather inelegant.

And of course, toDataURL would need to start tagging the destination ICC profile.

svgeesus commented 3 years ago

One use of that would be if rendering has been going to one context, whose image is to be captured and sent to another context. Although, a color managed canvas could take data in any colorspace.

A more compelling use case is where an image is being assembled in a canvas, which will then be used in a non-colormanaged, single-colorspace environment such as WebGL or WebGPU. Being able to get the image in that colorspace would be a great convenience, compared to getting it in the original context colorspace and then having the user do per-pixel colorspace conversion and gamut mapping. Which is still possible, but then everyone has to re-implement it while the cancas code already has that functionality.

kdashg commented 3 years ago

I actually think that getImageData might want to be (effectively) colorspace agnostic, since the goal there is generally "let me work with the backbuffer".

toDataURL encodes based on a file format always, right? We should be embedding color space info in formats that support it there. I think that it's likely a bug in browsers today if toDataURL doesn't encode colorspace info properly, though since everything is currently srgb, we might be getting that right by-default. :) When we do add colorspaces for canvases, toDataURL will need to encode the color info.

I'm not sure I want to sign us up for doing colorspace conversions as part of that. I would rather indeed ask users to make a new canvas in the colorspace they do want, drawImage to handle colorspace conversions, and toDataURL that instead. I see you consider this inelegant but I prefer to think of it as functional decomposition. :)

There's some motion towards ImageBitmap being the way to request image processing (y-flip, etc), so maybe that's a direction to consider but for color spaces?

For example use case #3, we're still TBD on what happens if you e.g. ask for the srgb value for p3 1,0,1. I think the way we're heading is that we may decide to give you float values in the srgb space, which may be outside [0,1]. Choosing to clip implicitly would be trickily lossy. (This will probably mean leaving behind our nice hexcode representations, which don't work for >8bit anyway!)

lexaknyazev commented 3 years ago

if toDataURL doesn't encode colorspace info properly, though since everything is currently srgb, we might be getting that right by-default. :)

Chrome and Firefox generate PNGs without any colorspace metadata. Per the PNG spec, this must be interpreted as sRGB encoding with sRGB gamut, so everything just works (for now).

Generated JPEGs (with .toDataURL("image/jpeg")) also lack any colorspace metadata. AFAIR the JFIF standard requires linear YCbCr encoding with Rec. 601 gamut and RGB transformation but virtually all implementations use sRGB instead when ICC profile is not embedded.