以编程方式使亮度变暗或变暗十六进制颜色(或rgb和混合颜色)
这是我正在努力的一个功能,以程序化的方式减轻或加深一个特定量的十六进制颜色。 只需传递像"3F6D2A"
的颜色( col
)和一个base10整数( amt
)的字符串,以使亮度变暗或变暗。 变暗,传入负数(即-20)。
我之所以这样做是因为我发现的所有解决方案,迄今为止,它们似乎使问题过度复杂化。 我有一种感觉,它可以用几行代码完成。 如果您发现任何问题,请告诉我,或者做出任何调整以加快速度。
function LightenDarkenColor(col,amt) {
col = parseInt(col,16);
return (((col & 0x0000FF) + amt) | ((((col>> 8) & 0x00FF) + amt) << 8) | (((col >> 16) + amt) << 16)).toString(16);
}
开发使用这里是一个更容易阅读的版本:
function LightenDarkenColor(col,amt) {
var num = parseInt(col,16);
var r = (num >> 16) + amt;
var b = ((num >> 8) & 0x00FF) + amt;
var g = (num & 0x0000FF) + amt;
var newColor = g | (b << 8) | (r << 16);
return newColor.toString(16);
}
最后是一个版本,用于处理可能(或可能不)在开头具有“#”的颜色。 加上调整不正确的颜色值:
function LightenDarkenColor(col,amt) {
var usePound = false;
if ( col[0] == "#" ) {
col = col.slice(1);
usePound = true;
}
var num = parseInt(col,16);
var r = (num >> 16) + amt;
if ( r > 255 ) r = 255;
else if (r < 0) r = 0;
var b = ((num >> 8) & 0x00FF) + amt;
if ( b > 255 ) b = 255;
else if (b < 0) b = 0;
var g = (num & 0x0000FF) + amt;
if ( g > 255 ) g = 255;
else if ( g < 0 ) g = 0;
return (usePound?"#":"") + (g | (b << 8) | (r << 16)).toString(16);
}
好的,现在它不仅仅是几行,而且看起来简单得多,如果你不使用“#”,并且不需要检查超出范围的颜色,那只是几行。
如果不使用“#”,您可以将其添加到如下代码中:
var myColor = "3F6D2A";
myColor = LightenDarkenColor(myColor,10);
thePlaceTheColorIsUsed = ("#" + myColor);
我想我的主要问题是,我在这里纠正? 这是否包含一些(正常)情况?
TL; DR? - 想简单的减轻/变暗(阴影)? 跳到第2版,选择一个RGB或十六进制。 - 想要一个功能齐全的着色器/混合器/转换器与错误检查和alpha和3位十六进制? 使用版本3附近的底部。
使用3.1版来玩:jsfiddle> shadeBlendConvert示例
GitHub上的3.1版:Goto GitHub> PJs> pSBC
经过一番思考......我决定回答我自己的问题。 一年半后。 这真的是一个冒险与来自几个有用的用户的想法,我谢谢大家! 这一个是给团队的! 虽然它不一定是我正在寻找的答案。 因为如果James Khoury说的是真的,那么javascript中就没有真正的十六进制数学,我必须使用小数,这种双重转换是必要的。 如果我们做出这样的假设,那么这可能是我看到(或可以想到)以百分比减轻(增加白色)或增加黑色(增加黑色)任意RBG颜色的最快方式。 它也解释了Cool Acid在他回答这个问题时提到的问题(它填充0)。 但是这个版本只调用一次toString
。 这也是超出范围的(它将强制执行0和255作为限制)。
但要小心,颜色输入必须是7个字符,如#08a35c
。 (如果使用顶级版本,则为6)
感谢Pablo提供使用百分比的灵感和想法。 为此,我将保持函数名称相同! 大声笑! 然而,这一点是不同的,因为它将百分比标准化为255,因此将相同的数量添加到每种颜色(更多白色)。 如果你在100的传递percent
它会让你的颜色纯白。 如果您以percent
传递0,则不会发生任何事情。 如果您通过percent
1,则会为所有颜色添加3个阴影(每1%2.55阴影,四舍五入)。 所以你真的在白色(或黑色,使用负面)的百分比传递。 因此,该版本允许您减轻纯红色(FF0000),例如。
我也使用Keith Mashinter对这个问题的答案的见解:如何在JavaScript中将十进制转换为十六进制?
我删除了一些,似乎是不必要的括号。 (就像在二元三元语句和G中一样)不确定这是否会在某些环境中与运算符优先级混淆。 测试良好的FireFox。
function shadeColor1(color, percent) { // deprecated. See below.
var num = parseInt(color,16),
amt = Math.round(2.55 * percent),
R = (num >> 16) + amt,
G = (num >> 8 & 0x00FF) + amt,
B = (num & 0x0000FF) + amt;
return (0x1000000 + (R<255?R<1?0:R:255)*0x10000 + (G<255?G<1?0:G:255)*0x100 + (B<255?B<1?0:B:255)).toString(16).slice(1);
}
或者,如果您想要它处理“#”:
function shadeColor1(color, percent) { // deprecated. See below.
var num = parseInt(color.slice(1),16), amt = Math.round(2.55 * percent), R = (num >> 16) + amt, G = (num >> 8 & 0x00FF) + amt, B = (num & 0x0000FF) + amt;
return "#" + (0x1000000 + (R<255?R<1?0:R:255)*0x10000 + (G<255?G<1?0:G:255)*0x100 + (B<255?B<1?0:B:255)).toString(16).slice(1);
}
对于两行代码来说呢?
编辑:修复B < - > G交换混淆。 谢谢svachalek!
- 更新 - 版本2与混合 -
一年多之后,又一次,它还在继续。 但是这次我认为它完成了。 注意到关于不使用HSL来正确减轻颜色的问题。 有一种技术可以消除大部分的不准确性,而不必转换为HSL。 主要的问题是颜色通道在其余颜色之前会完全饱和。 在那之后引起色调的变化。 我在这里和这里发现了这些问题,这让我走上了正轨。 Mark Ransom的帖子向我展示了它的不同之处,Keith的帖子为我指明了方向。 莱普是救世主。 它与混合颜色相同,所以我也创建了blendColors
函数。
TL; DR - 对于简单的减轻/变暗使用下面的这个函数shadeColor2
。 或者其RGB对应的shadeRGBColor
RGB进一步下面,给我一票。 但是,如果你想要任何和/或所有的好东西。 例如可以同时使用RGB和Hex色彩,错误检测,3位十六进制解码,混合,Alpha通道和RGB2Hex / Hex2RGB转换。 然后,跳至第3版,查看shadeBlendConvert
以获取所有的shadeBlendConvert
和哨子,并给我两张选票。 如果需要,您可以删除几行以删除其中一些功能。 如果您还记得上面的版本1 shadeColor1
已被弃用于所有用途,那么您会得到一票。
所以,毫不犹豫:
- 版本2 Hex-
function shadeColor2(color, percent) {
var f=parseInt(color.slice(1),16),t=percent<0?0:255,p=percent<0?percent*-1:percent,R=f>>16,G=f>>8&0x00FF,B=f&0x0000FF;
return "#"+(0x1000000+(Math.round((t-R)*p)+R)*0x10000+(Math.round((t-G)*p)+G)*0x100+(Math.round((t-B)*p)+B)).toString(16).slice(1);
}
function blendColors(c0, c1, p) {
var f=parseInt(c0.slice(1),16),t=parseInt(c1.slice(1),16),R1=f>>16,G1=f>>8&0x00FF,B1=f&0x0000FF,R2=t>>16,G2=t>>8&0x00FF,B2=t&0x0000FF;
return "#"+(0x1000000+(Math.round((R2-R1)*p)+R1)*0x10000+(Math.round((G2-G1)*p)+G1)*0x100+(Math.round((B2-B1)*p)+B1)).toString(16).slice(1);
}
更进一步:
没有错误检查,所以传入的值超出范围将导致意外的结果。 此外,颜色输入必须是7个字符,如#08a35c
。 但所有其他的东西仍然在这里像输出范围上限(00-FF输出),填充(0A),句柄#
,并可用于纯色,如#FF0000
。
这个新版本的shadeColor为其第二个参数提供了一个浮点数。 对于shadeColor2
,第二个(百分比)参数的有效范围是-1.0
到1.0
。
对于blendColors
,第三个(百分比)参数的有效范围是0.0
到1.0
,这里不允许使用负数。
这个新版本不再接受纯白的百分比,就像旧版本一样。 它从纯白色的颜色中吸收一定比例的DISTANCE。 在旧版本中,很容易使颜色饱和,结果,当使用相当大的百分比时,许多颜色会计算为纯白色。 这种新方法,如果你通过1.0
或纯黑色,则只计算纯白色,使用-1.0
。
调用blendColors(color, "#FFFFFF", 0.5)
与shadeColor2(color,0.5)
。 以及blendColors(color,"#000000", 0.5)
与shadeColor2(color,-0.5)
。 只是一个接触较慢。
shadeColor2
比shadeColor1
慢,但不是很明显。 (等等,这是一个自相矛盾的说法!)
获得的准确度可以在这里看到:
- 版本2 RGB -
function shadeRGBColor(color, percent) {
var f=color.split(","),t=percent<0?0:255,p=percent<0?percent*-1:percent,R=parseInt(f[0].slice(4)),G=parseInt(f[1]),B=parseInt(f[2]);
return "rgb("+(Math.round((t-R)*p)+R)+","+(Math.round((t-G)*p)+G)+","+(Math.round((t-B)*p)+B)+")";
}
function blendRGBColors(c0, c1, p) {
var f=c0.split(","),t=c1.split(","),R=parseInt(f[0].slice(4)),G=parseInt(f[1]),B=parseInt(f[2]);
return "rgb("+(Math.round((parseInt(t[0].slice(4))-R)*p)+R)+","+(Math.round((parseInt(t[1])-G)*p)+G)+","+(Math.round((parseInt(t[2])-B)*p)+B)+")";
}
用途:
var color1 = "rbg(63,131,163)";
var lighterColor = shadeRGBColor(color1, 0.5); // rgb(159,193,209)
var darkerColor = shadeRGBColor(color1, -0.25); // rgb(47,98,122)
var color2 = "rbg(244,128,0)";
var blend1 = blendRGBColors(color1, color2, 0.75); // rgb(199,129,41)
var blend2 = blendRGBColors(color2, color1, 0.62); // rgb(132,130,101)
- 版本2 Universal A -
function shade(color, percent){
if (color.length > 7 ) return shadeRGBColor(color,percent);
else return shadeColor2(color,percent);
}
function blend(color1, color2, percent){
if (color1.length > 7) return blendRGBColors(color1,color2,percent);
else return blendColors(color1,color2,percent);
}
用法:
var color1 = shade("rbg(63,131,163)", 0.5);
var color2 = shade("#3f83a3", 0.5);
var color3 = blend("rbg(63,131,163)", "rbg(244,128,0)", 0.5);
var color4 = blend("#3f83a3", "#f48000", 0.5);
- 版本2通用B -
好的! 这个答案的受欢迎程度让我觉得我可以做一个更好的通用版本。 所以,你去! 此版本是RGB和Hex色彩的全功能复制/粘贴着色器/混合器。 这个与上面提供的其他Uni版本没有任何区别。 除了它的小得多,只是一个功能粘贴和使用。 如果将它压缩成一行,我认为大小从大约1,592个字符变成了557个字符。 当然,如果你不需要在RGB和Hex之间交替使用它,那么你不需要像这样的通用版本,不管怎样,哈哈。 只需使用上面更小更快的版本之一; 适合您的配色方案。 继续......在某些方面,它稍微快一些,在某些方面稍慢一点。 我没有做任何最终的速度测试分析。 有两种用法上的区别:第一,百分比现在是函数的第一个参数,而不是最后一个。 其次,在混合时,可以使用负数。 他们只会转换为正数。
再也不用说了:
function shadeBlend(p,c0,c1) {
var n=p<0?p*-1:p,u=Math.round,w=parseInt;
if(c0.length>7){
var f=c0.split(","),t=(c1?c1:p<0?"rgb(0,0,0)":"rgb(255,255,255)").split(","),R=w(f[0].slice(4)),G=w(f[1]),B=w(f[2]);
return "rgb("+(u((w(t[0].slice(4))-R)*n)+R)+","+(u((w(t[1])-G)*n)+G)+","+(u((w(t[2])-B)*n)+B)+")"
}else{
var f=w(c0.slice(1),16),t=w((c1?c1:p<0?"#000000":"#FFFFFF").slice(1),16),R1=f>>16,G1=f>>8&0x00FF,B1=f&0x0000FF;
return "#"+(0x1000000+(u(((t>>16)-R1)*n)+R1)*0x10000+(u(((t>>8&0x00FF)-G1)*n)+G1)*0x100+(u(((t&0x0000FF)-B1)*n)+B1)).toString(16).slice(1)
}
}
用法:
var color1 = "#FF343B";
var color2 = "#343BFF";
var color3 = "rgb(234,47,120)";
var color4 = "rgb(120,99,248)";
var shadedcolor1 = shadeBlend(0.75,color1);
var shadedcolor3 = shadeBlend(-0.5,color3);
var blendedcolor1 = shadeBlend(0.333,color1,color2);
var blendedcolor34 = shadeBlend(-0.8,color3,color4); // Same as using 0.8
现在它可能是完美的! ;) @ Mevin
* V2其他语言*
- Swift Extension - RGB(Matej Ukmar) -
extension UIColor {
func shadeColor(factor: CGFloat) -> UIColor {
var r: CGFloat = 0
var g: CGFloat = 0
var b: CGFloat = 0
var a: CGFloat = 0
var t: CGFloat = factor < 0 ? 0 : 1
var p: CGFloat = factor < 0 ? -factor : factor
getRed(&r, green: &g, blue: &b, alpha: &a)
r = (t-r)*p+r
g = (t-g)*p+g
b = (t-b)*p+b
return UIColor(red: r, green: g, blue: b, alpha: a)
}
}
- PHP版本 - HEX(by Kevin M) -
function shadeColor2($color, $percent) {
$color = str_replace("#", "", $color);
$t=$percent<0?0:255;
$p=$percent<0?$percent*-1:$percent;
$RGB = str_split($color, 2);
$R=hexdec($RGB[0]);
$G=hexdec($RGB[1]);
$B=hexdec($RGB[2]);
return '#'.substr(dechex(0x1000000+(round(($t-$R)*$p)+$R)*0x10000+(round(($t-$G)*$p)+$G)*0x100+(round(($t-$B)*$p)+$B)),1);
}
- 更新 - 版本3.1通用 -
(这已经添加到我在GitHub的库中)
在几个月内,它将是上一个通用版本的又一年。 所以......感谢斯里克斯富有洞察力的评论。 我决定再次将它提升到一个新的水平。 它已经不再是它开始的两线速度恶魔了,哈哈。 但是,它的功能很快,很小。 它的大约1600字节。 如果您删除ErrorChecking并删除3位解码,则可以将其降至1200字节左右,且速度更快。 这对于一个K来说有很大的力量。想象一下,你可以将它加载到Commodore64上,并且还有50个空间! (不考虑JavaScript引擎大于63k的事实)
显然有更多的事情要做:
const shadeBlendConvert = function (p, from, to) {
if(typeof(p)!="number"||p<-1||p>1||typeof(from)!="string"||(from[0]!='r'&&from[0]!='#')||(to&&typeof(to)!="string"))return null; //ErrorCheck
if(!this.sbcRip)this.sbcRip=(d)=>{
let l=d.length,RGB={};
if(l>9){
d=d.split(",");
if(d.length<3||d.length>4)return null;//ErrorCheck
RGB[0]=i(d[0].split("(")[1]),RGB[1]=i(d[1]),RGB[2]=i(d[2]),RGB[3]=d[3]?parseFloat(d[3]):-1;
}else{
if(l==8||l==6||l<4)return null; //ErrorCheck
if(l<6)d="#"+d[1]+d[1]+d[2]+d[2]+d[3]+d[3]+(l>4?d[4]+""+d[4]:""); //3 or 4 digit
d=i(d.slice(1),16),RGB[0]=d>>16&255,RGB[1]=d>>8&255,RGB[2]=d&255,RGB[3]=-1;
if(l==9||l==5)RGB[3]=r((RGB[2]/255)*10000)/10000,RGB[2]=RGB[1],RGB[1]=RGB[0],RGB[0]=d>>24&255;
}
return RGB;}
var i=parseInt,r=Math.round,h=from.length>9,h=typeof(to)=="string"?to.length>9?true:to=="c"?!h:false:h,b=p<0,p=b?p*-1:p,to=to&&to!="c"?to:b?"#000000":"#FFFFFF",f=this.sbcRip(from),t=this.sbcRip(to);
if(!f||!t)return null; //ErrorCheck
if(h)return "rgb"+(f[3]>-1||t[3]>-1?"a(":"(")+r((t[0]-f[0])*p+f[0])+","+r((t[1]-f[1])*p+f[1])+","+r((t[2]-f[2])*p+f[2])+(f[3]<0&&t[3]<0?")":","+(f[3]>-1&&t[3]>-1?r(((t[3]-f[3])*p+f[3])*10000)/10000:t[3]<0?f[3]:t[3])+")");
else return "#"+(0x100000000+r((t[0]-f[0])*p+f[0])*0x1000000+r((t[1]-f[1])*p+f[1])*0x10000+r((t[2]-f[2])*p+f[2])*0x100+(f[3]>-1&&t[3]>-1?r(((t[3]-f[3])*p+f[3])*255):t[3]>-1?r(t[3]*255):f[3]>-1?r(f[3]*255):255)).toString(16).slice(1,f[3]>-1||t[3]>-1?undefined:-2);
}
使用3.1版来玩:jsfiddle> shadeBlendConvert示例
这个版本的核心数学和以前一样。 但是,我做了一些重大的重构。 这实现了更多的功能和控制。 它现在固有地转换RGB2Hex和Hex2RGB。
上面v2的所有旧功能应该仍然在这里。 我试图测试一切,如果发现任何错误,请发表评论。 总之,以下是新功能:
//3 digit
以删除此功能。 from
颜色或to
颜色具有alpha通道,则结果将具有alpha通道。 如果两种颜色都有一个alpha通道,则结果将是使用给定百分比的两个alpha通道的混合(就像它是一个正常的颜色通道一样)。 如果两种颜色中只有一种颜色具有alpha通道,则这个alpha将会直接传递给结果。 这允许在保持透明水平的同时混合/遮蔽透明颜色。 或者,如果透明级别也应混合,请确保两种颜色都有alpha。 底纹将直通alpha通道,如果你想基本的阴影还融合了阿尔法通道,然后使用rgb(0,0,0,1)
或rgb(255,255,255,1)
为您to
颜色(或hex等值)。 对于RGB颜色,生成的alpha通道将四舍五入至小数点后4位。 to
颜色的形式存在(如果存在)。 如果没有to
颜色,然后通过'c'
中的to
颜色,它会遮荫和转换。 如果只需要转换,则也将百分比传递给0
。 sbcRip
可以通过十六进制或rbg颜色,并返回包含此颜色信息的对象。 其形式为: {0:R,1:G,2:B,3:A}
。 其中R G和B的范围是0
到255
。 当没有alpha时: A是-1
。 否则: A的范围为0.0000
至1.0000
。 null
。 一个例子: shadeBlendConvert(0.5,"salt") = null
,因为它认为#salt
是一个有效的颜色。 删除标有//ErrorCheck
四行以删除此功能。 用途:
let color1 = "rgb(20,60,200)";
let color2 = "rgba(20,60,200,0.67423)";
let color3 = "#67DAF0";
let color4 = "#5567DAF0";
let color5 = "#F3A";
let color6 = "#F3A9";
let color7 = "rgb(200,60,20)";
let color8 = "rgba(200,60,20,0.98631)";
let c;
// Shade (Lighten or Darken)
c = shadeBlendConvert ( 0.42, color1 ); // rgb(20,60,200) + [42% Lighter] => rgb(119,142,223)
c = shadeBlendConvert ( -0.4, color5 ); // #F3A + [40% Darker] => #991f66
c = shadeBlendConvert ( 0.42, color8 ); // rgba(200,60,20,0.98631) + [42% Lighter] => rgba(223,142,119,0.98631)
// Shade with Conversion (use "c" as your "to" color)
c = shadeBlendConvert ( 0.42, color2, "c" ); // rgba(20,60,200,0.67423) + [42% Lighter] + [Convert] => #778edfac
// RGB2Hex & Hex2RGB Conversion Only (set percentage to zero)
c = shadeBlendConvert ( 0, color6, "c" ); // #F3A9 + [Convert] => rgba(255,51,170,0.6)
// Blending
c = shadeBlendConvert ( -0.5, color2, color8 ); // rgba(20,60,200,0.67423) + rgba(200,60,20,0.98631) + [50% Blend] => rgba(110,60,110,0.8303)
c = shadeBlendConvert ( 0.7, color2, color7 ); // rgba(20,60,200,0.67423) + rgb(200,60,20) + [70% Blend] => rgba(146,60,74,0.67423)
c = shadeBlendConvert ( 0.25, color3, color7 ); // #67DAF0 + rgb(200,60,20) + [25% Blend] => rgb(127,179,185)
c = shadeBlendConvert ( 0.75, color7, color3 ); // rgb(200,60,20) + #67DAF0 + [75% Blend] => #7fb3b9
// Error Checking
c = shadeBlendConvert ( 0.42, "#FFBAA" ); // #FFBAA + [42% Lighter] => null (Invalid Input Color)
c = shadeBlendConvert ( 42, color1, color5 ); // rgb(20,60,200) + #F3A + [4200% Blend] => null (Invalid Percentage Range)
c = shadeBlendConvert ( 0.42, {} ); // [object Object] + [42% Lighter] => null (Strings Only for Color)
c = shadeBlendConvert ( "42", color1 ); // rgb(20,60,200) + ["42"] => null (Numbers Only for Percentage)
c = shadeBlendConvert ( 0.42, "salt" ); // salt + [42% Lighter] => null (A Little Salt is No Good...)
// Error Check Fails (Some Errors are not Caught)
c = shadeBlendConvert ( 0.42, "#salt" ); // #salt + [42% Lighter] => #6b6b6b00 (...and a Pound of Salt is Jibberish)
// Ripping
c = sbcRip ( color4 ); // #5567DAF0 + [Rip] => [object Object] => {'0':85,'1':103,'2':218,'3':0.9412}
我现在毫不犹豫地把这件事完成......再次......
PT
-编辑:交换第3版使用let
,和箭头的功能,并增加了this
对sbcRip
调用。
---- === <| MAJOR EDIT(3/9/18)|> === ----
我很惭愧! (并且很惊讶,没有人提到过这个)显然,我不在自己的项目中使用alpha通道......并且...显然我做了可怕的测试。 版本3没有正确读取或写入带有alpha通道的颜色。 有几点,我要么是错了,要么从未真正学过:
rgba()
而不是rgb()
; 版本3从不输出rgba()
。 rgba()
但在rgb()
接受了alpha,这不应该发生。 我现在只是将版本3替换为版本3.1,解决了这些问题。 我没有把它作为一个单独的函数发布在这里; 看到旧版本3应该从存在中移除并替换为这个版本。 这就是我所做的。 以上版本3实际上是版本3.1。
以上所有旧功能仍在这里进行更新:
to
现在颜色接受串色或falsy(其仍然可以undefined
)。 ...我很高兴我犹豫再次将其称之为完成。 我们在这里,又过了一年......仍在完善......
PT
我提出了一个对我非常好的解决方案:
function shadeColor(color, percent) {
var R = parseInt(color.substring(1,3),16);
var G = parseInt(color.substring(3,5),16);
var B = parseInt(color.substring(5,7),16);
R = parseInt(R * (100 + percent) / 100);
G = parseInt(G * (100 + percent) / 100);
B = parseInt(B * (100 + percent) / 100);
R = (R<255)?R:255;
G = (G<255)?G:255;
B = (B<255)?B:255;
var RR = ((R.toString(16).length==1)?"0"+R.toString(16):R.toString(16));
var GG = ((G.toString(16).length==1)?"0"+G.toString(16):G.toString(16));
var BB = ((B.toString(16).length==1)?"0"+B.toString(16):B.toString(16));
return "#"+RR+GG+BB;
}
示例减轻:
shadeColor("#63C6FF",40);
示例变暗:
shadeColor("#63C6FF",-40);
我尝试了你的函数,并且有一个小bug:如果最后一个'r'的值只有1位数字,结果就像:'a0a0a',例如右边的值是'0a0a0a'。 我只是通过添加这个来代替你的回报来快速修复它:
var rStr = (r.toString(16).length < 2)?'0'+r.toString(16):r.toString(16);
var gStr = (g.toString(16).length < 2)?'0'+g.toString(16):g.toString(16);
var bStr = (b.toString(16).length < 2)?'0'+b.toString(16):b.toString(16);
return (usePound?"#":"") + rStr + gStr + bStr;
也许它不是很好,但它做的工作。 很棒的功能,顺便说一句。 正是我需要的。 :)
链接地址: http://www.djcxy.com/p/15313.html上一篇: Programmatically Lighten or Darken a hex color (or rgb, and blend colors)