skip to Main Content

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.

2

Answers


  1. 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

    Login or Signup to reply.
  2. 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
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search