前回のを書き足した。合ってる気がしない。
cf. RGBとHSVの色空間を相互変換する。Rubyで http://c4se.hatenablog.com/entry/2013/08/04/190937
# coding=utf-8 class Color # RGB to HSV conversion | color conversion http://www.rapidtables.com/convert/color/rgb-to-hsv.htm # @param r [Integer] red 0..255 # @param g [Integer] green 0..255 # @param b [Integer] blue 0..255 # @return [Integer[]] [hue, saturation, value] # hue 0..360 degree # saturation 0..100 % # value 0..100 % def self.rgb_to_hsv r, g, b r /= 255.0 g /= 255.0 b /= 255.0 cmax = [r, g, b].max cmin = [r, b, g].min d = cmax - cmin return [0, 0, (cmax * 100).floor] if d == 0 h = case cmax when r then 60 * ((g - b) / d % 6) when g then 60 * ((b - r) / d + 2) else 60 * ((r - g) / d + 4) end [ h, d / cmax * 100, cmax * 100 ].map &:floor end # HSV to RGB conversion | color conversion http://www.rapidtables.com/convert/color/hsv-to-rgb.htm # @param h [Integer] hue 0..360 degree # @param s [Integer] saturation 0..100 % # @param v [Integer] value 0..100 % # @return [Integer[]] [red, green, blue] # red 0..255 # green 0..255 # blue 0..255 def self.hsv_to_rgb h, s, v s /= 100.0 v /= 100.0 c = v * s x = c * (1 - ((h / 60.0) % 2 - 1).abs) m = v - c r, g, b = case when h < 60 then [c, x, 0] when h < 120 then [x, c, 0] when h < 180 then [0, c, x] when h < 240 then [0, x, c] when h < 300 then [x, 0, c] else [c, 0, x] end [r, g, b].map{|channel| ((channel + m) * 255).ceil } end # RGB to HSL converter | color conversion http://www.rapidtables.com/convert/color/rgb-to-hsl.htm # @param r [Integer] red 0..255 # @param g [Integer] green 0..255 # @param b [Integer] blue 0..255 # @return [Integer[]] [hue, lightness, saturation] # hue 0..360 degree # lightness 0..100 % # saturation 0..100 % def self.rgb_to_hls r, g, b r /= 255.0 g /= 255.0 b /= 255.0 cmax = [r, g, b].max cmin = [r, b, g].min d = cmax - cmin l = (cmax + cmin) / 2 return [0, (l * 100).floor, 0] if d == 0 h = case cmax when r then 60 * ((g - b) / d % 6) when g then 60 * ((b - r) / d + 2) else 60 * ((r - g) / d + 4) end [ h, l * 100, d / (1 - (l * 2 - 1).abs) * 100 ].map &:floor end # HSL to RGB conversion | color conversion http://www.rapidtables.com/convert/color/hsl-to-rgb.htm # @param h [Integer] hue 0..360 degree # @param l [Integer] lightness 0..100 % # @param s [Integer] saturation 0..100 % # @return [Integer[]] [red, green, blue] # red 0..255 # green 0..255 # blue 0..255 def self.hls_to_rgb h, l, s s /= 100.0 l /= 100.0 c = (1 - (l * 2 - 1).abs) * s x = c * (1 - ((h / 60.0) % 2 - 1).abs) m = l - c / 2 r, g, b = case when h < 60 then [c, x, 0] when h < 120 then [x, c, 0] when h < 180 then [0, c, x] when h < 240 then [0, x, c] when h < 300 then [x, 0, c] else [c, 0, x] end [r, g, b].map{|channel| ((channel + m) * 255).ceil } end # RGB to CMYK conversion | color conversion http://www.rapidtables.com/convert/color/rgb-to-cmyk.htm def self.rgb_to_cmyk r, g, b r /= 255.0 g /= 255.0 b /= 255.0 k = 1 - [r, g, b].max return [0, 0, 0, k.floor] if k == 1 [ (1 - r - k) / (1 - k), (1 - g - k) / (1 - k), (1 - b - k) / (1 - k), k ].map{|channel| channel.to_i if channel.to_i == channel } end # CMYK to RGB conversion | color conversion http://www.rapidtables.com/convert/color/cmyk-to-rgb.htm def self.cmyk_to_rgb c, m, y, k [ (1 - c) * (1 - k), (1 - m) * (1 - k), (1 - y) * (1 - k) ].map{|channel| (channel * 255).ceil } end # don't code today what you can't debug tomorrow: Converting between HSL and HSV http://ariya.blogspot.jp/2008/07/converting-between-hsl-and-hsv.html # @param h [Integer] hue 0..360 degree # @param s [Integer] saturation 0..100 % # @param v [Integer] value 0..100 % # @return [Integer[]] [hue, lightness, saturation] # hue 0..360 degree # lightness 0..100 % # saturation 0..100 % def self.hsv_to_hls h, hsv_s, v l = (200 - hsv_s) * v / 100.0 return [h, l / 2.0, 0].map(&:ceil) if l == 0 || l == 200 [ h, l / 2.0, hsv_s * v * 1.0 / (l <= 100 ? l : 200 - l) ].map &:ceil end # don't code today what you can't debug tomorrow: Converting between HSL and HSV http://ariya.blogspot.jp/2008/07/converting-between-hsl-and-hsv.html def self.hls_to_hsv h, l, hls_s l /= 100.0 hls_s /= 100.0 l *= 2.0 hls_s *= (l <= 1 ? l : 2 - l) return [h, 0, (l + hls_s) / 2.0].map(&:ceil) if l + hls_s == 0 [ h, (2.0 * hls_s) / (l + hls_s) * 100, (l + hls_s) / 2.0 * 100 ].map &:ceil end def initialize r = 0, g = 0, b = 0, a = 0 @r = r @g = g @b = b @a = a end def alpha; @a end def alpha= a; @a = a end def rgba; [@r, @g, @b, @a] end def rgba= channels r, g, b, a = channels @r = r if r @g = g if g @b = b if b @a = a if a end def hsva; [*self.class.rgb_to_hsv(@r, @g, @b), @a] end def hsva= channels h, s, v = self.class.rgb_to_hsv @r, @g, @b h = channels[0] if channels[0] s = channels[1] if channels[1] v = channels[2] if channels[2] @r, @g, @b = self.class.hsv_to_rgb h, s, v @a = channels[3] if channels[3] end def hlsa; [*self.class.rgb_to_hls(@r, @g, @b), @a] end def hsva= channels h, l, s = self.class.rgb_to_hls @r, @g, @b h = channels[0] if channels[0] l = channels[1] if channels[1] s = channels[2] if channels[2] @r, @g, @b = self.class.hls_to_rgb h, l, s @a = channels[3] if channels[3] end def cmyka; [*self.class.rgb_to_cmyk(@r, @g, @b), @a] end def cmyka= channels c, m, y, k = self.class.rgb_to_cmyk @r, @g, @b c = channels[0] if channels[0] m = channels[1] if channels[1] y = channels[2] if channels[2] k = channels[3] if channels[3] @r, @g, @b = self.class.cmyk_to_rgb c, m, y, k @a = channels[4] if channels[4] end end puts 'RGB to HSV' puts "black #{Color.rgb_to_hsv 0, 0, 0} = 0, 0, 0" puts "white #{Color.rgb_to_hsv 255, 255, 255} = 0, 0, 100" puts "red #{Color.rgb_to_hsv 255, 0, 0} = 0, 100, 100" puts "lime #{Color.rgb_to_hsv 0, 255, 0} = 120, 100, 100" puts "blue #{Color.rgb_to_hsv 0, 0, 255} = 240, 100, 100" puts "yellow #{Color.rgb_to_hsv 255, 255, 0} = 60, 100, 100" puts "cyan #{Color.rgb_to_hsv 0, 255, 255} = 180, 100, 100" puts "magenta #{Color.rgb_to_hsv 255, 0, 255} = 300, 100, 100" puts "silver #{Color.rgb_to_hsv 192, 192, 192} = 0, 0, 75" puts "gray #{Color.rgb_to_hsv 128, 128, 128} = 0, 0, 50" puts "maroon #{Color.rgb_to_hsv 128, 0, 0} = 0, 100, 50" puts "olive #{Color.rgb_to_hsv 128, 128, 0} = 60, 100, 50" puts "green #{Color.rgb_to_hsv 0, 128, 0} = 120, 100, 50" puts "purple #{Color.rgb_to_hsv 128, 0, 128} = 300, 100, 50" puts "teal #{Color.rgb_to_hsv 0, 128, 128} = 180, 100, 50" puts "navy #{Color.rgb_to_hsv 0, 0, 128} = 240, 100, 50" puts 'HSV to RGB' puts "black #{Color.hsv_to_rgb 0, 0, 0} = 0, 0, 0" puts "white #{Color.hsv_to_rgb 0, 0, 100} = 255, 255, 255" puts "red #{Color.hsv_to_rgb 0, 100, 100} = 255, 0, 0" puts "lime #{Color.hsv_to_rgb 120, 100, 100} = 0, 255, 0" puts "blue #{Color.hsv_to_rgb 240, 100, 100} = 0, 0, 255" puts "yellow #{Color.hsv_to_rgb 60, 100, 100} = 255, 255, 0" puts "cyan #{Color.hsv_to_rgb 180, 100, 100} = 0, 255, 255" puts "magenta #{Color.hsv_to_rgb 300, 100, 100} = 255, 0, 255" puts "silver #{Color.hsv_to_rgb 0, 0, 75} = 192, 192, 192" puts "gray #{Color.hsv_to_rgb 0, 0, 50} = 128, 128, 128" puts "maroon #{Color.hsv_to_rgb 0, 100, 50} = 128, 0, 0" puts "olive #{Color.hsv_to_rgb 60, 100, 50} = 128, 128, 0" puts "green #{Color.hsv_to_rgb 120, 100, 50} = 0, 128, 0" puts "purple #{Color.hsv_to_rgb 300, 100, 50} = 128, 0, 128" puts "teal #{Color.hsv_to_rgb 180, 100, 50} = 0, 128, 128" puts "navy #{Color.hsv_to_rgb 240, 100, 50} = 0, 0, 128" puts 'RGB to HLS' puts "black #{Color.rgb_to_hls 0, 0, 0} = 0, 0, 0" puts "white #{Color.rgb_to_hls 255, 255, 255} = 0, 100, 0" puts "red #{Color.rgb_to_hls 255, 0, 0} = 0, 50, 100" puts "lime #{Color.rgb_to_hls 0, 255, 0} = 120, 50, 100" puts "blue #{Color.rgb_to_hls 0, 0, 255} = 240, 50, 100" puts "yellow #{Color.rgb_to_hls 255, 255, 0} = 60, 50, 100" puts "cyan #{Color.rgb_to_hls 0, 255, 255} = 180, 50, 100" puts "magenta #{Color.rgb_to_hls 255, 0, 255} = 300, 50, 100" puts "silver #{Color.rgb_to_hls 192, 192, 192} = 0, 75, 0" puts "gray #{Color.rgb_to_hls 128, 128, 128} = 0, 50, 0" puts "maroon #{Color.rgb_to_hls 128, 0, 0} = 0, 25, 100" puts "olive #{Color.rgb_to_hls 128, 128, 0} = 60, 25, 100" puts "green #{Color.rgb_to_hls 0, 128, 0} = 120, 25, 100" puts "purple #{Color.rgb_to_hls 128, 0, 128} = 300, 25, 100" puts "teal #{Color.rgb_to_hls 0, 128, 128} = 180, 25, 100" puts "navy #{Color.rgb_to_hls 0, 0, 128} = 240, 25, 100" puts 'HLS to RGB' puts "black #{Color.hls_to_rgb 0, 0, 0} = 0, 0, 0" puts "white #{Color.hls_to_rgb 0, 100, 0} = 255, 255, 255" puts "red #{Color.hls_to_rgb 0, 50, 100} = 255, 0, 0" puts "lime #{Color.hls_to_rgb 120, 50, 100} = 0, 255, 0" puts "blue #{Color.hls_to_rgb 240, 50, 100} = 0, 0, 255" puts "yellow #{Color.hls_to_rgb 60, 50, 100} = 255, 255, 0" puts "cyan #{Color.hls_to_rgb 180, 50, 100} = 0, 255, 255" puts "magenta #{Color.hls_to_rgb 300, 50, 100} = 255, 0, 255" puts "silver #{Color.hls_to_rgb 0, 75, 0} = 192, 192, 192" puts "gray #{Color.hls_to_rgb 0, 50, 0} = 128, 128, 128" puts "maroon #{Color.hls_to_rgb 0, 25, 100} = 128, 0, 0" puts "olive #{Color.hls_to_rgb 60, 25, 100} = 128, 128, 0" puts "green #{Color.hls_to_rgb 120, 25, 100} = 0, 128, 0" puts "purple #{Color.hls_to_rgb 300, 25, 100} = 128, 0, 128" puts "teal #{Color.hls_to_rgb 180, 25, 100} = 0, 128, 128" puts "navy #{Color.hls_to_rgb 240, 25, 100} = 0, 0, 128" puts 'HSV to HLS' puts "black #{Color.hsv_to_hls 0, 0, 0} = 0, 0, 0" puts "white #{Color.hsv_to_hls 0, 0, 100} = 0, 100, 0" puts "red #{Color.hsv_to_hls 0, 100, 100} = 0, 50, 100" puts "lime #{Color.hsv_to_hls 120, 100, 100} = 120, 50, 100" puts "blue #{Color.hsv_to_hls 240, 100, 100} = 240, 50, 100" puts "yellow #{Color.hsv_to_hls 60, 100, 100} = 60, 50, 100" puts "cyan #{Color.hsv_to_hls 180, 100, 100} = 180, 50, 100" puts "magenta #{Color.hsv_to_hls 300, 100, 100} = 300, 50, 100" puts "silver #{Color.hsv_to_hls 0, 0, 75} = 0, 75, 0" puts "gray #{Color.hsv_to_hls 0, 0, 50} = 0, 50, 0" puts "maroon #{Color.hsv_to_hls 0, 100, 50} = 0, 25, 100" puts "olive #{Color.hsv_to_hls 60, 100, 50} = 60, 25, 100" puts "green #{Color.hsv_to_hls 120, 100, 50} = 120, 25, 100" puts "purple #{Color.hsv_to_hls 300, 100, 50} = 300, 25, 100" puts "teal #{Color.hsv_to_hls 180, 100, 50} = 180, 25, 100" puts "navy #{Color.hsv_to_hls 240, 100, 50} = 240, 25, 100" puts 'HLS to HSV' puts "black #{Color.hls_to_hsv 0, 0, 0} = 0, 0, 0" puts "white #{Color.hls_to_hsv 0, 100, 0} = 0, 0, 100" puts "red #{Color.hls_to_hsv 0, 50, 100} = 0, 100, 100" puts "lime #{Color.hls_to_hsv 120, 50, 100} = 120, 100, 100" puts "blue #{Color.hls_to_hsv 240, 50, 100} = 240, 100, 100" puts "yellow #{Color.hls_to_hsv 60, 50, 100} = 60, 100, 100" puts "cyan #{Color.hls_to_hsv 180, 50, 100} = 180, 100, 100" puts "magenta #{Color.hls_to_hsv 300, 50, 100} = 300, 100, 100" puts "silver #{Color.hls_to_hsv 0, 75, 0} = 0, 0, 75" puts "gray #{Color.hls_to_hsv 0, 50, 0} = 0, 0, 50" puts "maroon #{Color.hls_to_hsv 0, 25, 100} = 0, 100, 50" puts "olive #{Color.hls_to_hsv 60, 25, 100} = 60, 100, 50" puts "green #{Color.hls_to_hsv 120, 25, 100} = 120, 100, 50" puts "purple #{Color.hls_to_hsv 300, 25, 100} = 300, 100, 50" puts "teal #{Color.hls_to_hsv 180, 25, 100} = 180, 100, 50" puts "navy #{Color.hls_to_hsv 240, 25, 100} = 240, 100, 50" puts 'RGB to CMYK' puts "black #{Color.rgb_to_cmyk 0, 0, 0} = 0, 0, 0, 1" puts "white #{Color.rgb_to_cmyk 255, 255, 255} = 0, 0, 0, 0" puts "red #{Color.rgb_to_cmyk 255, 0, 0} = 0, 1, 1, 0" puts "green #{Color.rgb_to_cmyk 0, 255, 0} = 1, 0, 1, 0" puts "blue #{Color.rgb_to_cmyk 0, 0, 255} = 1, 1, 0, 0" puts "yellow #{Color.rgb_to_cmyk 255, 255, 0} = 0, 0, 1, 0" puts "cyan #{Color.rgb_to_cmyk 0, 255, 255} = 1, 0, 0, 0" puts "magenta #{Color.rgb_to_cmyk 255, 0, 255} = 0, 1, 0, 0" puts 'CMYK to RGB' puts "black #{Color.cmyk_to_rgb 0, 0, 0, 1} = 0, 0, 0" puts "white #{Color.cmyk_to_rgb 0, 0, 0, 0} = 255, 255, 255" puts "red #{Color.cmyk_to_rgb 0, 1, 1, 0} = 255, 0, 0" puts "green #{Color.cmyk_to_rgb 1, 0, 1, 0} = 0, 255, 0" puts "blue #{Color.cmyk_to_rgb 1, 1, 0, 0} = 0, 0, 255" puts "yellow #{Color.cmyk_to_rgb 0, 0, 1, 0} = 255, 255, 0" puts "cyan #{Color.cmyk_to_rgb 1, 0, 0, 0} = 0, 255, 255" puts "magenta #{Color.cmyk_to_rgb 0, 1, 0, 0} = 255, 0, 255"