3
\$\begingroup\$

Since 2016, new Apple products (like the iPhone 7) use the P3 color space instead of the sRGB color space. Therefore I'm interesting in measuring the practical impact on some pictures I have shot.

Given a JPEG file, how can I check if it contains any pixels that are not within sRGB? And how can I mark them, e.g. turn them pink or yellow? (Or almost equivalently: How can I check if conversion to sRGB has any destructive impact on an image?)

For example, on www.astramael.com, there are various examples of images that are representable with Adobe RGB or sRGB, but cannot be accurately represented using sRGB. If you scroll a bit down, you see a picture where all non-sRGB-pixels have been replaced with light red pixels, in order to make the difference visible. How is it possible to create such an image? Which tools can be used for that?

My motivation is that I want to check the impact of a color space that is different from sRGB. I don't doubt that there are real colors that are not-in-sRGB. But are there any colors out-of-sRGB in any of the pictures that I shot with my iPhone 7? How common are out-of-sRGB-colors really?

Update: It would be nice to have a freeware or opensource tool for that. I don't want to install Adobe Photoshop or a similar heavyweight application. In fact a 300KB-sized command line tool could solve the problem. I'm an iOS- and macOS-developer, so it would be fine if the program works on that platform too (this includes being installable by following the standard install instructions found in the docs.) For me, it would (probably) be an option to write such a program on my own; but I hoped that someone did it already.

\$\endgroup\$
1
  • \$\begingroup\$ Isn't the POINT of having a colour space to define a valid interpretation for all RGB values? \$\endgroup\$ Dec 17, 2019 at 18:34

3 Answers 3

2
\$\begingroup\$

The Foundry Nuke or Blackmagic Design Fusion perform operations with floating point numbers which allow you to implement that type of tests. It essentially boils down to convert your image from DCI-P3 to sRGB colourspace and check for any negative numbers in the output image/array. Here is an example in The Foundry Nuke:

The Foundry Nuke - DCI-P3 to sRGB

This is the above node tree that you can copy-paste into the application:

set cut_paste_input [stack 0]
version 10.5 v2
Read {
inputs 0
file /Users/kelsolaar/Downloads/Italy-P3.jpg
format "600 400 0 0 600 400 1 "
origset true
name Read1
selected true
xpos -50
ypos 11
}
set N30e152e0 [stack 0]
push $N30e152e0
Colorspace {
illuminant_in DCI-P3
primary_in DCI-P3
bradford_matrix true
name Colorspace1
selected true
xpos -50
ypos 91
}
Expression {
expr0 "r < 0 ? 1 : 0"
expr1 "g < 0 ? 1 : 0"
expr2 "b < 0 ? 1 : 0"
name Expression1
selected true
xpos -50
ypos 115
}
Viewer {
inputs 2
frame_range 1-100
input_number 1
name Viewer1
selected true
xpos -50
ypos 139
}

If you are comfortable with Python, you can also use Colour as follows:

import numpy as np

import colour
import colour.plotting

DCI_P3 = colour.read_image('/Users/kelsolaar/Downloads/Italy-P3.jpg')

sRGB = colour.RGB_to_RGB(DCI_P3, colour.DCI_P3_COLOURSPACE, colour.sRGB_COLOURSPACE)

colour.plotting.image_plot(np.where(sRGB < 0, 1.0, 0.0), 'sRGB - Out of Gamut')

sRGB - Out of Gamut

The source image is available at this url: https://webkit.org/blog-files/color-gamut/Italy-P3.jpg

As mentioned by @doug in the comments below, and given that the original post is about images in general and also specific to iPhone images, it is important to note that colours with high chroma and luminance might also overflow the [0-255] range. Those values need to be accounted for if you encode your images in an low dynamic range container, e.g. JPEG, PNG or any integer based image format.

\$\endgroup\$
9
  • 1
    \$\begingroup\$ While one of the out of gamut indications is converting to sRGB results in a negative value in one or more RGB channels, one should also check for sRGB values that exceed sRGB range, 255 for 8 bit sRGB. \$\endgroup\$
    – doug
    Aug 27, 2017 at 20:23
  • \$\begingroup\$ @doug: I'm not sure to understand, how can you get values over 255 with a 8-bit integer container? To add to that, with floating point numbers, values over 1 are high dynamic range, they are still part of the colourspace gamut but HDR. \$\endgroup\$
    – Kel Solaar
    Aug 27, 2017 at 20:59
  • \$\begingroup\$ When you convert from a larger colorspace to a smaller one the math can produce results that both underflow the minimum and overflow the maximum RGB values. Underflow will shift a color outside of the smaller chromaticity triangle. Overflow, OTOH, creates a color that exceeds the achievable luminosity of the smaller color space at a particular chromaticity. If one allows negative sRGB values there is no limit to chromaticity and if one allows unlimited magnitudes there is no limit to intensity. Typically, the white point RGB(255,255,255), 8-bit, forces this limit on any given display. \$\endgroup\$
    – doug
    Aug 28, 2017 at 7:07
  • \$\begingroup\$ In the case of overflow, it probably depends if you want to consider HDR values out of gamut for your particular use case. Any HDR image will very likely have values exceeding 1.0 no matter its encoding colourspace and AFAIK we don't consider that being out of gamut in the VFX industry, e.g. Paul Debevec's Grace Probe: imgur.com/a/BtJRH \$\endgroup\$
    – Kel Solaar
    Aug 28, 2017 at 7:59
  • 1
    \$\begingroup\$ Thanks for noting the overflow issue. It's something that often gets overlooked when a wide gamut color is in the sRGB xy chromaticity space yet, when converted to sRGB. changes significantly. Mostly one sees this in images encoded to a standard ICC colorspace where one of the three illuminants (red or blue going to sRGB) just doesn't have enough magnitude as these are controlled by the ICC spec for "whitepoint". It can be confusing since the xy coordinate is within the sRGB triangle. One of the nifty things about HDR is better preservation of luminous, saturated colors. Great in movies. \$\endgroup\$
    – doug
    Aug 28, 2017 at 20:23
1
\$\begingroup\$

Most color management engines should have a mechanism to mark out-of-gamut pixels when converting an image from one colourspace to another.

Your image editing program may have a function to mark out of gamut pixels (maybe not iphone versions, but a possibility for desktop ones that use colour management and let you switch between colourspaces).

If you write your own programs, littleCMS (a free colour manangement engine that works with ICC profiles) definitely has such a mechanism, and if you hunt around on the web you may find someone has already put a suitable utility together.

\$\endgroup\$
0
\$\begingroup\$

One application that can show you this is Final Cut Pro X. Another is Motion.

In FCPX, create a new project and be sure to select Rec. 709 as the color space:

FCPX New Project Dialog

Import your image into your library, and then drop it into the new project. From the canvas' "View" menu select "Luminance" or "Saturation" (you should probably check both):

FCPX Canvas View Menu

If you have any out-of-gamut values, it should display zebra-stripes like this:

FCPX Zebra Stripes

In Motion, you can simply put the footage on the canvas, open the canvas' "Channels" menu, and select either "Exposure" or "Saturation":

Motion Zebra Stripes

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.