本模块封装一系列简单的色彩操作,以适应不同的使用需求。
应被模板封装以提供对外使用的接口。
为颜色的亮度设置一个门限值,当超过该门限值时自动降低亮度。
为颜色的明度设置一个门限值,当超过该门限值时自动降低亮度。
对颜色的色相进行增减操作。
混合两种颜色。
校验输入的十六进制颜色代码并转换为RGB值。
将输入的RGB值转换为十六进制颜色代码。
将RGB颜色转换为HSL颜色。
将HSL颜色转换为RGB颜色。
将RGB颜色转换为HSV颜色。
将HSV颜色转换为RGB颜色。
0.4124564 | 0.3575761 | 0.1804375 |
0.2126729 | 0.7151522 | 0.0721750 |
0.0193339 | 0.1191920 | 0.9503041 |
将RGB颜色转换为XYZ颜色。
将XYZ颜色转换为RGB颜色。
p = {} p["LuminThres"] = function(frame) local colorString = frame.args[1] local lumThreshold = frame.args[2] return p.luminThres(colorString, lumThreshold) end -- 为HSL颜色的L设置门限值,在超过门限值时自动降低。 -- Arg: Hex, 门限值 -- Return: 处理后的颜色的Hex function p.luminThres(colorString, lumThreshold) r,g,b,flag = parseString(colorString) h,s,l = rgbToHsl(r,g,b) l = math.min(lumThreshold, l) r,g,b = hslToRgb(h,s,l) return parseRGB(r,g,b,flag) end p["ValThres"] = function(frame) local colorString = frame.args[1] local valThreshold = frame.args[2] return p.valThres(colorString, valThreshold) end -- 为HSV颜色的V设置门限值,在超过门限值时自动降低。 -- Arg: Hex, 门限值 -- Return: 处理后的颜色的Hex function p.valThres(colorString, valThreshold) r,g,b,flag = parseString(colorString) h,s,v = rgbToHsv(r,g,b) v = math.min(valThreshold, v) r,g,b = hsvToRgb(h,s,v) return parseRGB(r,g,b,flag) end p["HueShift"] = function(frame) local colorString = frame.args[1] local shift = frame.args[2] return p.hueShift(colorString, shift) end -- 对HSL颜色的H进行偏移。 -- Arg: Hex, 偏移值(整个色环为360度) -- Return: 处理后的颜色的Hex function p.hueShift(colorString, shift) r,g,b,flag = parseString(colorString) h,s,l = rgbToHsl(r,g,b) h = h+shift/360 r,g,b = hslToRgb(h,s,l) return parseRGB(r,g,b,flag) end p["ColorMix"] = function(frame) local colorString1 = frame.args[1] local colorString2 = frame.args[2] local weight = frame.args[3] return p.colorMix(colorString1, colorString2, weight) end -- 以取RGB均值的方式混合颜色 -- Arg: 两个颜色各自的Hex, 权值 -- Return: 混合后的颜色的Hex function p.colorMix(colorString1, colorString2, weight) r1,g1,b1,flag1 = parseString(colorString1) r2,g2,b2,flag2 = parseString(colorString2) r = r1*(1-weight) + r2*weight g = g1*(1-weight) + g2*weight b = b1*(1-weight) + b2*weight return parseRGB(r,g,b,flag1) end -- Helper function: 将RGB值转换为Hex -- Arg: R, G, B, 输出模式(0 = 不带#号 / 1 = 带#号) -- Return: Hex function parseRGB(r,g,b,mode) -- 四舍五入处理 r=math.floor(math.max(math.min(r + 0.5, 255),0)) g=math.floor(math.max(math.min(g + 0.5, 255),0)) b=math.floor(math.max(math.min(b + 0.5, 255),0)) colorNumber = r * 65536 + g * 256 + b colorString = string.format("%06X",colorNumber) -- padding if(mode == 0) then return colorString end if(mode == 1) then return "#"..colorString end end -- Helper function: 检测Hex值是否合法,并将Hex转换为RGB值 -- Arg: Hex -- Return: R, G, B, 输出模式(0 = 不带#号 / 1 = 带#号) -- TODO: 三位Color Hex、Web Color名 function parseString(colorString) length = #colorString startWith, endWith = string.find(colorString,"[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]") if(string.sub(colorString, 1, 1) == "#" and startWith == 2 and endWith == 7 and length == 7) then colorString = (string.sub(colorString, 2)) colorNumber = tonumber(colorString, 16) r = math.floor(colorNumber / 65536) g = math.floor(colorNumber / 256 % 256) b = colorNumber % 256 return r,g,b,1 elseif(startWith == 1 and endWith == 6 and length == 6) then colorNumber = tonumber(colorString, 16) r = math.floor(colorNumber / 65536) g = math.floor(colorNumber / 256 % 256) b = colorNumber % 256 return r,g,b,0 end end -- ref from http://axonflux.com/handy-rgb-to-hsl-and-rgb-to-hsv-color-model-c function rgbToHsl(r, g, b) r, g, b = r / 255, g / 255, b / 255 local max, min = math.max(r, g, b), math.min(r, g, b) local h, s, l l = (max + min) / 2 if max == min then h, s = 0, 0 -- achromatic else d = max - min if l > 0.5 then s = d / (2 - max - min) else s = d / (max + min) end if max == r then h = (g - b) / d if g < b then h = h + 6 end elseif max == g then h = (b - r) / d + 2 elseif max == b then h = (r - g) / d + 4 end h = h / 6 end return h, s, l end -- ref from http://axonflux.com/handy-rgb-to-hsl-and-rgb-to-hsv-color-model-c function hslToRgb(h, s, l) local r, g, b if s == 0 then r, g, b = l, l, l -- achromatic else function hue2rgb(p, q, t) if t < 0 then t = t + 1 end if t > 1 then t = t - 1 end if t < 1/6 then return p + (q - p) * 6 * t end if t < 1/2 then return q end if t < 2/3 then return p + (q - p) * (2/3 - t) * 6 end return p end local q if l < 0.5 then q = l * (1 + s) else q = l + s - l * s end local p = 2 * l - q r = hue2rgb(p, q, h + 1/3) g = hue2rgb(p, q, h) b = hue2rgb(p, q, h - 1/3) end return r * 255, g * 255, b * 255 end -- ref from http://axonflux.com/handy-rgb-to-hsl-and-rgb-to-hsv-color-model-c function rgbToHsv(r, g, b) r, g, b = r / 255, g / 255, b / 255 local max, min = math.max(r, g, b), math.min(r, g, b) local h, s, v v = max local d = max - min if max == 0 then s = 0 else s = d / max end if max == min then h = 0 -- achromatic else if max == r then h = (g - b) / d if g < b then h = h + 6 end elseif max == g then h = (b - r) / d + 2 elseif max == b then h = (r - g) / d + 4 end h = h / 6 end return h, s, v end -- ref from http://axonflux.com/handy-rgb-to-hsl-and-rgb-to-hsv-color-model-c function hsvToRgb(h, s, v) local r, g, b local i = math.floor(h * 6); local f = h * 6 - i; local p = v * (1 - s); local q = v * (1 - f * s); local t = v * (1 - (1 - f) * s); i = i % 6 if i == 0 then r, g, b = v, t, p elseif i == 1 then r, g, b = q, v, p elseif i == 2 then r, g, b = p, v, t elseif i == 3 then r, g, b = p, q, v elseif i == 4 then r, g, b = t, p, v elseif i == 5 then r, g, b = v, p, q end return r * 255, g * 255, b * 255 end function rgbToXyz (r, g, b) r, g, b = r / 255, g / 255, b / 255 -- normalize if r <= 0.03928 then r = r/12.92 else r = ((r+0.055)/1.055) ^ 2.4 end if g <= 0.03928 then g = g/12.92 else g = ((g+0.055)/1.055) ^ 2.4 end if b <= 0.03928 then b = b/12.92 else b = ((b+0.055)/1.055) ^ 2.4 end -- matrix x = r*0.4124564 + g*0.3575761 + b*0.1804375 y = r*0.2126729 + g*0.7151522 + b*0.0721750 z = r*0.0193339 + g*0.1191920 + b*0.9503041 return x,y,z end function xyzToRgb (x, y, z) -- matrix r = x*3.2404542 - y*1.5371385 - z*0.4985314 g = -x*0.9692660 + y*1.8760108 + z*0.0415560 b = x*0.0556434 - y*0.2040259 + z*1.0572252 -- denormalize if r <= 0.00303949249 then r = r*12.92 else r = r^(1/2.4) * 1.055 - 0.055 end if g <= 0.00303949249 then g = g*12.92 else g = g^(1/2.4) * 1.055 - 0.055 end if b <= 0.00303949249 then b = b*12.92 else b = b^(1/2.4) * 1.055 - 0.055 end return r*255, g*255, b*255 end return p