1 /** 2 This module defines RGB <-> HSV conversions. 3 */ 4 module gfm.image.hsv; 5 6 import std.algorithm, 7 std.math; 8 9 import gfm.math.vector; 10 11 // RGB <-> HSV conversions. 12 13 /// Converts a RGB triplet to HSV. 14 /// Authors: Sam Hocevar 15 /// See_also: $(WEB http://lolengine.net/blog/2013/01/13/fast-rgb-to-hsv) 16 vec3f rgb2hsv(vec3f rgb) pure nothrow 17 { 18 float K = 0.0f; 19 20 if (rgb.y < rgb.z) 21 { 22 swap(rgb.y, rgb.z); 23 K = -1.0f; 24 } 25 26 if (rgb.x < rgb.y) 27 { 28 swap(rgb.x, rgb.y); 29 K = -2.0f / 6.0f - K; 30 } 31 32 float chroma = rgb.x - (rgb.y < rgb.z ? rgb.y : rgb.z); 33 float h = abs(K + (rgb.y - rgb.z) / (6.0f * chroma + 1e-20f)); 34 float s = chroma / (rgb.x + 1e-20f); 35 float v = rgb.x; 36 37 return vec3f(h, s, v); 38 } 39 40 /// Convert a HSV triplet to RGB. 41 /// Authors: Sam Hocevar. 42 /// See_also: $(WEB http://lolengine.net/blog/2013/01/13/fast-rgb-to-hsv). 43 vec3f hsv2rgb(vec3f hsv) pure nothrow 44 { 45 float S = hsv.y; 46 float H = hsv.x; 47 float V = hsv.z; 48 49 vec3f rgb; 50 51 if ( S == 0.0 ) 52 { 53 rgb.x = V; 54 rgb.y = V; 55 rgb.z = V; 56 } 57 else 58 { 59 if (H >= 1.0) 60 { 61 H = 0.0; 62 } 63 else 64 { 65 H = H * 6; 66 } 67 int I = cast(int)H; 68 assert(I >= 0 && I < 6); 69 float F = H - I; /* fractional part */ 70 71 float M = V * (1 - S); 72 float N = V * (1 - S * F); 73 float K = V * (1 - S * (1 - F)); 74 75 if (I == 0) { rgb.x = V; rgb.y = K; rgb.z = M; } 76 if (I == 1) { rgb.x = N; rgb.y = V; rgb.z = M; } 77 if (I == 2) { rgb.x = M; rgb.y = V; rgb.z = K; } 78 if (I == 3) { rgb.x = M; rgb.y = N; rgb.z = V; } 79 if (I == 4) { rgb.x = K; rgb.y = M; rgb.z = V; } 80 if (I == 5) { rgb.x = V; rgb.y = M; rgb.z = N; } 81 } 82 return rgb; 83 }