Mega Code Archive

 
Categories / Delphi / Examples
 

RGB and HSV conversions

Title: RGB and HSV conversions Question: 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 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 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 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 MinIndex:= 1; if B 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 H:= 1 + H; end; end; end.