使用PHP生成100个HTML颜色代码的列表

6
我需要一种在PHP/HTML中生成颜色列表(十六进制代码)的方法,从1到100。0为红色,100为绿色,中间每个颜色都是两者之间平滑过渡的阴影色(例如,从红色到橙色到黄色到绿色)。
因此,假设我可以将一个数字传递给它,比如数字50,它会从列表中返回一个十六进制代码(50将是黄色)。
手动分配每种颜色到一个数组中是唯一的方法吗?还是有更简单的方法?
(这个请求很奇怪 - 我已经搜索过了,但找不到类似的东西。)

4
所以...我们在这里完全忽略了蓝色吗? - Levi Morrison
1
请看这里:https://dev59.com/5HM_5IYBdhLWcg3w02z8 - Paystey
我认为你想要在HSV颜色模型上进行往返计算以计算RGB六元组。请参见PHP中的百分比转十六进制颜色 - mario
5个回答

1

最简单、最灵活的方法是使用两个函数:一个从RGB数组创建HTML十六进制值,另一个用于淡化RGB数组...

// Creates an HTML HEX color from an array of color integers array(r,g,b)...
function rgb($rgb) {
    $ret = '';
    foreach ($rgb as $x) {
        // Make sure the RGB values are 0-255...
        $x = max(0, min(255, $x));
        // create a 2 digit hex value for this color component...
        $ret .= ($x < 16 ? '0'.dechex($x) : dechex($x));
    }
    return '#'.$ret;
}

// Returns a fade of $from into $to by $amount ($from and $to are RGB arrays)...
function fade($from, $to, $amount) {
    $rgb = array();
    // Go through the RGB values and adjust the values by $amount...
    for ($i = 0; $i <= 2; $i++) {
        $rgb[$i] = (($to[$i] - $from[$i]) * $amount) + $from[$i];
    }
    return $rgb;
}

然后,您可以通过任意数量将任何颜色淡化为任何其他颜色,例如以下示例,它使用100个步骤从红色淡化到绿色...

for ($fadeAmount = 0; $fadeAmount < 1; $fadeAmount += 0.01) {
    $color = rgb(fade(array(255,0,0), array(0,255,0), $fadeAmount));
    echo "<div style='color:$color'>$fadeAmount</div>";
}

0

试一下这个:

function rgb($val){
  if($val < 0 || $val > 100)
    return; // Error!

  $r = (100 - $val)*255/50;
  if((100 - $val) > 50)
    $r = 255;
  $rr = dechex($r);
  if($r < 16)
    $rr = '0' . $rr;

  $g = ($val)*255/50;
  if((100-$val) < 50)
    $g = 255;
  $gg = dechex($g);
  if($g < 16)
    $gg = '0'.$gg;

  $bb = '00';

  return $rr . $gg . $bb;
}

以下是从0到100每隔10个数的输出值:

ff0000
ff3300
ff6600
ff9900
ffcc00
ffff00
ccff00
99ff00
66ff00
33ff00
00ff00

几乎完美地符合我的需求,谢谢。只有一个小问题,有没有办法将颜色间隔得更开一些?似乎在顶部和底部的范围内变化不大,而中间范围的变化较多。如果没有简单的方法来解决这个问题,那也没关系。 - user961882
好的,只需取 $val 并在它被处理之前进行一些数学运算。我不太确定您想要如何拉伸它,但对该变量进行修改就是答案。 - Landon
做一些类似这样的事情:如果($val<10)$val+=9; 否则如果($val<20)$val+=7; 否则如果($val<30)$val+=5; 否则如果($val<40)$val+=3; 否则如果($val<50)$val+=1; 否则如果($val<60)$val-=1; 否则如果($val<70)$val-=3; 否则如果($val<80)$val-=5; 否则如果($val<90)$val-=7; 否则如果($val<100)$val-=9;虽然不太优雅(或数学化),但这会将事物从中心拉开,可以尝试类似的东西。 - Landon
如果您对答案满意,可以给我一个向上的箭头吗? - Landon

0
无论是预先生成表格,还是每次计算一个值,或者介于两者之间,真正的复杂性在于计算RGB颜色。您需要在2个RGB代码之间使用线性插值器,并将1映射到纯红色,100映射到纯绿色。也许可以尝试以下方式:
function interpolateRGB($from, $to, $at)
{
  $col = array(0.0, 0.0, 0.0);
  for ($i=0;$i<3;++$i)
    $col[$i] = $from[$i]*(1.0-$at) + $to[i]*$at;
  return $col;
}

function convertToHexCol($col)
{
  $ret = '#';
  foreach ($col as $comp)
    $ret .= dechex(max(255,round(255.0*$comp)));
  return $ret;
}

function getColor($index)
{
  $at = (float)($index-1)/99.0;
  $from = array(1.0, 0.0, 0.0); // red
  $to = array(0.0, 1.0, 0.0);  // green
  $color = interpolateRGB($from, $to, $at);
  return convertToHexCol($col);
}

0

是的,有一种更简单的方法。可以直接通过对值范围0到255进行归一化计算得出。由于您可以在0到100之间选择一个数字,因此可以使用公式(n * 255) / 100将其缩放到0到255的范围内。完成后,确定红色、绿色、蓝色的适当值,转换为十六进制,并将结果合并为最终的十六进制颜色:

  1. 将用户输入0到100的数值存入n中。
  2. 计算归一化值norm = (n * 255) / 100
  3. 设置red255 - norm,因为它随着n的减小而减小。
  4. 设置greennorm,因为它随着n的增加而增加。
  5. blue设置为0。
  6. redgreenblue转换为十六进制并拼接成单个字符串。

这里是JavaScript的一个示例实现,展示了十六进制颜色输出,并使用该颜色对文本进行着色以进行演示:http://jsfiddle.net/zEB4J/

样例图片:

enter image description here

enter image description here

enter image description here

这是一个生成渐变的演示:http://jsfiddle.net/XMTcb/

enter image description here


谢谢,有没有办法让它通过黄色作为中心?这样基准(0)是红色,中心(50)是黄色,而顶部(100)是绿色? - user961882

0

我对php不是很了解,但你可以使用简单的数学运算来解决它,而不需要使用数组。假设x是0-100之间的数字。我们RGB中的每种颜色都必须在0和0xFF(256个可能值)之间,因此我们应该查看x/100并将其四舍五入为分母为256的分数。

换句话说,这个分数是:round((x/100)*256)/256

这是绿色(00FF00)的数量。红色(FF0000)的数量显然是:

1 - round((x/100)*256)/256

综合起来,我们得到以下值:

0xFF0000 + round((x/100)*256)/256 * (0x00FF00 - 0xFF0000)

如果x是整数,并且我们想避免整数除法舍入,则应在除法之前评估乘法:

0xFF0000 + (round((x*256)/100) * (0x00FF00 - 0xFF0000)) / 256

这就是最接近的评估方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接