Farver

Tags:    delphi

Da jeg er i gang med at lave et lille simpelt tegneprogram a la mspaint, vil jeg gerne give mulighed for at bruge hsl-farver (Hue, Saturaion, Luminosity) uden at bruge colordialogen. Jeg har tre skydebare men ved ikke hvordan jeg beregner farver ud fra disse tre værdier ligesom man kan lave en farve ved hjælp af rgb. jeg leder efter nogle funktioner i lighed med:

GetRValue
GetGValue
GatBValue
rgb(r,g,b)

bare for hsl. Håber i kan hjælpe mig.



4 svar postet i denne tråd vises herunder
1 indlæg har modtaget i alt 3 karma
Sorter efter stemmer Sorter efter dato
Du kan finde en masse information (og kode) om farver her:

http://www.efg2.com/Lab/Library/Delphi/Graphics/Color.htm


Kim Jensen aka BOSH
http://www.hulubulu.dk



Sjovt spørgsmål, og godt link.
Jeg kan særligt godt lide denne side som du finder via BOSH's link:

http://www.efg2.com/Lab/Graphics/Colors/HSV.htm

Jeg har ofte selv tænkt på hvordan det hang sammen, og jeg syntes det er rimeligt tydeligt her.

Hue
Hue er selve farve blandingen, altså er det ren rød, blanding mellem rød og grøn, ren grøn, blanding mellem grøn og blå, ren blå, blanding mellem blå og rød og til sidst ren rød igen.

Disse deles op i 360 fraktioner, og kan regnes om til at "forhold" mellem r, g og b værdierne, f.eks vil 0 (ren rød) have et forhold mellem r, g og b hvor rød er fuld, g er 0 og b er 0.

Saturation
Saturation er så et udtryk for hvor rent Hue forholdet skal udtrykkes ... når den er 0 er alle farver lige stærke (hvide), når den er fuld (255) er Hue farve udtrykket så stærkt som muligt (hvis Hue er 0 (rød) og Saturation er 255, er r 255, g 0 og b 0).

Value
Value spiller ind og justerer resultatet for r, g og b når du har lagt Saturation oven på Hue.
Value går fra 0 til 255, og er den 255 er der fuld kraft på .. dvs hvis r = 255, g = 0 og b = 0 og Value er 0 bliver de alle 0. Er Value 255 bliver de ved med at være 255, 0 og 0.

Den tror jeg er lige til at omsætte til en algoritme, hvis man ellers kan læse min elendige forklaring på hvad jeg tror, ud fra en enkelt billede, ha ha.

Held og lykke med det, men jeg vil anbefale at du laver farven om til rgb og bruger den funktioner du allerede har.

Evt lige dobbelt tjekke om min teori holder ved nærmere undersøgelse ... jeg kikkede jo bare på den dump der :D



Jeg kunne ikke slippe det helt ... :)

For at finde r, g og b's inbyrdes forhold ud fra en Hue værdi, tror jeg det er nemmest at lave en tabel.

Ikke helt Delphi, men det kan nok nemt laves om:

byte hueTable = new byte[361][3];

denne tabel fyldes ud for hver af de 3 dimensioner .. rød [0], gul [1] og blå [2].

Hver position vil så ud for hue index og farve index give styrken på den farve man kikker efter. Fra 0 til 120 i dette eksempel, simpelthen fordi vi bruger grunddefinitionen pås Hue's 360 grader til at dele ind med.

Lav følgende initiering for hver farve:

Rød [0]

index: 0 - 120 - 240 -360
styrke: 120 - 0 - 0 - 120

Gul [1]
index: 0 - 120 - 240 -360
styrke: 0 - 120 - 0 - 0

Blå [2]
index: 0 - 120 - - 240 - 360
styrke: 0 - 0 - 120 - 0

Dette er angivet med forløb, både i index og styrke.
Dvs . f.eks skal index 0 til 120, med subindex 0 (rød) have værdierne fra 120 til 0 (120,119,118,117 ...)

Så har du en Hue på 240, finder du r, g og b sådan her:

r = hueTable[240][0];
g = hueTable[240][1];
b = hueTable[240][2];

De 240 er naturligvis din aktuelle hue værdi, og ikke 240 hardcoded.

Så har de hver fra 0 til 120, og du kan smide Saturation på ved at gange med 255 (hvis det er din max Saturation værdi) og dividere med Saturation værdien ... hvis den så er max vil de være uændrede og hvis ikke vil de blive mindre i takt med Saturation.

Den sidste, Value, skal du få den højeste af din r,g og b til at blive lig med.
Det gør du ved at finde ud af hvor meget du skal gange den største af r,g eller b med for at det bliver det samme som Value.
Når det tal er fundet gange du hvert enelt med dette.

Så hvis Value er lille bliver r,g og b små .. er den står bliver de større, men ikek over 255 (eller hvad din max for Value skal være).

Håber det hjælper lidt med arbejdet hvis du ville implementere det selv, og ikke blot ledte efter et library :)



Tak skal i ha'. nu skulle der ikke være nogle problemer med at lave en algoritme, så man også kan vægle farve ud fra hsl/hsv



t