2010-08-18 54 views
42

我有一些顏色的十六進制值,例如#202010如何用PHP生成較亮/較暗的顏色?

如何生成一個新的顏色,它是在PHP中用百分比(即20%較暗)給出的較亮或較暗的顏色?

+3

您已經提出過這個問題,最好嘗試實施您提供的Javascript解決方案,並對該問題發表評論,而不是開始新的問題。 – Kyle 2010-08-18 13:07:58

+0

[從PHP生成漸變顏色]可能的重複。(http://stackoverflow.com/questions/3511094/generate-gradient-color-from-php) – 2010-08-18 13:11:10

+0

如果你正在爲webapp /網站做這件事,我是認爲使用LESS或SASS和CSS或JavaScript方法將是更有效的解決方案。 但是我的觀點可能會因爲我喜歡PHP/node/C#等而傾斜​​,用於爲前端技術創建後端服務以進行交互,(而不是將它們混合成一個像舊的ASP .NET如此痛苦地做/做)。 – MER 2017-03-24 20:10:15

回答

22

下面是一個例子:

<?php 
$color = '#aabbcc'; // The color we'll use 

提取的顏色。我寧願使用正則表達式,但也可能有其他更有效的方法。

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

現在我們已經紅$parts[1],綠色$parts[2]和藍色$parts[3]。現在,讓我們將它們轉換從十六進制爲整數:

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

然後,我們將減少20%其中:

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

現在,我們把它們放回十六進制,並將其添加到我們的產量字符串

$out .= str_pad(dechex($parts[$i]), 2, '0', STR_PAD_LEFT); 
} 

然後只是在字符串的開頭添加一個「#」,就是這樣!

+1

爲此,我只是將'#'加入$ out =「」;所以它現在讀$ out =「#」; //準備填寫結果 – 2013-04-30 13:59:07

105

調整顏色的百分比,如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年1月6日: - 清理代碼一點點。

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; 
} 
+1

謝謝!今天派上用場。 – 472084 2012-12-19 11:07:50

+1

令人敬畏的工作,謝謝! – schmatz 2012-12-25 23:29:47

+1

太棒了,我在我的wordpress主題中使用了這個! – Dafen 2013-11-05 12:05:36

15

答案是錯誤的。

使用RGB模型是一個概念錯誤。

您需要將顏色從RGB(或十六進制格式)轉換爲HSL。

這就是色調,飽和度,亮度。

將其從RGB轉換爲HSL後,爲了減輕顏色,只需將L值(亮度)調整10%即可。然後一旦你完成你從HSL轉換回RGB,你就完成了。

瞧!

RGB to HSV in PHP

+3

+1提HSL – philipp 2013-10-04 04:21:52

3

我感興趣的是這個,但我的問題是如何添加一個不透明的顏色?

我想要一種顏色褪色,而不是做得更輕。我發現這個: 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([email protected]_match($pattern, $foreground) or [email protected]_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']); 
}