2004. május 2., vasárnap
RGB and HSV conversions
Problem/Question/Abstract:
Sometimes it is best to deal with colors as HSV rather than RGB. The artical explains a little bit what HSV is and includes source for converting between the two.
Answer:
HSV is Hue, Saturation, and Value.
HSV:
Hard to explain without a picture so you will have to use your imagination...
Hue:
Draw a circle in your head, the circle is 0 to 360 degrees (or 359 :-) ). On the outer edge of the circle, place a red dot at 0 degrees, a green dot at 120 degrees and a blue dot at 240 degrees. Those are the main points. The other points between these 3 colors are interpolated... for example yellow is between red and green at 60 degrees (equal red + green = yellow), cyan is between green and blue at 180 degrees, magenta is between blue and red at 300 degrees. Then between yellow and red is another and you keep breaking it down until your circle is full. The outer edge from 0 to 360 degrees is the hue.
Saturation:
The center of the circle is white. The color blends with the other colors to white as you go from the outside of the circle to the center. The outer egde is saturation of 1 and the center is 0 (white).
Value:
Value is simply the intensity of the color.
You already know RGB I assume since you are a programmer.
I played around with my digital camera and took a picture of my brown computer chair. I created an algorithm that turned my chair green. It was easy with HSV, I simply used photoshop to see what the hue was of the chair. Then I rotated the hue so that the chair was in the green range. Boom, the chair was green.
Here they are:
http://www.eggcentric.com/eimages/greenchair.jpg
http://www.eggcentric.com/eimages/brownchair.jpg
Here is the source of procedures to convert between RGB and HSV and back again. You can also download it from the link.
unit RGBHSV;
{
William Egge, public@eggcentric.com
http://www.eggcentric.com
This unit converts between RGB and HSV color models.
procedure HSVToRGB(const H, S, V: Single; out R, G, B: Single);
in
H = Hue. Range is from 0..1. 0.5 = 180 degrees, 1 = 360. or H < 0 for gray
S = Satration. Range is 0..1 where 0 is white and 1 is no saturation.
V = Value. Range is 0..255
out
R = 0..255
G = 0..255
B = 0..255
If H < 0 then the result is a gray value R=V, G=V, B=V
procedure RGBToHSV(const R, G, B: Single; out H, S, V: Single);
in
R = 0..255
G = 0..255
B = 0..255
out
H = Hue. -1 for grey scale or range 0..1. 0..1 represents 0..360 degrees
S = Saturation. Range = 0..1. 0 = white, 1 = no saturation.
V = Value or intensity. Range 0..255
}
interface
uses
Math;
procedure HSVToRGB(const H, S, V: Single; out R, G, B: Single);
procedure RGBToHSV(const R, G, B: Single; out H, S, V: Single);
implementation
procedure HSVToRGB(const H, S, V: Single; out R, G, B: Single);
const
SectionSize = 60 / 360;
var
Section: Single;
SectionIndex: Integer;
f: single;
p, q, t: Single;
begin
if H < 0 then
begin
R := V;
G := R;
B := R;
end
else
begin
Section := H / SectionSize;
SectionIndex := Floor(Section);
f := Section - SectionIndex;
p := V * (1 - S);
q := V * (1 - S * f);
t := V * (1 - S * (1 - f));
case SectionIndex of
0:
begin
R := V;
G := t;
B := p;
end;
1:
begin
R := q;
G := V;
B := p;
end;
2:
begin
R := p;
G := V;
B := t;
end;
3:
begin
R := p;
G := q;
B := V;
end;
4:
begin
R := t;
G := p;
B := V;
end;
else
R := V;
G := p;
B := q;
end;
end;
end;
procedure RGBToHSV(const R, G, B: Single; out H, S, V: Single);
var
RGB: array[0..2] of Single;
MinIndex, MaxIndex: Integer;
Range: Single;
begin
RGB[0] := R;
RGB[1] := G;
RGB[2] := B;
MinIndex := 0;
if G < R then
MinIndex := 1;
if B < RGB[MinIndex] then
MinIndex := 2;
MaxIndex := 0;
if G > R then
MaxIndex := 1;
if B > RGB[MaxIndex] then
MaxIndex := 2;
Range := RGB[MaxIndex] - RGB[MinIndex];
// Check for a gray level
if Range = 0 then
begin
H := -1; // Can't determine on greys, so set to -1
S := 0; // Gray is at the center;
V := R; // could choose R, G, or B because they are all the same value.
end
else
begin
case MaxIndex of
0: H := (G - B) / Range;
1: H := 2 + (B - R) / Range;
2: H := 4 + (R - G) / Range;
end;
S := Range / RGB[MaxIndex];
V := RGB[MaxIndex];
H := H * (1 / 6);
if H < 0 then
H := 1 + H;
end;
end;
end.
Component Download: http://www.eggcentric.com/download/rgbhsv.zip
Feliratkozás:
Megjegyzések küldése (Atom)
Nincsenek megjegyzések:
Megjegyzés küldése