Post Reply 

manually calculating HSL

Sep 12, 2014, 05:39 (This post was last modified: Sep 14, 2014 06:01 by Sagemode.)
Post: #1
manually calculating HSL
Hey,

I wonder.....

The only way I've found thus far in GIMP to get any HSL reading is pretty laborious. I have to decompose my image into HSL and then check the % values for each layer.

However, this does give me an idea....

I want an easy or automated (or self-scripted) way to turn a picture into HSL, and then set the Alpha (as a [0,1] value) to its Lightness (as a [0,100] value).

Now GIMP has very limited mixing operations from layers to alpha channels and so on.

I can decompose my image into HSL. Then I can add a layer mask on the lightness, fill it with a grayscale of the lightness, apply it to the image and then I have a alpha channel that I would want to use to turn these three components + alpha into one HSLA image.

But, the original image also had an alpha channel which would complicate things. But I just overwrite that. I would make sure any transparent pixels are set to black. Not good enough for more complicated images, but then I run into my problem with the color2alpha being a destructive operation. It would not be in the HSLA model.

HSL is called the bi-cone whereas HSV is the mono-cone.
[Image: 320px-HSL_color_solid_dblcone_chroma_gray.png]
[Image: 320px-HSV_color_solid_cone_chroma_gray.png]

If I knew how to convert e.g. GIMP's RGBA into HSLA and then adjust my image and then save that (or make it RGBA first again) that would be awesome.

Does anyone have any pointers on how to start doing that?
Find all posts by this user
Quote this message in a reply
Sep 12, 2014, 05:58
Post: #2
RE: manually calculating HSL
If you are going to use script-fu then I have seen this code in use...
Code:
;
; Define RGB to HSV functions
;
(define (fu-do-rgb-to-hsv color)
    (let* (
            (r (car color))
            (g (cadr color))
            (b (caddr color))
            (cmin (min r (min g b)))
            (cmax (max r (max g b)))
            (diff 0.0)
            (rc 0.0)
            (gc 0.0)
            (bc 0.0)
            (h 0.0)
          )
            
        (set! diff (- cmax cmin))
        (if (= diff 0.0)
            (set! diff (+ diff 1.0)))
        (set! rc (/ (- cmax r) diff))
        (set! gc (/ (- cmax g) diff))
        (set! bc (/ (- cmax b) diff))
        (set! h  (/ (if (= r cmax)
                            (- bc gc)
                            (if (= g cmax)
                                (+ 2.0 (- rc bc))
                                (+ 4.0 (- gc rc))))
                        6.0))
        
        (list (if (= cmin cmax)
                0
                (* 360 (if (< h 0.0)
                        (+ h 1.0)
                        h
                    )
                )
            )
            (if (= cmin cmax)
                0
                (/ (- cmax cmin) cmax)
            )
            cmax
        )
    )
)

;
; RGB to HSV in gimp ranges
;
(define (fu-conv-rgb-to-hsv color)
    (let*
        (
            (r (car color))
            (g (cadr color))
            (b (caddr color))
            (hsv (fu-do-rgb-to-hsv (list (/ r 255.0) (/ g 255.0) (/ b 255.0))))
            (h (car hsv))
            (s (cadr hsv))
            (v (caddr hsv))
        )
        (list h (* s 100.0) (* v 100.0))
    )
)
;
; then insert these lines into your function
;
    (set! hsv (fu-conv-rgb-to-hsv my-color))
    (set! h (car hsv))
    (set! s (cadr hsv))
    (set! v (caddr hsv))
    (set! v (- v 100))
Find all posts by this user
Quote this message in a reply
Sep 12, 2014, 08:55 (This post was last modified: Sep 12, 2014 09:00 by rich2005.)
Post: #3
RE: manually calculating HSL
Quote:...big snip...
..If I knew how to convert e.g. GIMP's RGBA into HSLA and then adjust my image and then save that (or make it RGBA first again) that would be awesome.
Does anyone have any pointers on how to start doing that?

Maybe some other tool than Gimp
You could try this tool
http://code.google.com/p/delaboratory/ there are compiled version for Windows

