18

It is very clear question, but I've done a lot of research and didn't find answer. StackOverflow question as this or this are about jpeg converting. This is about python build-in library.

So, how to convert sRGB to AdobeRGB and vice versa??? I mean a mathematical function, that convert 3 bytes to 3 bytes. No jpges, and so on. Just mathematical function to convert colors using pen and paper.

Yes, photoshop does it in fact and there are some strange online calculators, that show another result.

Why can't I find a simple formula in google?

I got to thinking, that I don't know something and there is no straight answer to my question.

I will be very grateful if someone can describe, what's going on or give formula.

UPDATE

Large array of results for integer rgbs will be also correct answer.

Community
  • 1
  • 1
lenden
  • 800
  • 2
  • 14
  • 38
  • I think (but I'm not sure), that this kind of conversion is not as simple as it shows. Maybe, these links can help a little: [Completely Painless Programmer's Guide to XYZ, RGB, ICC, xyY, and TRCs](http://ninedegreesbelow.com/photography/xyz-rgb.html) and [Colour Space Conversions (PDF)](http://www.poynton.com/PDFs/coloureq.pdf) – Gomiero Oct 17 '16 at 17:03
  • Generally this kind of conversion is done in two parts, sRGB→XYZ then XYZ→AdobeRGB. I can't see any reason why the two operations couldn't be combined. – Mark Ransom Oct 18 '16 at 21:08
  • See [RGB/XYZ Matrices](http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html) for the formula you are seeking. – davidcondrey Oct 21 '16 at 08:05
  • @MarkRansom sRGB→XYZ contains non-linear operation. That's the reason two ops coundn't combined, I think. And reference white point for sRGB is D65, for AdobeRGB is D50. That maybe another reason not combining them. And using XYZ is more flexible concerning convert to another color spaces. – Toris Oct 22 '16 at 16:45
  • I have been trying for almost a week to come up with an answer to this question, but it's not as easy as it looks. It turns out the XYZ ranges aren't standardized - sRGB uses Y<=80 while Adobe RGB uses Y<=160, and they have different black intensities as well. The worst part is not being able to test my results, since I don't have Photoshop available. I may try to take one more stab at it tonight. – Mark Ransom Oct 24 '16 at 15:41
  • @MarkRansom Out of range values (and sometimes in range values) are converted with software specific algorithm (Photoshop and other software may have different outputs). We can get theoretical answer with formulas in spec sheets, but not practical I think. It's intermediate to intermediate transform. sRGB values must be adjusted with input device profile (intermediate 1), sRGB -> (XYZ) -> AdobeRGB with software specific conversion (intermediate 2), and convert for output device. And without ICC profile, some of them are not done. – Toris Oct 25 '16 at 16:59
  • NB: In Adobe RGB spec sheet, XYZ have two types. For values with ICC profile and without profile. – Toris Oct 25 '16 at 17:03

2 Answers2

10

Here is Python code to implement the formulas. As noted in the comments, you convert from one color space to XYZ (normalized) then from XYZ to the new color space. I'm not 100% happy with the accuracy of these functions, but it should get you in the ballpark. As I come up with refinements I'll edit them into the answer.

def linear_sRGB(c):
    if c <= 0.04045:
        return c / 12.92
    else:
        return pow((c + 0.055) / 1.055, 2.4)

def sRGB_to_XYZn(r, g, b):
    Rlin = linear_sRGB(r / 255.0)
    Glin = linear_sRGB(g / 255.0)
    Blin = linear_sRGB(b / 255.0)
    Xn = Rlin * 0.4124 + Glin * 0.3576 + Blin * 0.1805
    Yn = Rlin * 0.2126 + Glin * 0.7152 + Blin * 0.0722
    Zn = Rlin * 0.0193 + Glin * 0.1192 + Blin * 0.9505
    return Xn, Yn, Zn

def gamma_sRGB(c):
    if c <= 0.0031308:
        return 12.92 * c
    else:
        return 1.055 * pow(c, 1/2.4) - 0.055

def XYZn_to_sRGB(Xn, Yn, Zn):
    Rlin = Xn * 3.2406255 + Yn *-1.5372080 + Zn *-0.4986286
    Glin = Xn *-0.9689307 + Yn * 1.8757561 + Zn * 0.0415175
    Blin = Xn * 0.0557101 + Yn *-0.2040211 + Zn * 1.0569959
    R = round(255 * gamma_sRGB(Rlin))
    G = round(255 * gamma_sRGB(Glin))
    B = round(255 * gamma_sRGB(Blin))
    return R, G, B

def linear_AdobeRGB(c):
    if c <= 0.0:
        return 0.0
    return pow(c, 2.19921875)

def AdobeRGB_to_XYZn(R, G, B):
    Rlin = linear_AdobeRGB(R / 255.0)
    Glin = linear_AdobeRGB(G / 255.0)
    Blin = linear_AdobeRGB(B / 255.0)
    Xn = Rlin * 0.57667 + Glin * 0.18556 + Blin * 0.18823
    Yn = Rlin * 0.29734 + Glin * 0.62736 + Blin * 0.07529
    Zn = Rlin * 0.02703 + Glin * 0.07069 + Blin * 0.99134
    return Xn, Yn, Zn

def gamma_AdobeRGB(c):
    if c <= 0.0:
        return 0.0
    return pow(c, 1/2.19921875)

def XYZn_to_AdobeRGB(Xn, Yn, Zn):
    Rlin = Xn * 2.04159 + Yn *-0.56501 + Zn *-0.34473
    Glin = Xn *-0.96924 + Yn * 1.87597 + Zn * 0.04156
    Blin = Xn * 0.01344 + Yn *-0.11836 + Zn * 1.01517
    R = round(255 * gamma_AdobeRGB(Rlin))
    G = round(255 * gamma_AdobeRGB(Glin))
    B = round(255 * gamma_AdobeRGB(Blin))
    return R, G, B
Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
  • I have already make my own code like this, but I think you've made more serious research, so I think it should be correct answer, thank you. – lenden Oct 25 '16 at 09:37
  • @MarkRansom It's better adding note XYZ is for which white point. sRGB itself is not locked for D65. (And also needed for ICC profile connection space (ex, XYZ pcs v2 in spec sheet) or not.) – Toris Oct 25 '16 at 17:12
  • @Toris, Mark's code is not using ICC PCS, he's not using ICC at all. He is going direct from a D65 RGB to a D65 XYZ to a D65 RGB. Because he's using XYZ D65 no Chromatic Adaptation is required. See this useful page: http://brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html – Myndex Apr 29 '19 at 02:29
2

It's a little complicated ones, so please read spec sheets if you need formulas.

sRGB (PDF)
https://www.w3.org/Graphics/Color/srgb
Adobe RGB (Oct.12,2004 draft) (PDF)
http://www.color.org/adobergb.pdf
Adobe RGB (1998) (PDF)
https://www.adobe.com/digitalimag/pdfs/AdobeRGB1998.pdf

Wiki is also good.
sRGB
https://en.wikipedia.org/wiki/SRGB_color_space
Adobe RGB
https://en.wikipedia.org/wiki/Adobe_RGB_color_space


For testing, check color conversion settings.
Software specific conversion may occur.
(mainly if out of range, but in some settings, not out of range values also be affected)

ex. Photoshop color settings
http://help.adobe.com/en_US/creativesuite/cs/using/WS6A727430-9717-42df-B578-C0AC705C54F0.html#WS6078C298-CB20-4dc8-ACD4-D344110AA026

About rendering intents
Perceptual
Aims to preserve the visual relationship between colors ... even though the color values themselves may change.

Related readings
http://www.color-management-guide.com/conversion-mode-perceptual-relative-colorimetric-rendering-intent.html


Using XYZ is more flexible concerning about converting to other color spaces than direct (between sRGB and Adobe RGB) conversion.

RGB color space
https://en.wikipedia.org/wiki/RGB_color_space


Conversion between sRGB and XYZ contains non-linear operation.
So, direct conversion between sRGB and Adobe RGB is difficult.

See Specification of the transformation section in wiki of sRGB. (The reverse transformation part.)

from spec sheet

If R, G, B are less than or equal to 0.04045
RL = R/12.92
...
If R, G, B are greater than 0.04045
RL = ((R + 0.055)/1.055)^2.4
...

RL for linear(XYZ(D65)), R for sRGB in this formula.
Green and blue also have same formulas.


Not preventing direct conversion between other color spaces but,
conversion between Adobe RGB and XYZ also contains non-linear operation. (Rounding to int.)

More precisely, it is Adobe RGB(in float values) to Adobe RGB(in int values) conversion.


NB: Intended white points for them are different.
(as there purpose are different. sRGB for display, Adobe RGB for photos.)
And conversion matrix in spec sheets are for D65(sRGB) and D50 or D65(Adobe RGB).

We should think about 3 things.
RGB value itself, value range (and correctness of color) of display, and viewing environment.

Ex.
1.Conversion matrix (and other formulas): RGB value
2.Display white and black point: value range of display
3.Ambient illumination chromaticity: viewing environment

Only 1(matrix and formulas) has effects in converting values,
but 2 and 3 also important because they decide how we can see RGB values.
NB: with ICC profile, if 2(display settings) is stored, it counts on.

If display range is narrow than RGB value can represent, they will be clipped (while displaying).
If range is not proper, white or black maybe seen as gray, etc.

If ambient illumination chromaticity is different from the one conversion matrix and formulas are intended for, we will see different colors.


Conversion matrix
(This is important, as having effects on RGB converted values.)

from sRGB (Showing conversion matrix is for D65.)

  1. Conversion from XYZ (D65) to linear sRGB values

In Adobe RGB(1998) spec sheet, two types of conversion matrices (and formulas) exist.
4.3.1~ (without ICC): D65
4.3.6~ (with ICC): D50

from Adobe RGB(1998)
(for images with ICC profile etc.)

4.3.6 Encoding ICC PCS Version 2 values in 24-bit Adobe RGB (1998)
4.3.6.1 Converting XYZ to RGB tristimulus values
NOTE The above matrix is derived from the color space chromaticity coordinates, and a chromatic adaptation to CIE Standard Illuminant D50

The XYZ tristimulus values 0.0000, 0.0000, 0.0000 in the Profile Connection Space (XYZ PCS v2) shall correspond to the reference display black point. The XYZ tristimulus values 0.9642, 1.000, 0.8249 shall correspond to the reference display white point.

NB: caution white is not (1.0, 1.0, 1.0).

from Adobe RGB(1998)
(for images without ICC profile etc.)
This maybe good for calc (and white point for sRGB is pre-known(and it is D65)).

4.3.1 The Adobe RGB(1998) Color Space And Color Image Encoding

Color space chromaticities and luminance
Red x=0.6400, y=0.3300
Green x=0.2100, y=0.7100
Blue x=0.1500, y=0.0600
White x=0.3127, y=0.3290
The color space white point shall be equal to the reference display white point.
The color space black point shall be equal to the reference display black point.

NB:White (x=0.3127, y=0.3290) corresponds to D65.
(See section 4.2.1 Reference Display White Point.)


Ambient illumination chromaticity
(Do not confuse with display white point. This has effects on color correctness we can see.)

from Adobe RGB (draft)

3.1.4 Reference Viewing Conditions
4. Reference Ambient White Point x = 0.3457, y = 0.3585 (D50)

from Adobe RGB (1998)

Annex B.
Ambient Illumination Chromaticity: ... The ambient illumination chromaticity may be D65 to D50 ...


Display white point
(Do not confuse with ambient illumination chromaticity. This is about range which display can show up.)

from sRGB

  1. Reference display white point chromaticity: x = 0.3127, y = 0.3290, z = 0.3583 (equivalent to the chromaticity of CIE Illuminant D65).

from Adobe RGB (1998)

4.2.1 Reference Display White Point
NOTE The chromaticity coordinates correspond to CIE Standard Illuminant D65.


from Adobe RGB (1998) (for information.)

Annex A. The Adobe RGB(1998) ICC profile from Adobe Systems is an instance of the Adobe RGB(1998) color image encoding.

from sRGB

  1. Chromatic adaptation and converting to the ICC XYZ PCS

Example: If D65 is selected as the sRGB adapted white, the chro matic adaptation transform will go from D65 to D50, the resulting D50 values will be encoded in the mediaWhitePoint tag
...
However, if D50 were selected as the sRGB adapted white, chromatic adaptation would not be necessary
...
IEC 61966-2-1 does not specify the colorimetry of the sRGB reference display adapted white point.

(NB: sRGB is defined in IEC 61966-2-1)
This means it is not per-defined which white(D65 etc) is used for displaying sRGB, so store it in ICC profile.


Standard illuminant (wiki) (Just for info. Not part of this conversion.)
https://en.wikipedia.org/wiki/Standard_illuminant

Toris
  • 2,348
  • 13
  • 16
  • 1
    The [Adobe reference](http://www.adobe.com/digitalimag/pdfs/AdobeRGB1998.pdf) says "NOTE The chromaticity coordinates correspond to CIE Standard Illuminant D65". I don't know why everyone keeps insisting that Adobe RGB is D50, except that *all* ICC profiles are referenced to D50. – Mark Ransom Oct 23 '16 at 22:54
  • @MarkRansom D65 is for display, not for "ambient illumination". from Annex B in Adobe reference, "The ambient illumination chromaticity may be D65 to D50", and from "section 4.3.6.1 Converting XYZ to RGB tristimulus values" "NOTE The above matrix is derived from the color space chromaticity coordinates, and a chromatic adaptation to CIE Standard Illuminant D50" – Toris Oct 23 '16 at 23:15
  • from Annex A "The Adobe RGB(1998) ICC profile from Adobe Systems is an instance of the Adobe RGB(1998) color image encoding. " So, D50 is right, I think. – Toris Oct 23 '16 at 23:20
  • 4.3.1.1: "The color space white point shall be equal to the reference display white point." As I said above, all ICC profiles use a D50 white point, so if your color space does not then there's an extra step involved with creating the profile. But this question has nothing to do with ICC profiles. – Mark Ransom Oct 23 '16 at 23:45
  • @MarkRansom Now I get it. Adobe reference has two conversion matrices (for D65 and D50). 4.3.1 (D65) and 4.3.6 (D50) with different purposes. – Toris Oct 24 '16 at 01:22
  • I'm sorry @Toris, I don;t think you get it. NO, Adobe98 is NOT D50, NOT EVER. It is D65. Google the term "Ambient Illumination". Ambient has nothing to do with the colorspace, ambient is the light in the room and is part of the "viewing conditions". It is not even remotely relevant to this colorspace transform. – Myndex Apr 29 '19 at 01:58
  • Also as sRGB and Abobe98 both use D65, you don't really want to use D50 XYZ as a PCS. Better to go avoid ICC and transform sRGB to Adobe98 directly (or via XYZ D65). sRGB and Adobe98 have the same white point, same Red and Blue primaries, and *almost* the same TRC/Gamma — really the only thing substantially different is the green primary. As for the rest of the post, I understand you are trying to be helpful, but I'd like to suggest that you read Poynton's [Gamma FAQ](https://poynton.ca/GammaFAQ.html) and Color FAQ to get a better understand of the concepts involved. – Myndex Apr 29 '19 at 02:11