none
Tint and Shade elements RRS feed

  • Question

  • Does anyone know how to calculate the <a:tint> and <a:shade> elements in DrawingML? The Ecma documentation does not offer any help as to an algorithm. What is says is "X% of the input color and X% of white/black.", but it doesn't offer a way to calculate this. FYI - what are commonly refered to as tint/shade are controlled by luminance such as <a:lumMod> and <a:lumOff>, but these do not produce the same values as <a:tint> and <a:shade>. For reference, the <a:lumMod> and similar elements can be produced by using standard HSL "L" modifications, so this isn't what I'm after.

    For example:

    <a:srgbClr val="FF99FF">
    
    <a:shade val="25000"/>
    
    </a:srgbClr>
    
    

    which should be 25% of #FF99FF (RGB 255, 153, 255) and 75% of #000000 (RGB 0,0,0) (black) according to the Ecma specs. The values produced by RGB->HSL and a modification of the luminance (Brightness * Shade), however, produces #660066 (RGB 102, 0, 102). Similarly, trying to modify the RGB values directly by the shade percentage of 25% does not produce the correct results.

    What PowerPoint 2007 produces is #895089 (RGB 137, 80, 137), which doesn't seem to make any sense as far as I can work out. There seem to be a number of people confused about how <a:shade> and <a:tint> are calculated. I've done quite a bit of researching and searching on this and have come up empty-handed - all standard methods do not work to produce the same result DrawingML does.

    What PPT produces is the same as the "TintandShade" property in the object model. For example, this code also produces RGB 137, 80, 137.

    Sub setTintandShade()
        Dim p As Presentation
        Set p = ActivePresentation
        Dim S As Shape
        Set S = p.Slides(2).Shapes(2) '2nd shape on slide 2
        With S.Fill.ForeColor
            .rgb = rgb(255, 153, 255) 'same as #FF99FF
            .TintAndShade = -0.75 'same as <a:shade val="25000">
        End With
    End Sub

    Could anyone who knows how these are calculated this let me (and everyone) know?

    The reason I'm doing this is for a DrawingML to XAML conversion project and need to get the correct color value into XAML.


    TMP
    Monday, September 14, 2009 5:50 AM

