[C#] RGB to HSL colourspace

Pagina: 1
Acties:
  • 130 views sinds 30-01-2008
  • Reageer

  • microchip
  • Registratie: Maart 2004
  • Laatst online: 29-05-2021
Ik ben bezig geweest met wat code om RGB waarden om te zetten in HSL (hue, saturation, lumination). Ik denk dat dit redelijk gelukt is voor de saturation en lumination, alleen werkt het voor de hue totaal niet.
Om het een beetje te verduidelijken:
Afbeeldingslocatie: http://home.wanadoo.nl/markvdw/probleem.PNG
Het plaatje linksboven is het origineel. De rode is de hue, blauw de saturation en groen de illumination. Zoals je ziet, klopt er van de hue niets. Wat er niet klopt is dat er zijn maar een stuk of 4 waardes te zien in het plaatje, terwijl het een 8 bit getal hoort te zijn. En de kleurovergangen zijn zeker niet zo drastisch als op het plaatje op een egaal oppervlak (zie de muur rondom de poster). Ook is de muur eerder groen dan rood, waar dus zeker geen hue van rond de 255 hoort te zijn...

De code:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
    PixelData RGBtoHLS(PixelData colour)
    {
        float hue = 0;
        float sat = 0;
        float R = (float)colour.red / (float)255;
        float G = (float)colour.green / (float)255;
        float B = (float)colour.blue / (float)255;
        float min = Math.Min(R, Math.Min(G, B));
        float max = Math.Max(R, Math.Max(G, B));
        float delta = max - min;
        float lum = (max + min) / 2;
        //Trace.WriteLine(lum);
        if (delta == 0)
        {
            hue = 0;
            sat = 0;
        }
        else
        {
            if (lum < 0.5)
            {
                sat = delta / (max + min);
            }
            else
            {
                sat = delta / (2 - max - min);
            }
            float deltaR = (((max - R) / 6) + (delta / 2)) / delta;
            float deltaG = (((max - G) / 6) + (delta / 2)) / delta;
            float deltaB = (((max - B) / 6) + (delta / 2)) / delta;
            if (R == max)
            {
                hue = deltaB - deltaG;
            }
            else if (G == max)
            {
                hue = (1 / 3) + deltaR - deltaB;
            }
            else if (B == max)
            {
                hue = (2 / 3) + deltaG - deltaR;
            }

            if (hue < 0)
            {
                hue += 1;
            }
            else if (hue > 1)
            {
                hue -= 1;
            }
        }

        PixelData hls;
        // De rode channel krijgt de hue informatie mee, groene de lumination en blauw de saturation.
        hls.red = (byte)Math.Round(hue * 255);
        hls.green = (byte)Math.Round(lum * 255);
        hls.blue = (byte)Math.Round(sat * 255);
        return hls;
    }


Ik heb deze code geschreven met behulp van deze site http://www.easyrgb.com/math.php?MATH=M18#text18. Als ik de code geport heb naar een functie in ActionScript, werkt het wel prima...

[ Voor 5% gewijzigd door microchip op 02-03-2006 23:56 ]


  • MTWZZ
  • Registratie: Mei 2000
  • Laatst online: 13-08-2021

MTWZZ

One life, live it!

Wilde gok hoor maar probeer het eens met doubles ipv floats en step dan met de debugger eens door je code heen om te kijken of er in de tussenstappen wel de goeie waarden uit komen.

Nu met Land Rover Series 3 en Defender 90


  • bigbeng
  • Registratie: Augustus 2000
  • Laatst online: 26-11-2021
maak van die literals op 37 en 41 eens 1.0, 2.0 en 3.0. Want volgens mij worden de expressies tussen de haakjes als ints of longs afgehandeld, wat dus neerkomt op 0 voor beide berekeningen. Ik heb dit overigens niet getest, maar dit is wel iets waar ik in andere talen (C o.a.) tegenaan gelopen bent.

  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

ik weet niet waar jij mee bezig bent maar ik doe dit zo:
C#:
1
2
3
4
Color c = Color.FromARGB(r,g,b);
float hue = c.GetHue();
float sat = c.GetSaturation();
float lum = c.GetBrightness();


waarom alles zelf willen schrijven als zoveel dingen reeds gedefinieerd zijn ?

ASSUME makes an ASS out of U and ME


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 08-04 12:26
Als je constante floats wilt declareren kan dat met een f ( bv 1.0f ), zonder toevoeging zal het een double worden.

Er is dus niet echt een reden om deze constanten te casten naar een float.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 16:58

.oisyn

Moderator Devschuur®

Demotivational Speaker

(jarig!)
HIGHGuY: HSB (ook wel HSV) is niet hetzelfde als HSL ;)
http://en.wikipedia.org/wiki/HLS_color_space

[ Voor 28% gewijzigd door .oisyn op 03-03-2006 11:15 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • microchip
  • Registratie: Maart 2004
  • Laatst online: 29-05-2021
bigbeng schreef op vrijdag 03 maart 2006 @ 09:05:
maak van die literals op 37 en 41 eens 1.0, 2.0 en 3.0. Want volgens mij worden de expressies tussen de haakjes als ints of longs afgehandeld, wat dus neerkomt op 0 voor beide berekeningen. Ik heb dit overigens niet getest, maar dit is wel iets waar ik in andere talen (C o.a.) tegenaan gelopen bent.
Je hebt 100% gelijk. Stom van me dat ik dat niet zag, in C doe ik het wel atijd goed... Werkt een stuk beter nu.

@HIGHGuy: Dit was eigenlijk meer een oefening om de theorie achter het converteren te snappen. Ik hou er niet van dingen te gebruiken zonder te weten wat erachter zit. Uiteindelijk gebruik ik de snelste wel :)

  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

njah.. ik werk meer in CIE1931 color space atm...

brightness ~ luminance ?? ff kijken op je linkje ;)

ASSUME makes an ASS out of U and ME

Pagina: 1