Sign in to follow this  
Followers 0
PAEz

Chromes/Skia's Color/HSL/Tint Functions

1 post in this topic

#1 ·  Posted (edited)

I converted some routines from Chromes source code for something Im doing and thought Id share them as their really quite useful.

Should be pretty obvious what they do...Convert HSL to RGB and RGB to HSL and tint an rgb value with a hsl.

The tint routine is great for tinting colors/images once you get use to the odd way of representing the hsl. In these functions the hsl values are in the range of 0 to 1. When it comes to the tint routine you can also use a value of -1 which means no change in this value. You can read more about how the tint works in my doc on google chrome themes.....

https://docs.google.com/Doc?docid=0Aa86I...XPZGtzZDU0NV85ZnFocnQzZGo&hl=e

...there's some pics there that will help you visualize how it works

Keep in mind please that I dont know jack of AutoIT, so if you see anything that should be different please say.

Also if your interested in doing chrome theme stuff with AutoIT have a look at this thread....

http://forum.valorsolo.com/viewtopic.php?f=21&t=189&p=490#p490

I started of making some routines for the themes manifest and now I might make an editor :mellow:

;-- Chrome/SKIA's color/hsl tint routines
;-- These routines where taken from Chromes source and are part of the SKIA
;-- graphics library (I think ;) )....
;-- http://www.google.com/codesearch/p?hl=en#OAMlx_jo-ck/src/gfx/color_utils.cc
;-- http://en.wikipedia.org/wiki/Skia_Graphics_Engine
;-- http://code.google.com/p/skia/
;-- Converted to AutoIT by PAEz
#include <Math.au3>
#include <Array.au3>
; Call with (red, green, blue) or an array of [red,green,blue]
Func _ColorToHSL($red, $green=0, $blue=0)
If @NumParams=1 Then
    $blue = $red[2]
    $green = $red[1]
    $red = $red[0]
EndIf
local $luminance
local $hue
local $saturation
$red = $red / 255
$green = $green / 255
$blue = $blue / 255
local $vmax = _Max(_Max($red, $green), $blue)
local $vmin = _Min(_Min($red, $green), $blue)
local $delta = $vmax - $vmin
local $luminance = ($vmax + $vmin) / 2
if $delta > 0 then
   local $dr = ((($vmax - $red) / 6.0) + ($delta / 2.0)) / $delta
   local $dg = ((($vmax - $green) / 6.0) + ($delta / 2.0)) / $delta
   local $db = ((($vmax - $blue) / 6.0) + ($delta / 2.0)) / $delta
   ;-- We need to compare for the max value because comparing $vmax to r,
   ;-- g or b can sometimes result in values overflowing registers.
   if $red >= $green and $red >= $blue then
    $hue = $db - $dg
   elseif $green >= $red and $green >= $blue then
    $hue = (1.0 / 3.0) + $dr - $db
   else
    $hue = (2.0 / 3.0) + $dg - $dr
     EndIf
 
   if $hue < 0.0 then
    $hue = $hue + 1
   elseif $hue > 1.0 then
    $hue = $hue - 1
     EndIf
 
   if $luminance < 0.5 then
    $saturation = $delta / ($vmax + $vmin)
   else
    $saturation = $delta / (2 - $vmax - $vmin)
    EndIf
 
else
   $hue = 0
   $saturation = 0
  EndIf
  Local $HSL[3] = [$hue,$saturation,$luminance]
return $HSL
EndFunc
 
Func calcHue($temp1, $temp2, $hue)
 
if $hue < 0.0 then
   $hue = $hue+1
elseif $hue > 1.0 then
   $hue =$hue-1
EndIf
 
if $hue * 6.0 < 1.0 then
    return  $temp1 + ($temp2 - $temp1) * $hue * 6.0
ElseIf ($hue * 2.0) < 1.0 then
    return  $temp2
ElseIf $hue * 3.0 < 2.0 then
    return $temp1 + ($temp2 - $temp1) * (2.0 / 3.0 - $hue) * 6.0
