Skip to content

Adding support for High Dynamic Range (HDR) imagery to HTML Canvas: a baseline proposal #9461

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
palemieux opened this issue Jun 28, 2023 · 6 comments

Comments

@palemieux
Copy link

palemieux commented Jun 28, 2023

The Color on the Web CG would very much appreciate your feedback on the following strawman, which motivates and proposes baseline modifications to the HTML Canvas API to enable support for High-Dynamic Range (HDR) imagery:

https://github.com/w3c/ColorWeb-CG/blob/8eac62f15e5b41940636beb031f6214b61e933af/hdr_html_canvas_element.md

The proposed modifications allow the HTML Canvas API to manipulate High Dynamic Range (HDR) images expressed using the widespread BT.2100 PQ and BT.2100 HLG color spaces, without precluding adding future HDR capabilities, such as support for additional color spaces like a linear high-dynamic range color space.

@palemieux palemieux changed the title Adding support High Dynamic Range (HDR) imagery to HTML Canvas: a baseline proposal Adding support for High Dynamic Range (HDR) imagery to HTML Canvas: a baseline proposal Jun 28, 2023
@Kaiido
Copy link
Member

Kaiido commented Jun 28, 2023

cc @whatwg/canvas

Not my domain of expertise at all, so pardon me if I'm out of context here, but the colorMetadata attribute is a bit unclear to me.
It says in the strawman that it is used to "define the tone mapping algorithm used when rendering the image to a display" (emphasize mine). Is it really to be used only when rendering to a display (like a monitor)? Authors don't really have access to that time. Also, what if they want to render two images on the same canvas, both requiring different tone mapping options?
Or is it actually meant to affect the next drawings on the context? (including compositing etc.)
If this is meant mainly for images drawn through drawImage(), maybe an alternative would be to set that option on createImageBitmap() instead?

@palemieux
Copy link
Author

colorMetadata is intended to be used whenever the image is rendered, i.e. the pixels of the image transformed, and is not limited to rendering to a physical display. I will file an issue to clarify this.

Also, what if they want to render two images on the same canvas, both requiring different tone mapping options?

Is the following use case the one you have in mind?

  • image A has a certain set of colorMetadata parameters
  • image B has a different set of colorMetadata parameters
  • image A and image B are drawn into a Canvas element

What should the colorMetadata parameters of the Canvas element be set to?

@Kaiido
Copy link
Member

Kaiido commented Jun 29, 2023

I'll continue the first branch of the discussion over at the linked issue.

Is the following use case the one you have in mind?

image A has a certain set of colorMetadata parameters
image B has a different set of colorMetadata parameters
image A and image B are drawn into a Canvas element

What should the colorMetadata parameters of the Canvas element be set to?

Yes, that's the use case I had in mind. And I'm not sure how using that API it can be handled, nor if it's actually possible to handle it.

@palemieux
Copy link
Author

One approach is to set the colorVolumeMetadata of the destination Canvas element to the union of the two color volumes (or a superset thereof). In media & entertainment, Rec. 2020 primaries + D65 white point is effectively a superset of common distribution color spaces. minimumLuminance and maximumLuminance can then be set as the union of the range covered by each of the two images.

Another approach is to simply not specify any colorVolumeMetadata, which should work fine for individual images.

Finally, the next step for the CG is to define an API that allows the web app to perform its own tone-mapping. for more complex uses or when the app needs finer control.

@palemieux
Copy link
Author

Please find below an updated proposal for adding support for High Dynamic Range (HDR) imagery to HTML Canvas.

https://github.com/w3c/ColorWeb-CG/blob/hdr_canvas_r2/hdr_html_canvas_element.md

Selected highlights of this revision to the proposal;

  • adds a linear display-referred color space (rec2100-display-linear)
  • adds display color volume information to Screen interface of the CSS Object Model
  • improves color space conversion examples

Feedback, issues and questions are welcome at mailto:[email protected] and https://github.com/w3c/ColorWeb-CG/issues.

Contacts: @palemieux and @svgeesus (Color on the Web CG co-chairs)

@mdrejhon
Copy link

mdrejhon commented Apr 4, 2025

(Crosspost from my local github)

World's First Web HDR Test Matrix

This is not even found on 'caniuse' (cc: @Fyrd) yet. Due to the emerging flagless WebGPU HDR situation, I am refactoring TestUFO 2D animations to eventually support any canvas type for common 2D animations. By summer my intent is all TestUFO animations can run on Canvas2D / WebGL / WebGPU (switchable in TestuFO settings), making flagless HDR easy in many browsers.

To make this easy, I want to team-up and/or donate time to creating a single webpage to check common HDR HTML elements (canvas/video/image). A quick visual check of true end-to-end HDR support (HTML to photons). Also complicating testing is many VMs (e.g. BrowserStack, Parallels) do not suport HDR yet, although VMWARE Fusion does support HDR.

Happy 404 Day

One time manual-test special for State of Web HDR on Windows and Mac.
Test Pass = brighter than #FFFFFF hex white supported.
Recommended Display: Any OLED or MiniLED. (LCD HDR = crap)

HDR Support Per Browser Engine, 2025-04-04

HDR Feature Chromium Webkit Gecko
VIDEO Pass Pass Mac
Images Pass v108+ Tech Preview v215+ x
Canvas2D Behind Flag v108+ x x
WebGL Behind Flag v129+ x x
WebGPU Pass v129+ Tech Preview v215+ x

Legend

A successful pass is the human visible brighter-than-#FFFFFF-white becoming visible on HDR monitor on both Windows/Mac, as indicated in below photograph example.

  • x = Failure of brighter-than-#FFFFFF-white becoming visible on HDR monitor on both Windows/Mac
  • Tech Preview = Safari Tech Preview
  • Bold = Tested on both Windows and Mac
  • Behind Flag = Requires chrome://flags "Experimental Web Platform Features" = Enabled
  • Chromium = Tested latest Chrome (Windows/Mac), Edge (Windows) Brave (Windows)
  • Webkit = Tested latest Safari (Mac)
  • Gecko = Tested latest FireFox (Windows/Mac)
  • Mac = Mac-only
  • Numbers = Best-Effort Estimated Minimum Versions of the most common user of the browser engine (Other users, e.g. Edge of Chromium, may be off by a few version points, especially Edge added AVIF a bit later after Chrome)
    (Linux not tested yet at this time; will add Linux test suites in 2026)

Test Suite (Manual Tests)

Example Test Pass Of End-To-End HDR: Brighter-Than-#FFFFFF White

The background of the gregbenz page is RGB Hex #FFFFFF. Anything that successfully shows as HDR, means the browser compositing framebuffer is already successfully matching display colorspace (usually float16x3 = 48bit framebuffer), and successfully displaying whites brighter than hex #FFFFFF white, confirming definitive end-to-end HDR support.

Image
Note: These are from the HDR image test page (the colors/gradients/text are AVIF HDR images).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

3 participants