Open the image as sRGB (jpg or tiff)
Change the colour space to HSL
Bring up the curves and adjust
Export or change back to sRGB and export.

looks like this. http://i.imgur.com/jidOogH.jpg

** https://www.gimp-forum.net/ now answering questions**
Find all posts by this user
Quote this message in a reply
Sep 12, 2014, 12:11
Post: #4
RE: manually calculating HSL
Thank you miss fluffysomething,

But unfortunately that code calculates hue using the hexagonal coordinates warping it into a circle (with angle hue and distance chroma) and I will need to have the rectangular to polar coordinates. Nevertheless, it would seem easy enough to adjust that. My many thanks for introducing me to this language :). It seems like a cute functional programming language.

Also, the function calculates "V" or "value" as the maximum R,G,B component. This is the HSV model that GIMP uses. But I need "L" or "lightness" as the average of the minimum and the maximum value. Also easy.

The saturation value is then not hard to calculate. No, the difficulty lies in that the polar coordinates I need use trigonometry and the Wikipedia article that describes it (never have seen such a useful Wikipedia page in my life!) only lists the reverse operations for the hexagonal system most commonly used.

But, not something beyond the realm of the possible :p. I'll just need to think about it for a while.

(The hexagon method treats the color space as 6 chunks of 60 degrees and determines the angle within each chunk in a somewhat discontinuous way, whereas the Cartesian method treats the hexagon as just a shape in rectangular space, and then determines the angle using regular mathematics for circles. The latter angle is the real angle around the hexagon, the former is just a type of linear distance along each of the 6 sides.)

But you've been wonderful once more :).

<3.
Find all posts by this user
Quote this message in a reply
Sep 12, 2014, 12:57
Post: #5
RE: manually calculating HSL
(Sep 12, 2014 08:55)rich2005 Wrote:  Maybe some other tool than Gimp
You could try this tool
http://code.google.com/p/delaboratory/ there are compiled version for Windows

Perhaps I will check it out, it's just that the screenshots you post are extremely disconcerting to me, I find it hard to look at them as if there is a lot of chaos and distortion present in you when you make these screenshots and those edits to them, or maybe even the programs themselves, hard to tell....

Well, in any case...

I think I started at 9:00. It has taken me about 4 hours to implement my written-from-scratch converter functions that can convert any single pixel value from RGBA to HSLA and back without any loss of accuracy --- although I haven't checked for complete equality yet.

The funny thing is -- my values are [0,360) for hue, [0,100] for saturation and [0,100] for lightness -- as soon as I start ROUNDING these values after the transform to HSL (and prior to transforming back to RGB) I get the same kind of artifacts (it actually looks like clipping) that I got in my other thread where I mentioned the weird stuff that happens when you change transparency values.

APPARENTLY these artefacts are getting introduced (or perhaps some of them?) because of rounding -loss-of-information due to being converted back to RGB? But HSV itself is a flawed model that no one should use. These models arise from the RGB cube being put on its 'black' apex which causes the projected surface (on the floor surface on which the black apex rests) to become a hexagon. The projection (distance from the vertical axis) then results in a "chroma" value being created.

HSV and HSL only differ in what happens next. In HSL, the cube stays a cube. The hexagon (chromatic distances) usually gets warped into a circle as seen from the top down. Then the question is what becomes of the vertical distance along that axis. In HSL it remains a value congruent with the cube itself. White remains at the top of a cube. I do not know why, HSL seems strange because it only ever uses two of the components to calculate the L value. But for some reason it is totally and completely and perfectly harmonious in all respects. The alternative is to use the average of all three values. But the base of these chromatic shapes is always - somewhere - a hexagon.

HSV creates a single hexagonal pyramid which is a very bad shape. HSL creates a dual hexagonal pyramid, which is a good shape. I'm not sure what HSI does. It creates a weird shape, for sure.

[Image: Ostwald.svg]

This is the only harmonious shape. No one should use HSV. GIMP should not use HSV. In HSV, white is treated as a primary or secondary colour, while black is the only exception to everything. It is weird, unhealthy.
Find all posts by this user
Quote this message in a reply
Sep 12, 2014, 15:01
Post: #6
RE: manually calculating HSL
Oh, by the way, here are my mathematics for getting HSL turned back into RGB:

