Skip to content

fix: normalize color space for consistent pixel values in nativeImage#48178

Merged
jkleinsc merged 12 commits intoelectron:mainfrom
felixrieseberg:felixr/native-image-color-normalization
May 8, 2026
Merged

fix: normalize color space for consistent pixel values in nativeImage#48178
jkleinsc merged 12 commits intoelectron:mainfrom
felixrieseberg:felixr/native-image-color-normalization

Conversation

@felixrieseberg
Copy link
Copy Markdown
Member

@felixrieseberg felixrieseberg commented Aug 27, 2025

Description of Change

This PR normalizes color space so that pixel values in nativeImage match if they do match visually to the user. I am not entirely sure whether we actually want this - a priori, I think this feels correct but I'm happy to be corrected.

Closes #46949

Checklist

Release Notes

Notes: fix: If a nativeImage was passed an image with a color profile, its pixel values will now be normalized to SRGB. This ensures that two visually identical images after color space application will receive similar pixel values when converted to a nativeImage.

@electron-cation electron-cation Bot added the new-pr 🌱 PR opened recently label Aug 27, 2025
@nikwen
Copy link
Copy Markdown
Member

nikwen commented Aug 27, 2025

We might want to consider this a breaking change, just to make sure we don't break any apps relying on the old behavior.

@felixrieseberg felixrieseberg force-pushed the felixr/native-image-color-normalization branch from 1445729 to 75f0685 Compare August 28, 2025 19:30
@felixrieseberg
Copy link
Copy Markdown
Member Author

I'll let @reitowo decide! I think breaking change seems reasonable

Copy link
Copy Markdown
Member

@codebytere codebytere left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Conceptually LGTM - i'm leaving semver-major for this as well.

Comment thread spec/api-native-image-spec.ts Outdated
Comment thread spec/api-native-image-spec.ts Outdated
Comment thread shell/common/api/electron_api_native_image.cc Outdated
@electron-cation electron-cation Bot removed the new-pr 🌱 PR opened recently label Sep 3, 2025
@felixrieseberg felixrieseberg force-pushed the felixr/native-image-color-normalization branch from 75f0685 to cb2e462 Compare January 24, 2026 19:02
@felixrieseberg
Copy link
Copy Markdown
Member Author

It only took me forever but I have integrated all feedback and rebased!

Copy link
Copy Markdown
Member

@reitowo reitowo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

API LGTM with a minor nit suggestion

Comment thread spec/api-native-image-spec.ts Outdated
Comment thread docs/api/native-image.md Outdated
Comment thread docs/api/native-image.md Outdated
Comment thread docs/api/native-image.md Outdated
Copy link
Copy Markdown
Member

@samuelmaddock samuelmaddock left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

API LGTM

Open to include nativeImage.getColorSpace in this PR or separate as per @reitowo's feedback.

Will approve once tests are passing.

Comment thread docs/api/native-image.md
Comment thread docs/api/native-image.md
@felixrieseberg felixrieseberg requested a review from a team as a code owner February 9, 2026 03:29
@reitowo
Copy link
Copy Markdown
Member

reitowo commented Feb 25, 2026

I think this is ready for merge?

@ckerr ckerr force-pushed the felixr/native-image-color-normalization branch 3 times, most recently from 983322a to 69a031e Compare March 23, 2026 17:31
@ckerr
Copy link
Copy Markdown
Member

ckerr commented Mar 25, 2026

@samuelmaddock @codebytere this is green now, anyone want to re-review?

Copy link
Copy Markdown
Member

@jkleinsc jkleinsc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should update the breaking changes to either 42 or 43 depending upon whether or not we want this to land in 42 or 43. I'm fine with it going into 42.

felixrieseberg and others added 9 commits April 28, 2026 11:33
toBitmap() now normalizes the color space to sRGB by default, ensuring
that visually identical images produce consistent pixel values regardless
of their original color profile (e.g., Display P3 on macOS).

An optional colorSpace parameter is added to toBitmap() to control the
target color space: 'srgb' (default), 'display-p3', or 'source' (no
conversion).

Closes electron#46949
Sort ui/gfx/ includes alphabetically: codec/jpeg_codec.h,
codec/png_codec.h, then color_space.h.
- Add breaking-changes.md entry for toBitmap() color space
  normalization under Planned Breaking API Changes (41.0)
