这是一个我正在工作的函数,以编程方式使十六进制颜色变亮或变暗。只需要传入一个像“3F6D2A”这样的字符串来表示颜色(col),并传入一个base10整数(amt)来表示要变亮或变暗的量。为了变暗,传入一个负数(即-20)。

我这么做的原因是,到目前为止,我找到的所有解决方案似乎都把问题复杂化了。我有一种感觉,只需几行代码就可以完成。请让我知道,如果你发现任何问题,或有任何调整,以加快它。

有趣的灯光 上校(16号); return键(col . & 0x0000FF) + amt) | ((((col > > 8) & 0x00FF) + amt) < < 8) | (16 (col > >) + amt) < < 16) . toString (16); 的 / /测试 控制台(照明颜色(“3F6D2A”,40);

对于开发人员来说,这里有一个更容易阅读的版本:

函数 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 新颜色 = g |(b << 8) |(第16<<条); 返回 newColor.toString(16); } 测试 console.log(LightenDarkenColor(“3F6D2A”, -40));

最后一个版本可以处理开头可能有(也可能没有)“#”的颜色。加上调整不适当的颜色值:

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);

我想我的主要问题是,我说的对吗?这不是包括大多数(正常)情况吗?如果是的话,最快最小的方法是什么?我想在动画和小环境中使用,所以速度是这里的第一个最重要的因素,尺寸第二,准确性第三,可读性?嗯?不在要求清单上(对不起,我知道你们中有一半人正在泪眼汪汪!)


当前回答

如何简单的阴影颜色在PHP?

<?php
function shadeColor ($color='#cccccc', $percent=-25) {

  $color = Str_Replace("#",Null,$color);

  $r = Hexdec(Substr($color,0,2));
  $g = Hexdec(Substr($color,2,2));
  $b = Hexdec(Substr($color,4,2));

  $r = (Int)($r*(100+$percent)/100);
  $g = (Int)($g*(100+$percent)/100);
  $b = (Int)($b*(100+$percent)/100);

  $r = Trim(Dechex(($r<255)?$r:255));  
  $g = Trim(Dechex(($g<255)?$g:255));  
  $b = Trim(Dechex(($b<255)?$b:255));

  $r = ((Strlen($r)==1)?"0{$r}":$r);
  $g = ((Strlen($g)==1)?"0{$g}":$g);
  $b = ((Strlen($b)==1)?"0{$b}":$b);

  return (String)("#{$r}{$g}{$b}");
}

echo shadeColor(); // #999999

其他回答

你考虑过RGB > HSL转换吗?然后上下移动亮度?这就是我要走的路。

快速查找一些算法得到了以下网站。

PHP: http://serennu.com/colour/rgbtohsl.php

Javascript: http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript

编辑以上链接不再有效。你可以查看git hub的页面源或要旨

或者,另一个StackOverflow问题可能是一个好地方。


尽管这不是OP的正确选择,但以下是我最初建议的代码的近似值。(假设你有rgb/hsl转换函数)

var SHADE_SHIFT_AMOUNT = 0.1; 

function lightenShade(colorValue)
{
    if(colorValue && colorValue.length >= 6)
    {
        var redValue = parseInt(colorValue.slice(-6,-4), 16);
        var greenValue = parseInt(colorValue.slice(-4,-2), 16);
        var blueValue = parseInt(colorValue.slice(-2), 16);

        var hsl = rgbToHsl(redValue, greenValue, blueValue);
        hsl[2]= Math.min(hsl[2] + SHADE_SHIFT_AMOUNT, 1);
        var rgb = hslToRgb(hsl[0], hsl[1], hsl[2]);
        return "#" + rgb[0].toString(16) + rgb[1].toString(16) + rgb[2].toString(16);
    }
    return null;
}

function darkenShade(colorValue)
{
    if(colorValue && colorValue.length >= 6)
    {
        var redValue = parseInt(colorValue.slice(-6,-4), 16);
        var greenValue = parseInt(colorValue.slice(-4,-2), 16);
        var blueValue = parseInt(colorValue.slice(-2), 16);

        var hsl = rgbToHsl(redValue, greenValue, blueValue);
        hsl[2]= Math.max(hsl[2] - SHADE_SHIFT_AMOUNT, 0);
        var rgb = hslToRgb(hsl[0], hsl[1], hsl[2]);
        return "#" + rgb[0].toString(16) + rgb[1].toString(16) + rgb[2].toString(16);
    }
    return null;
}

这样的假设:

你有hslToRgb和rgbToHsl函数。 参数colorValue是一个#RRGGBB形式的字符串

虽然我们讨论的是css,但在IE9/Chrome/Firefox中有指定hsl/hsla的语法。

你的方法是可以的:)我简化了你的最短版本一点点(饱和度控制看这里)

(col,amt)=> (+('0x'+col)+amt*0x010101).toString(16).padStart(6,0)

