#!ruby -Ku # -*- mode: ruby; coding: utf-8 -*- # Last updated: <2017/04/09 12:53:38 +0900> # # hls to rgb and rgb to hls # # License: CC0 / Public Domain # hls to rgb, rgb to hls module TinyColorSys # HLS to RGB # @param h [Float] hue (0.0 - 1.0) # @param l [Float] lightness (0.0 - 1.0) # @param s [Float] saturation (0.0 - 1.0) # @return [Array] R,G,B (0 - 255) def hls_to_rgb(h, l, s) h = (h % 1.0) l = [[l, 1.0].min, 0.0].max s = [[s, 1.0].min, 0.0].max if l < 0.5 maxv = l + l * s minv = l - l * s else maxv = l + (1.0 - l) * s minv = l - (1.0 - l) * s end maxv *= 255.0 minv *= 255.0 h *= 360.0 h = (h % 360.0) if h >= 0 and h <= 60 r = maxv g = (h / 60.0) * (maxv - minv) + minv b = minv elsif h >= 60 and h <= 120 r = ((120 - h) / 60.0) * (maxv - minv) + minv g = maxv b = minv elsif h >= 120 and h <= 180 r = minv g = maxv b = ((h - 120) / 60.0) * (maxv - minv) + minv elsif h >= 180 and h <= 240 r = minv g = ((240 - h) / 60.0) * (maxv - minv) + minv b = maxv elsif h >= 240 and h <= 300 r = ((h - 240) / 60.0) * (maxv - minv) + minv g = minv b = maxv elsif h >= 300 and h <= 360 r = maxv g = minv b = ((360 - h) / 60.0) * (maxv - minv) + minv end return r.to_i, g.to_i, b.to_i end # RGB to HLS # @param r [Integer] Red (0 - 255) # @param g [Integer] Green (0 - 255) # @param b [Integer] Blue (0 - 255) # @return [Array] hue, lightness, saturation # hue = (0.0 - 1.0) # lightness = (0.0 - 1.0) # saturation = (0.0 - 1.0) def rgb_to_hls(r, g, b) minv = [r, g, b].min maxv = [r, g, b].max # hue if maxv == minv h = 0.0 else if r > g and r > b # R MAX h = 60.0 * (g - b) / (maxv - minv) elsif g > b # G MAX h = 60.0 * (b - r) / (maxv - minv) + 120.0 elsif b > g # B MAX h = 60.0 * (r - g) / (maxv - minv) + 240.0 else h = 0.0 end end h += 360.0 if h < 0 h /= 360.0 # saturation cnt = (maxv + minv) / 2.0 if maxv == minv s = 0.0 else if cnt <= 127 s = (maxv - minv).to_f / (maxv + minv) else s = (maxv - minv).to_f / (510.0 - maxv - minv) end end # lightness l = ((maxv + minv) / 2.0) / 255.0 return h, l, s end end if $0 == __FILE__ # ---------------------------------------- # usage sample require 'dxruby' include TinyColorSys fnt = Font.new(28) v2 = 0.5 set_hls = true Window.loop do break if Input.keyPush?(K_ESCAPE) set_hls = !set_hls if Input.mousePush?(M_LBUTTON) v0 = Input.mousePosX.to_f / (Window.width - 1) v0 = [[v0, 1.0].min, 0.0].max v1 = Input.mousePosY.to_f / (Window.height - 1) v1 = [[v1, 1.0].min, 0.0].max v2 += (Input.keyDown?(K_UP))? (1.0 / 255.0) : 0 v2 -= (Input.keyDown?(K_DOWN))? (1.0 / 255.0) : 0 v2 = [[v2, 1.0].min, 0.0].max if set_hls h = v0 l = v1 s = v2 r, g, b = hls_to_rgb(h, l, s) h = (h * 360).to_i l = (l * 100).to_i s = (s * 100).to_i else r = (v0 * 255).to_i g = (v1 * 255).to_i b = (v2 * 255).to_i h, l, s = rgb_to_hls(r, g, b) h = (360 * h).to_i l = (100 * l).to_i s = (100 * s).to_i end Window.bgcolor = [r, g, b] col = (l < 50)? C_WHITE : C_BLACK msg = (set_hls)? "use HLS" : "use RGB" Window.drawFont(4, 4, msg, fnt, :color => col) Window.drawFont(4, 40, "RGB=#{r}, #{g}, #{b}", fnt, :color => col) Window.drawFont(4, 80, "HLS=#{h}, #{l}, #{s}", fnt, :color => col) Window.drawFont(4, 120, "(mouse x/y , Up/Down key)", fnt, :color => col) end end