1. The HSL model expands chroma distances for every level of lightness to always cover the entire reach of [0,1] or [0,100]. The hexagonal bi-cone is expanded to a hexagonal cylinder.

PHP Code:
$max_chroma_for_level =  abs($lightness 1);
$real_chroma $saturation $max_chroma_for_level

Then the following relations exist:

* tangent of the angle of the hue equals the proportion of the height vs width of a unit triangle drawn from the center of the circle, to the actual edge of the hexagon, in a unit circle. Because it is hexagon and not a circle, the actual maximum height (y-axis) of the triangle is less than 1, being ½√3. The maximum width (x-axis) is 1. We call these values α and β. With α being the distance on the x-axis, and β the distance on the y-axis.
* the actual chroma squared (diagonal, radius) is equal to the α squared + β squared (pythagoras).
* the tangent can fall into one of four quadrants defined by 0, ½π, π, 1½π, 2π (or 0°, 90°, 180°, 270°). A positive tangent can mean either quadrant 1 or 3, a negative tangent would mean quadrant 2 or 4.
* this is enough information to obtain the actual α and β using angle and chroma (the polar coordinates usually denoted as (φ, r). This is something every scientific calculator can do. Note that our chroma here is the actual distance to (the edge) of the hexagon, not to (the edge) of the circle on its outer edge.

PHP Code:
$chroma_squared $chroma $chroma;
$tan tan($hue); $tan_squared $tan $tan;
$beta_squared $chroma_squared $tan_squared / ($tan_squared 1);
$alpha sqrt($chroma_squared $beta_squared);
$beta sqrt($beta_squared);

$alpha = ($hue 0.5 M_PI || $hue 1.5 M_PI) ? $alpha : -$alpha;
$beta = ($hue M_PI) ? $beta : -$beta

You could also use sine and cosine functions, but that is additional computation. But that would be as simple as:

α = r · cos φ
β = r · sin φ

Actually, it appears to be faster too :P :P :P. Haha, it took me a while to figure out what I was doing anyway ;-).

After that I had to do a lot of math to turn

L = ½(min(R,G,B) + max(R,G,B))
α = ½(2R - G - B)
β = ½√3(G - B)

(from Wikipedia), into:

let Q = 2α
let P = β / ½√3
Q = 2R - G - B
P = G - B
Q - P = 2R - (G + B) - (G - B) = 2R - 2G --> ½(Q - P) = R - G
Q + P = 2R - (G + B) + (G - B) = 2R - 2B --> ½(Q + P) = R - B

d(G,B) = P
d(R,B) = ½(Q + P)
d(R,G) = ½(Q - P)

range = d(max, min) = max(abs(d(G,B)), abs(d(R,B)), abs(d(R,G)))
min = L - range / 2
max = L + range / 2

then find which of R,B,G is the largest value (max) based on their differences and use that to calculate the other two.
Find all posts by this user
Quote this message in a reply
Sep 12, 2014, 15:51
Post: #7
RE: manually calculating HSL
Quote:Perhaps I will check it out, it's just that the screenshots you post are extremely disconcerting to me, I find it hard to look at them as if there is a lot of chaos and distortion present in you when you make these screenshots and those edits to them, or maybe even the programs themselves, hard to tell....

PEBKAC

** https://www.gimp-forum.net/ now answering questions**
Find all posts by this user
Quote this message in a reply
Sep 13, 2014, 01:09
Post: #8
RE: manually calculating HSL
Well, that one is new for me.

If I were to have to use your system, I would throw it (or myself) out of the window within a split millisecond.
Find all posts by this user
Quote this message in a reply
Sep 14, 2014, 06:03
Post: #9
RE: manually calculating HSL
Yes, I know. H is the same for HSV/HSL, so I use the Pointer dialog to find my Hue if I need it. Also, in a colour select tool (the way GIMP shows H S V R G B) you can also easily find the hue.
Find all posts by this user
Quote this message in a reply
Post Reply 


Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  Drawing along path - Manually Slabity 5 562 Jul 21, 2013 19:32
Last Post: ofnuts

Forum Jump:


GIMP ForumPortalArchiveContactTermsRSS