如何用PHP生成更浅/更深的颜色?

eni*_*eni 49 html css php colors

例如,我有一些颜色的十六进制值#202010.

如何在PHP中以百分比(即20%更暗)生成更亮或更暗的新颜色 ?

Tor*_*sen 121

按照Frxstrem给出的示例,按百分比调整颜色并不理想.

如果你的颜色是黑色(RGB为0,0,0),你将乘以零,这根本不会产生任何变化.如果您的颜色是深灰色(例如RGB中的2,2,2),则必须减轻50%才能向上移动到(3,3,3).另一方面,如果你的RGB颜色为(100,100,100),那么50%的调整会使你达到(150,150,150),相比之下这是一个更大的变化.

一个更好的解决方案是按步骤/数字(0-255)而不是百分比进行调整,例如像这样(PHP代码):

编辑2014-01-06:稍微清理一下代码.

function adjustBrightness($hex, $steps) {
    // Steps should be between -255 and 255. Negative = darker, positive = lighter
    $steps = max(-255, min(255, $steps));

    // Normalize into a six character long hex string
    $hex = str_replace('#', '', $hex);
    if (strlen($hex) == 3) {
        $hex = str_repeat(substr($hex,0,1), 2).str_repeat(substr($hex,1,1), 2).str_repeat(substr($hex,2,1), 2);
    }

    // Split into three parts: R, G and B
    $color_parts = str_split($hex, 2);
    $return = '#';

    foreach ($color_parts as $color) {
        $color   = hexdec($color); // Convert to decimal
        $color   = max(0,min(255,$color + $steps)); // Adjust color
        $return .= str_pad(dechex($color), 2, '0', STR_PAD_LEFT); // Make two char hex code
    }

    return $return;
}
Run Code Online (Sandbox Code Playgroud)

  • 这些步骤不能简单地同等地添加到每个颜色值,因为这将改变您正在使用的颜色的阴影.为了保持相同的颜色阴影,这是期望的结果,它必须是R,G和B值的小数部分.这看起来像:`$ r = max(0,min(255,$ r +($ r*($ steps/255)))); (6认同)
  • 您对为什么乘以百分比是错误的解释恰好是当您将亮度 (HSB) 设置为可变并将滑块从暗到亮上下擦洗时,Photoshop 如何更改其颜色。试试看。设置 RGB=(127,127,1) 并且当您从 0 亮度擦洗到 100 亮度时,B 保持在 0-2 的范围内。 (2认同)
  • 谢谢!我只是改变了开头,所以你可以使用百分比而不是 -255 或 255。`function adjustBrightness($hex, $percent, $darken = true) { $brightness = $darken ? -255:255;$steps = $percent*$brightness/100; ……`。用法:`adjustBrightness('#c2002f', 10, false )` 这将使我的颜色变亮。 (2认同)

小智 25

答案是对的.

使用RGB模型是一个概念错误.

您需要将颜色从RGB(或十六进制形式)转换为HSL.

那就是Hue,Saturation,Lightness.

一旦将其从RGB转换为HSL,为了减轻颜色,您只需将L值(亮度)调整10%即可.然后,一旦完成,您将从HSL转换回RGB,您就完成了.

瞧!

PHP中的RGB到HSV


Frx*_*rem 22

这是一个例子:

<?php
$color = '#aabbcc'; // The color we'll use
Run Code Online (Sandbox Code Playgroud)

提取颜色.我更喜欢使用正则表达式,尽管可能还有其他更有效的方法.

if(!preg_match('/^#?([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i', $color, $parts))
  die("Not a value color");
Run Code Online (Sandbox Code Playgroud)

现在我们有红色$parts[1],绿色$parts[2]和蓝色$parts[3].现在,让我们将它们从十六进制转换为整数:

$out = ""; // Prepare to fill with the results
for($i = 1; $i <= 3; $i++) {
  $parts[$i] = hexdec($parts[$i]);
Run Code Online (Sandbox Code Playgroud)

然后我们将减少20%:

  $parts[$i] = round($parts[$i] * 80/100); // 80/100 = 80%, i.e. 20% darker
  // Increase or decrease it to fit your needs
Run Code Online (Sandbox Code Playgroud)

现在,我们将它们变回十六进制并将它们添加到输出字符串中

  $out .= str_pad(dechex($parts[$i]), 2, '0', STR_PAD_LEFT);
}
Run Code Online (Sandbox Code Playgroud)

然后只需在字符串的开头添加一个"#",就是这样!


mal*_*yas 15

Torkil Johnsen的答案基于固定的步骤,该步骤不仅会操纵亮度,还会稍微改变色相。正如Torkil Johnsen指出的那样,Frxstrem的方法也有缺陷。

我从Github注释中采用了这种方法,并改进了代码。它适用于任何情况。

/**
 * Increases or decreases the brightness of a color by a percentage of the current brightness.
 *
 * @param   string  $hexCode        Supported formats: `#FFF`, `#FFFFFF`, `FFF`, `FFFFFF`
 * @param   float   $adjustPercent  A number between -1 and 1. E.g. 0.3 = 30% lighter; -0.4 = 40% darker.
 *
 * @return  string
 */
function adjustBrightness($hexCode, $adjustPercent) {
    $hexCode = ltrim($hexCode, '#');

    if (strlen($hexCode) == 3) {
        $hexCode = $hexCode[0] . $hexCode[0] . $hexCode[1] . $hexCode[1] . $hexCode[2] . $hexCode[2];
    }

    $hexCode = array_map('hexdec', str_split($hexCode, 2));

    foreach ($hexCode as & $color) {
        $adjustableLimit = $adjustPercent < 0 ? $color : 255 - $color;
        $adjustAmount = ceil($adjustableLimit * $adjustPercent);

        $color = str_pad(dechex($color + $adjustAmount), 2, '0', STR_PAD_LEFT);
    }

    return '#' . implode($hexCode);
}
Run Code Online (Sandbox Code Playgroud)

这是一个示例结果:

例


pge*_*e70 5

我对此很感兴趣,但我的问题是如何为颜色添加不透明度

我想要一种褪色的颜色,而不是变浅。我发现这个:http : //www.gidnetwork.com/b-135.html 并且它工作得很好 - 从原始站点发布的代码供 SO 读者使用。

function color_blend_by_opacity( $foreground, $opacity, $background=null )
{
    static $colors_rgb=array(); // stores colour values already passed through the hexdec() functions below.
    $foreground = str_replace('#','',$foreground);
    if( is_null($background) )
        $background = 'FFFFFF'; // default background.

    $pattern = '~^[a-f0-9]{6,6}$~i'; // accept only valid hexadecimal colour values.
    if( !@preg_match($pattern, $foreground)  or  !@preg_match($pattern, $background) )
    {
        trigger_error( "Invalid hexadecimal colour value(s) found", E_USER_WARNING );
        return false;
    }

    $opacity = intval( $opacity ); // validate opacity data/number.
    if( $opacity>100  || $opacity<0 )
    {
        trigger_error( "Opacity percentage error, valid numbers are between 0 - 100", E_USER_WARNING );
        return false;
    }

    if( $opacity==100 )    // $transparency == 0
        return strtoupper( $foreground );
    if( $opacity==0 )    // $transparency == 100
        return strtoupper( $background );
    // calculate $transparency value.
    $transparency = 100-$opacity;

    if( !isset($colors_rgb[$foreground]) )
    { // do this only ONCE per script, for each unique colour.
        $f = array(  'r'=>hexdec($foreground[0].$foreground[1]),
                     'g'=>hexdec($foreground[2].$foreground[3]),
                     'b'=>hexdec($foreground[4].$foreground[5])    );
        $colors_rgb[$foreground] = $f;
    }
    else
    { // if this function is used 100 times in a script, this block is run 99 times.  Efficient.
        $f = $colors_rgb[$foreground];
    }

    if( !isset($colors_rgb[$background]) )
    { // do this only ONCE per script, for each unique colour.
        $b = array(  'r'=>hexdec($background[0].$background[1]),
                     'g'=>hexdec($background[2].$background[3]),
                     'b'=>hexdec($background[4].$background[5])    );
        $colors_rgb[$background] = $b;
    }
    else
    { // if this FUNCTION is used 100 times in a SCRIPT, this block will run 99 times.  Efficient.
        $b = $colors_rgb[$background];
    }

    $add = array(    'r'=>( $b['r']-$f['r'] ) / 100,
                     'g'=>( $b['g']-$f['g'] ) / 100,
                     'b'=>( $b['b']-$f['b'] ) / 100    );

    $f['r'] += intval( $add['r'] * $transparency );
    $f['g'] += intval( $add['g'] * $transparency );
    $f['b'] += intval( $add['b'] * $transparency );

    return sprintf( '%02X%02X%02X', $f['r'], $f['g'], $f['b'] );
}
Run Code Online (Sandbox Code Playgroud)