Else
    return $temp1
EndIf
EndFunc
 
; Call with (hue,saturation,luminance) or an array of [hue,saturation, luminance]
Func _HSLToColor($hue,$saturation=0,$luminance=0)
If @NumParams=1 Then
    $luminance = $hue[2]
    $saturation = $hue[1]
    $hue = $hue[0]
 
EndIf
local $temp1 = 0
local $temp2 = 0
local $light = 0
;-- If there's no color, we don't care about $hue and can do everything based
;-- on brightness.
if $saturation<=0 then
    if $luminance < 0 then
        $light = 0
    elseif $luminance >= 1.0 then
        $light = 255
    else
        $light = round($luminance * 255)
    EndIf
    Local $Color[3] = [$light, $light, $light]
    return $Color
EndIf
 
if $luminance < 0.5 then
    $temp2 = $luminance * (1.0 + $saturation)
else
    $temp2 = $luminance + $saturation - ($luminance * $saturation)
EndIf
$temp1 = 2.0 * $luminance - $temp2
Local $RGB[3] = [round(calcHue($temp1, $temp2, $hue + 1.0 / 3.0) * 255), round(calcHue($temp1, $temp2, $hue) * 255), round(calcHue($temp1, $temp2, $hue - 1.0 / 3.0) * 255)]
Return $RGB
EndFunc
 
; May be called with two arrays of [red,green,blue] and [hue,saturation,luminance]
Func _HSLShift($red, $green, $blue=0, $hue=0, $saturation=0, $luminance=0)
If @NumParams=2 Then
    $luminance = $green[2]
    $saturation = $green[1]
    $hue = $green[0]
    $blue = $red[2]
    $green = $red[1]
    $red = $red[0]
EndIf
local $sourceHSL[3]
$sourceHSL= _ColorToHSL($red, $green, $blue)
local $sourceHue=$sourceHSL[0], $sourceSaturation=$sourceHSL[1], $sourceLuminance =$sourceHSL[2]
 
;-- Replace the $hue with the tint's hue.
if $hue >= 0 then
   $sourceHue = $hue
   EndIf
 
;-- Change the saturation.
if $saturation >= 0 then
   if $saturation <= 0.5 then
    $sourceSaturation = $sourceSaturation * $saturation * 2.0
   else
    $sourceSaturation = $sourceSaturation +( (1.0 - $sourceSaturation) * (($saturation - 0.5) * 2.0))
     EndIf
EndIf
local $sourceRGB[3]
$sourceRGB= _HSLToColor($sourceHue, $sourceSaturation, $sourceLuminance)
$red=$sourceRGB[0]
$green=$sourceRGB[1]
$blue =$sourceRGB[2]
 
if $luminance < 0 then
     local $result[3]=[$red, $green, $blue]
    return $result
EndIf
 
;-- $luminance shifts in the style of popular image editors aren't
;-- actually represented in HSL - the L value does have some effect
;-- on saturation.
 
if $luminance <= 0.5 then
   $red = $red * ($luminance * 2.0)
   $green = $green * ($luminance * 2.0)
   $blue = $blue * ($luminance * 2.0)
else
   $red = $red + (255.0 - $red) * (($luminance - 0.5) * 2.0)
   $green = $green + (255.0 - $green) * (($luminance - 0.5) * 2.0)
   $blue = $blue + (255.0 - $blue) * (($luminance - 0.5) * 2.0)
EndIf
  local $result[3]=[round($red), round($green), round($blue)]
return $result
EndFunc

test code

Dim $col[3] = [255,0,0]
Dim $tint[3] =[ -1, -1, 0.75 ]
$HSL= _ColorToHSL($col)
$RGB = _HSLShift($col,$tint)
_ArrayDisplay($HSL,"HSL of 255,0,0")
_ArrayDisplay($RGB,"RGB of 255,0,0 tinted by -1,-1,0.75 which increases luminance by half ")
Edited by PAEz

Share this post


Link to post
Share on other sites



Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0