#646: Canvas 2D color management

Visit on Github.

Opened Jun 10, 2021

I'm requesting a TAG review of Canvas 2D color management.

This was developed in the W3C's ColorWeb CG, and has been reviewed and updated in WhatWG review. I would like TAG to put their eyes on it too!

Summary: This formalizes the convention of 2D canvases being in the sRGB color color space by default, that input content be converted to the 2D canvas's color space when drawing and that "untagged" content is to be interpreted as sRGB. This adds a parameter whereby a 2D canvas can specify a different color space (with Display P3 being the only value exposed so far). Similarly, this formalizes that ImageData is sRGB by default, and add a parameter to specify its color space.

Further details:

We'd prefer the TAG provide feedback as (please delete all but the desired option): 💬 leave review feedback as a comment in this issue and @-notify ccameron-chromium

Discussions

2021-06-14

Minutes

Assigned to next week

2021-06-21

Minutes

Lea: left a few comments -

[discussiom of p3 color spaces]

[reviewing comments]

Lea: pretty satisfied with all of his answers. One small thing - getImageData returns sRGB data even with a p3 canvas - don't think that's a good idea but he said this has already been fixed. One of the concerns I have - consistency with getContext. I guess it's fine. you set the color space when getcontext is first called - subsequent calls return context already created even if the options are different - he said that's consistent with existing context attributes like alpha. Not happy 8bit by default forever - but you can get away with 8bits in p3 though - there will be worse banding than sRGB but not super bad - so i think that's OK.

Lea: colorspace attribute mutable ? arguments pro and against. right now it's immutable. if you wanted to extend to paint API we can't. however we don't really need it there.

Rossen: need to further review. They would have the recreate only the predefined color space and 2d settings context?

Lea: you'd need to create a new canvas and paint the previous canvas on the new canvas.

Rossen: from the use case - how often do you change color space... either use initiartiated - moving to a different device - or changing the color settings...

Lea: It's unrelated to the output device. You could be working on a P3 canvas, on an sRGB device. You obviously wouldn't be able to see the non-sRGB colors in that case, but their coordinates would be unchanged.

Rossen: trying to identify the use case - when you would want to change the color space - it seems like it's pretty rare. based on that the immutable principle will reduce complexity downstream.

Lea: Agreed, also it can be made mutable in the future if there are enough use cases.

Yves: if you're changing the color space you're better off creating a new canvas anyway...

Rossen: probably cheaper from a compute point of view.

Peter: could happen a lot by accident... e.g. some library might assume sRGB...

Lea: that's what my concern was... You get back a P3 context not expecting it.

Peter: might be safer if it throws an exception ... If I create a canvas in p3 and get rendering context in srgb - it could give me a context that is srgb and does the math - or it converts the backing image store.. losing data.

Peter: mutable would be problematic. could potentially destroy data. returning an unxpected color space could cause you to draw wrong color.

Lea: silent failure worries me.

Rossen: a long transition for libraries to get onboard with color management.

Peter: safer: getConext gives you whatever space you asked for....

Lea: we don't want getContext to change what's displayed on the canvas - it should not be destructive.

Rossen: but how would the conversion happen?

Dan: what should we ask them.

Rossen: if the getContext has the explicit color space - create a context and call getContext 2d - that assumes sRGB. From this usage point of view you can throw - and teach using a stick.

Lea: he made the point that browsers who don't know about the feature would not throw.

Rossen: but for them it will be sRGB anyway... Once the feature is there and supported - you expect the library to respect it or you don't support it at all which is fine because everything is in sRGB... So teach [libraries] with a stick or carrot? carrot would be don't throw an exception but do some kind of magic that converts the colors...

Lea: what about the argument that this is the way alpha works already, so consistency. If you call getContext() with alpha: true and you have previously called getContext() with alpha: false on the same canvas, you'll silently get a context without alpha. No errors thrown. 2nd: we need to consider the case of 2 libraries working on the same context object... if the canvas changes the 1st library wouldn't know that - that would be messy. Breaks expectations of existing code...

Tess: In the current design the 2nd call to getContext returns the same context - we're concerned about the case where the 2nd caller doesn't know about new feature. Is it inspectable?

Lea: queryable using getContextAttributes - it's unclear to me whether an unsupported color space becomes sRGB or ...

Tess: I think Peter's solution of returning a new context that does the conversion - a proxy - that would break the fewest sites. But color space conversions though not computational expensive it's non-zero. Ethical Web Principle of sustainability - making lots of extra calculation is not great. Libraries don't get update so throwing sucks. Visible bugs - color space conversion errors - visible bugs might cause someone to update the library. Library authors shiould check the return color space - best practice.

Dan: that's where they're headed anyway...

[yes]

Dan: let's put it to proposed close and close at the plenary if appropriate.

ACTION: Lea to draft comment before the Plenary

Proposed comment:

Hi @ccameron-chromium,

We reviewed this proposal this week and overall we are happy with the direction. We were initially troubled by some of the design decisions, but after discussing them further, we came to the same conclusions.

Therefore, we are going to close this issue. We are looking forward to seeing this feature evolve further