// Similar to OP shortest version, we not have here # and colors range checking var LightenDarkenColor = (col,amt) => (+('0x'+col)+amt*0x010101).toString(16).padStart(6,0); // ------ // TEST // ------ function update() { let c= col.value.padEnd(6,'0').slice(0,6); let color = '#'+LightenDarkenColor(c, +amt.value); oldColor.innerHTML = 'Old: #'+c; oldColor.style = `background: #${c}`; newColor.innerHTML = 'New: '+color newColor.style = `background: ${color}`; } update(); .box{ width: 100px; height: 100px; margin: 10px; display: inline-block} <input id="col" value="3F6D2A" oninput="update()"> <input id="amt" value="30" oninput="update()"><br> <div id="oldColor" class="box"></div> <div id="newColor" class="box"></div>

和版本#和颜色范围检查

// # and colors range checking var LightenDarkenColor = (col,amt) => '#'+col.slice(1).match(/../g) .map(x=>(x=+`0x${x}`+amt,x<0?0:(x>255?255:x)) .toString(16).padStart(2,0)).join``; // ------ // TEST // ------ function update() { let c= col.value.padEnd(6,'0').slice(0,7); let color = LightenDarkenColor(c, +amt.value); oldColor.innerHTML = 'Old: '+c; oldColor.style = `background: ${c}`; newColor.innerHTML = 'New: '+color newColor.style = `background: ${color}`; } update(); .box{ width: 100px; height: 100px; margin: 10px; display: inline-block} <input id="col" value="#3F6D2A" oninput="update()"> <input id="amt" value="40" oninput="update()"><br> <div id="oldColor" class="box"></div> <div id="newColor" class="box"></div>

我的版本写在typescript:

function changeColorLightness(color: number, lightness: number): number {
    return (Math.max(0, Math.min(((color & 0xFF0000) / 0x10000) + lightness, 0xFF)) * 0x10000) +
        (Math.max(0, Math.min(((color & 0x00FF00) / 0x100) + lightness, 0xFF)) * 0x100) +
        (Math.max(0, Math.min(((color & 0x0000FF)) + lightness, 0xFF)));
}

解释:

export function changeColorLightness(color: number, lightness: number): number {
    const r = (color & 0xFF0000) / 0x10**4;
    const g = (color & 0x00FF00) / 0x10**2;
    const b = (color & 0x0000FF);

    const changedR = Math.max(0, Math.min(r + lightness, 0xFF));
    const changedG = Math.max(0, Math.min(g + lightness, 0xFF));
    const changedB = Math.max(0, Math.min(b + lightness, 0xFF));

    return (changedR * 0x10**4) + (changedG * 0x10**2) + changedB;
}

用法:

changeColorLightness(0x00FF00, 0x50);
changeColorLightness(parseInt("#00FF00".replace('#',''), 16), 0x50);
changeColorLightness(0x00FF00, 127.5);

c#版本…… 注意,我得到的颜色字符串的格式是#FF12AE34,需要剪掉#FF。

    private string GetSmartShadeColorByBase(string s, float percent)
    {
        if (string.IsNullOrEmpty(s))
            return "";
        var r = s.Substring(3, 2);
        int rInt = int.Parse(r, NumberStyles.HexNumber);
        var g = s.Substring(5, 2);
        int gInt = int.Parse(g, NumberStyles.HexNumber);
        var b = s.Substring(7, 2);
        int bInt = int.Parse(b, NumberStyles.HexNumber);

        var t = percent < 0 ? 0 : 255;
        var p = percent < 0 ? percent*-1 : percent;

        int newR = Convert.ToInt32(Math.Round((t - rInt) * p) + rInt);
        var newG = Convert.ToInt32(Math.Round((t - gInt) * p) + gInt);
        var newB = Convert.ToInt32(Math.Round((t - bInt) * p) + bInt);

        return String.Format("#{0:X2}{1:X2}{2:X2}", newR, newG, newB);
    }

下面的方法将允许您使十六进制(Hex)颜色字符串的曝光值变亮或变暗:

private static string GetHexFromRGB(byte r, byte g, byte b, double exposure)
{
    exposure = Math.Max(Math.Min(exposure, 1.0), -1.0);
    if (exposure >= 0)
    {
        return "#"
            + ((byte)(r + ((byte.MaxValue - r) * exposure))).ToString("X2")
            + ((byte)(g + ((byte.MaxValue - g) * exposure))).ToString("X2")
            + ((byte)(b + ((byte.MaxValue - b) * exposure))).ToString("X2");
    }
    else
    {
        return "#"
            + ((byte)(r + (r * exposure))).ToString("X2")
            + ((byte)(g + (g * exposure))).ToString("X2")
            + ((byte)(b + (b * exposure))).ToString("X2");
    }

}

对于GetHexFromRGB()中的最后一个参数值,传递一个介于-1和1之间的双值(-1为黑色,0不变,1为白色):

// split color (#e04006) into three strings
var r = Convert.ToByte("e0", 16);
var g = Convert.ToByte("40", 16);
var b = Convert.ToByte("06", 16);

GetHexFromRGB(r, g, b, 0.25);  // Lighten by 25%;