Jump to content

Chromes/Skia's Color/HSL/Tint Functions


PAEz
 Share

Recommended Posts

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
Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...