- Update getBitmap() docs to include colorSpace option and
  breaking-changes-header since it delegates to toBitmap()
Regenerate the colorspace-srgb.png and colorspace-p3.png test fixtures
so they represent the same visual color encoded in two different source
color spaces. The updated sRGB fixture stores the color as sRGB pixel
values, while the Display P3 fixture stores the corresponding Display P3
pixel values and retains its embedded P3 ICC profile.

Even though the source bitmaps can contain different bytes, their outputs
should be byte-identical after normalization to the sRGB color space.
@ckerr ckerr force-pushed the felixr/native-image-color-normalization branch from da8835a to a4bb37c Compare April 28, 2026 16:41
@ckerr
Copy link
Copy Markdown
Member

ckerr commented Apr 28, 2026

We should update the breaking changes to either 42 or 43 depending upon whether or not we want this to land in 42 or 43. I'm fine with it going into 42.

I think I'd be OK with 42 if anyone feels strongly about it, but -- since it's a month later now -- it feels a little late in the cycle?

I've pushed two changes up to unblock this PR:

  • updated breaking-changes.md to put this change in 43.0 to address @jkleinsc's change request
  • rebased to main

@ckerr ckerr requested a review from jkleinsc April 28, 2026 16:43
@jkleinsc jkleinsc added target/43-x-y PR should also be added to the "43-x-y" branch. and removed no-backport labels May 7, 2026
@jkleinsc jkleinsc merged commit 0e354e8 into electron:main May 8, 2026
69 checks passed
@release-clerk
Copy link
Copy Markdown

release-clerk Bot commented May 8, 2026

Release Notes Persisted

fix: If a nativeImage was passed an image with a color profile, its pixel values will now be normalized to SRGB. This ensures that two visually identical images after color space application will receive similar pixel values when converted to a nativeImage.

@trop
Copy link
Copy Markdown
Contributor

trop Bot commented May 8, 2026

I have automatically backported this PR to "43-x-y", please check out #51565

@trop trop Bot added in-flight/43-x-y and removed target/43-x-y PR should also be added to the "43-x-y" branch. labels May 8, 2026
ckerr pushed a commit that referenced this pull request May 8, 2026
…#51565)

fix: normalize color space for consistent pixel values in nativeImage (#48178)

* fix: normalize color space for consistent pixel values in nativeImage

toBitmap() now normalizes the color space to sRGB by default, ensuring
that visually identical images produce consistent pixel values regardless
of their original color profile (e.g., Display P3 on macOS).

An optional colorSpace parameter is added to toBitmap() to control the
target color space: 'srgb' (default), 'display-p3', or 'source' (no
conversion).

Closes #46949

* fix: implement feedback

* fix: correct include ordering in electron_api_native_image.cc

Sort ui/gfx/ includes alphabetically: codec/jpeg_codec.h,
codec/png_codec.h, then color_space.h.

* docs: add breaking-changes entry and update getBitmap docs

- Add breaking-changes.md entry for toBitmap() color space
  normalization under Planned Breaking API Changes (41.0)
- Update getBitmap() docs to include colorSpace option and
  breaking-changes-header since it delegates to toBitmap()

* docs: linter: remove semicolons from js code samples

* docs: linter: make change description <= 120 chars

* test: fix new colorSpace spec

* test: regenerate nativeImage color-space PNG fixtures

Regenerate the colorspace-srgb.png and colorspace-p3.png test fixtures
so they represent the same visual color encoded in two different source
color spaces. The updated sRGB fixture stores the color as sRGB pixel
values, while the Display P3 fixture stores the corresponding Display P3
pixel values and retains its embedded P3 ICC profile.

Even though the source bitmaps can contain different bytes, their outputs
should be byte-identical after normalization to the sRGB color space.

* docs: marked breaking change for 43.0

* chore: fix up for lint

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Felix Rieseberg <f@anthropic.com>
@trop trop Bot added merged/43-x-y PR was merged to the "43-x-y" branch. and removed in-flight/43-x-y labels May 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api-review/approved ✅ merged/43-x-y PR was merged to the "43-x-y" branch. semver/major incompatible API changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

nativeImage.toBitmap() doesn't preserve color matrix / color space information.

8 participants