Answers

  • In Office 2007 and later, the Tint and Shade algorithm is as follows:

    ·         Convert each sRGB color component from an integer to a linear value (value / 255)

    ·         Convert each linear sRGB to a linear scRGB using this VB function:

     

    Public Function sRGB_to_scRGB(value As Double)

       If value < 0# Then

          sRGB_to_scRGB = 0#

          Exit Function

       End If

       If value <= 0.04045 Then

          sRGB_to_scRGB = value / 12.92

          Exit Function

       End If

       If value <= 1# Then

          sRGB_to_scRGB = ((value + 0.055) / 1.055) ^ 2.4

          Exit Function

       End If

       sRGB_to_scRGB = 1#

    End Function

     

    ·         Shade each component using these formulas where Shade is a value from 0-1 (these are Excel formulas -- translate to the language of your choice):

     

    =IF(Red*Shade<0,0,IF(Red*Shade>1,1,Red*Shade))

    =IF(Green*Shade<0,0,IF(Green*Shade>1,1,Green*Shade))

    =IF(Blue*Shade<0,0,IF(Blue*Shade>1,1,Blue*Shade))

     

    ·         *Or* Tint each component using these formulas where Tint is a value from 0-1:

     

    =IF(Tint>0,Red*(1-Tint)+Tint,Red*(1+Tint))

    =IF(Tint>0,Green*(1-Tint)+Tint,Green*(1+Tint))

    =IF(Tint>0,Blue*(1-Tint)+Tint,Blue*(1+Tint))

     

    ·         Converted these values back to linear sRGB values using this VB function:

     

    Public Function scRGB_to_sRGB(value As Double)

       If value < 0# Then

          scRGB_to_sRGB = 0#

          Exit Function

       End If

       If value <= 0.0031308 Then

          scRGB_to_sRGB = value * 12.92

          Exit Function

       End If

       If value < 1# Then

          scRGB_to_sRGB = 1.055 * (value ^ (1# / 2.4)) - 0.055

          Exit Function

       End If

       scRGB_to_sRGB = 1#

    End Function

     

    ·         Convert each linear sRGB value back to integer ( ROUND( value * 255, 0 ) )

    Here's some information about the sRGB and scRGB color spaces:

    http://en.wikipedia.org/wiki/SRGB

    http://en.wikipedia.org/wiki/ScRGB

     

    • Proposed as answer by Tom Underhill Thursday, September 24, 2009 11:55 PM
    • Marked as answer by Todd Main Friday, September 25, 2009 1:39 AM
    Thursday, September 24, 2009 11:51 PM

All replies

  • Anybody?
    TMP
    Thursday, September 17, 2009 6:32 PM
  • Could someone from MSFT take over this ticket? I really need to get an answer to this.


    TMP
    Tuesday, September 22, 2009 1:05 AM
  • In Office 2007 and later, the Tint and Shade algorithm is as follows:

    ·         Convert each sRGB color component from an integer to a linear value (value / 255)

    ·         Convert each linear sRGB to a linear scRGB using this VB function:

     

    Public Function sRGB_to_scRGB(value As Double)

       If value < 0# Then

          sRGB_to_scRGB = 0#

          Exit Function

       End If

       If value <= 0.04045 Then

          sRGB_to_scRGB = value / 12.92

          Exit Function

       End If

       If value <= 1# Then

          sRGB_to_scRGB = ((value + 0.055) / 1.055) ^ 2.4

          Exit Function

       End If

       sRGB_to_scRGB = 1#

    End Function

     

    ·         Shade each component using these formulas where Shade is a value from 0-1 (these are Excel formulas -- translate to the language of your choice):

     

    =IF(Red*Shade<0,0,IF(Red*Shade>1,1,Red*Shade))

    =IF(Green*Shade<0,0,IF(Green*Shade>1,1,Green*Shade))

    =IF(Blue*Shade<0,0,IF(Blue*Shade>1,1,Blue*Shade))

     

    ·         *Or* Tint each component using these formulas where Tint is a value from 0-1:

     

    =IF(Tint>0,Red*(1-Tint)+Tint,Red*(1+Tint))

    =IF(Tint>0,Green*(1-Tint)+Tint,Green*(1+Tint))

    =IF(Tint>0,Blue*(1-Tint)+Tint,Blue*(1+Tint))

     

    ·         Converted these values back to linear sRGB values using this VB function:

     

    Public Function scRGB_to_sRGB(value As Double)

       If value < 0# Then

          scRGB_to_sRGB = 0#

          Exit Function

       End If

       If value <= 0.0031308 Then

          scRGB_to_sRGB = value * 12.92

          Exit Function

       End If

       If value < 1# Then

          scRGB_to_sRGB = 1.055 * (value ^ (1# / 2.4)) - 0.055

          Exit Function

       End If

       scRGB_to_sRGB = 1#

    End Function

     

    ·         Convert each linear sRGB value back to integer ( ROUND( value * 255, 0 ) )

    Here's some information about the sRGB and scRGB color spaces:

    http://en.wikipedia.org/wiki/SRGB

    http://en.wikipedia.org/wiki/ScRGB

     

    • Proposed as answer by Tom Underhill Thursday, September 24, 2009 11:55 PM
    • Marked as answer by Todd Main Friday, September 25, 2009 1:39 AM
    Thursday, September 24, 2009 11:51 PM
  • Tom, you are amazing! Wow, I would have never figured this out on my own and your documentation was great, clear and easy to follow. It works like a charm.

    If you don't mind, I'll share a link back to this thread on other forums I and others have asked about this issue.

    Again, thank you so much!! Fantastic!

    Cheers,
    Todd
    TMP
    Friday, September 25, 2009 1:45 AM
  • Hi Todd,

    I'm glad it worked for you.  I have to make a correction: the code and algorithm is correct, but I mislabled the functions.  Those VBA function aren't converted sRGB_to_scRGB and scRGB_to_sRGB, they're actually converting sRGB_to_linearRGB and linearRGB_to_sRGB.   You can see from the code that they match the formulas here http://en.wikipedia.org/wiki/SRGB#Specification_of_the_transformation.  The scRGB namespace doesn't apply here at all.

    Thanks,
    Tom
    Wednesday, October 7, 2009 4:02 PM
  • Hi Tom,

    I am trying to import an Excel 2007 document and experiencing issues in color import. I tried number of combinations including the one above but it didn't. Here are my questions:

     

    1) Does this algo hold good for Excel 2007 also?

    2) In Excel we simply get tint value and its sign indicates shade or tint. In above algos you said the range of shade and tint is 0-1 while the excel formulas consider negative values also. I am confused by that.

    3) In case of borderline values like Black and White does this work well

    4) Would the same procedure apply to sysClr values also?

     

    Thanks

     

    Tuesday, April 13, 2010 9:22 AM
  • Hi Tom ,

     

    I have referred your earlier post and created the sample to convert sRGB to Linear scRGB and , but it not worked at my side. Could you  please let me know any thing wrong in this.

     

    [Code]

     

      Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

     

     

            Dim Red As Double

            Dim Green As Double

            Dim Blue As Double

            Dim Tint As Double = 0.6

            Dim color As Color = color.FromArgb(255, 31, 73, 125)

     

            Red = color.R / 255

            Green = color.G / 255

            Blue = color.B / 255

     

            Red = sRGB_to_scRGB(Red)

            Green = sRGB_to_scRGB(Green)

            Blue = sRGB_to_scRGB(Blue)

     

            Red = If(Tint > 0, Red * (1 - Tint) + Tint, Red * (1 + Tint))

            Green = If(Tint > 0, Green * (1 - Tint) + Tint, Green * (1 + Tint))

            Blue = If(Tint > 0, Blue * (1 - Tint) + Tint, Blue * (1 + Tint))

     

            Red = scRGB_to_sRGB(Red)

            Green = scRGB_to_sRGB(Green)

            Blue = scRGB_to_sRGB(Blue)

     

            Red = Math.Round(Red * 255)

            Green = Math.Round(Green * 255)

            Blue = Math.Round(Blue * 255)

     

        End Sub

        Public Function scRGB_to_sRGB(ByVal value As Double)

            If value < 0.0# Then

                scRGB_to_sRGB = 0.0#

                Exit Function

            End If

            If value <= 0.0031308 Then

                scRGB_to_sRGB = value * 12.92

                Exit Function

            End If

            If value < 1.0# Then

                scRGB_to_sRGB = 1.055 * (value ^ (1.0# / 2.4)) - 0.055

                Exit Function

            End If

            scRGB_to_sRGB = 1.0#

        End Function

        Public Function sRGB_to_scRGB(ByVal value As Double)

            If value < 0.0# Then

                sRGB_to_scRGB = 0.0#

                Exit Function

            End If

            If value <= 0.04045 Then

                sRGB_to_scRGB = value / 12.92

                Exit Function

            End If

            If value <= 1.0# Then

                sRGB_to_scRGB = ((value + 0.055) / 1.055) ^ 2.4

                Exit Function

            End If

            sRGB_to_scRGB = 1.0#

        End Function

     

    [/Code]

     

    Thanks in advance.

     

    Thanks,
    Sathish 


    Monday, April 25, 2011 4:16 PM