2012-09-01 24 views
12

Tôi đang làm việc trên dự án cửa hàng động và tôi sử dụng vòng lặp để in tất cả các tùy chọn màu cho sản phẩm làm hộp màu, tuy nhiên tôi thực sự cần thêm "đường viền" vào các màu này đó là ánh sáng. Tôi cố gắng một cái gì đó như sau nhưng Nó là rất hạn chế, nó thực sự giới hạn màu trắng duy nhất, nó sẽ không bắt cái gì đó như #ddd, #eea ... vvLàm cách nào để phát hiện màu "ánh sáng" với PHP

Đây là vòng lặp của tôi:

foreach($colors as $color) { 
       $color = trim($color); 
       if (!empty($color)) { 
        if (in_array($color, array('white','White','#fff','#FFF','#FFFFFF','#ffffff'))) { 
         $bordercolor = '#bbb'; 
        } else { 
         $bordercolor = $color; 
        } 
       } 
    } 

Màu sắc là một mảng từ chương trình phụ trợ như: Trắng, # 000, # cc0000, v.v. Không thực tế để thêm tất cả ngoại lệ trong điều kiện if/else nữa, bất kỳ ý tưởng nhanh nào?

+7

Google cho ' RGB TO HSV (HSL) '- Giá trị bão hòa Hue (Độ sáng). Giá trị độ sáng cao hơn là màu sáng hơn. – Peter

+0

Câu hỏi này có thể giúp bạn: [RGB to HSV in PHP] (http://stackoverflow.com/q/1773698/112968). Sau đó bạn có thể chỉ cần kiểm tra các giá trị của V trên một ngưỡng nhất định. – knittl

+0

http://stackoverflow.com/questions/5614011/intelligent-color-detection kiểm tra điều này –

Trả lời

13

Biến đổi màu HTML để RGB, sau đó đến Huế-Saturation-Lightnes (HSV)

<?php 

function HTMLToRGB($htmlCode) 
    { 
    if($htmlCode[0] == '#') 
     $htmlCode = substr($htmlCode, 1); 

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

    $r = hexdec($htmlCode[0] . $htmlCode[1]); 
    $g = hexdec($htmlCode[2] . $htmlCode[3]); 
    $b = hexdec($htmlCode[4] . $htmlCode[5]); 

    return $b + ($g << 0x8) + ($r << 0x10); 
    } 

function RGBToHSL($RGB) { 
    $r = 0xFF & ($RGB >> 0x10); 
    $g = 0xFF & ($RGB >> 0x8); 
    $b = 0xFF & $RGB; 

    $r = ((float)$r)/255.0; 
    $g = ((float)$g)/255.0; 
    $b = ((float)$b)/255.0; 

    $maxC = max($r, $g, $b); 
    $minC = min($r, $g, $b); 

    $l = ($maxC + $minC)/2.0; 

    if($maxC == $minC) 
    { 
     $s = 0; 
     $h = 0; 
    } 
    else 
    { 
     if($l < .5) 
     { 
     $s = ($maxC - $minC)/($maxC + $minC); 
     } 
     else 
     { 
     $s = ($maxC - $minC)/(2.0 - $maxC - $minC); 
     } 
     if($r == $maxC) 
     $h = ($g - $b)/($maxC - $minC); 
     if($g == $maxC) 
     $h = 2.0 + ($b - $r)/($maxC - $minC); 
     if($b == $maxC) 
     $h = 4.0 + ($r - $g)/($maxC - $minC); 

     $h = $h/6.0; 
    } 

    $h = (int)round(255.0 * $h); 
    $s = (int)round(255.0 * $s); 
    $l = (int)round(255.0 * $l); 

    return (object) Array('hue' => $h, 'saturation' => $s, 'lightness' => $l); 
    } 

$colour = '#F12346'; 
$rgb = HTMLToRGB($colour); 
$hsl = RGBToHSL($rgb); 

var_dump($hsl); 

Cách sử dụng:

$colour = '#F12346'; 
$rgb = HTMLToRGB($colour); 
$hsl = RGBToHSL($rgb); 
if($hsl->lightness > 200) { 
    // this is light colour! 
} 

Nguồn:

Demo:

+0

ý nghĩa của << nghĩa là gì? – Scramble

+0

có tiềm năng để tối ưu hóa giải pháp lạ mắt này. nghĩa là # FFFC00 (màu vàng sáng bóng) sẽ không được phát hiện dưới dạng màu sáng trên 150 –

6

Điều tôi muốn làm trong trường hợp này là phát hiện độ sáng của màu sắc bằng cách sử dụng HSL và so sánh với một tỷ lệ nhất định. Ví dụ, các thuộc tính nhẹ nhàng trong thuật toán HSL lấy chroma (M - m trong đó M là giá trị RGB lớn nhất và m là giá trị RGB nhỏ nhất) và chia rằng bằng 2.

function lightness($R = 255, $G = 255, $B = 255) { 
    return (max($R, $G, $B) + min($R, $G, $B))/510.0; // HSL algorithm 
} 

Chức năng trên sẽ trở lại một tỷ lệ phần trăm của màu sắc ánh sáng mà bạn đã chọn là (đơn giản hex -> chuyển đổi rgb là cần thiết cho điều này cũng có, nhưng điều đó nên được khá dễ dàng). Lý do tôi chia cho 510 thay vì 2 là vì để có được tỷ lệ phần trăm sau khi chia cho 2, bạn chia cho 255. Để làm cho nó nhanh hơn, bạn có thể chỉ cần nói: (x/2)/255 = x/510. Sau đó, tôi so sánh giá trị được trả về bởi hàm trên, ví dụ, 80%.

$r = hexdec($hex[0].$hex[1]); 
$g = hexdec($hex[2].$hex[3]); 
$b = hexdec($hex[4].$hex[5]); 

if(lightness($r, $g, $b) >= .8) { 
    // add border 
} else { 
    // no border 
} 
+0

Giải pháp tuyệt vời. Chỉ muốn chỉ ra cho những người khác rằng giá trị '$ hex' không nên có' # '; ví dụ: '$ hex = 'aaaaaa';'; – Alvaro

+0

Giải pháp tuyệt vời thực sự! – ChristianG

4

Ngoài công thức khác được đưa ra bởi câu trả lời khác, bạn có thể muốn xem xét Luma.

function luma($r, $g, $b) 
{ 
    return (0.2126 * $r + 0.7152 * $g + 0.0722 * $b)/255; 
} 

$l = luma(0, 15, 255); 

Giá trị gần bằng 0 sẽ tối hơn. Giá trị gần bằng 1 sẽ nhẹ hơn.

0

Ngoài ra còn có một cách đơn giản với mã thậm chí còn ít:

<?php 
//Functions 

function getRGB($colorCode) { 
    //Turn html color code into RGB 
    $var_R = substr($colorCode, 0, 2); 
    $var_G = substr($colorCode, 2, 2); 
    $var_B = substr($colorCode, 4, 2); 

    //Get Hex values 
    $val_R = hexdec($var_R); 
    $val_G = hexdec($var_G); 
    $val_B = hexdec($var_B); 

    //Red is seen as light too, gets fixed with this 
    $remRed = hexdec('99'); 
    if ($val_R > $remRed) { 
     $RGB = $val_G.' '.$val_B; 
    } else { 
     $RGB = $val_R.' '.$val_G.' '.$val_B; 
    } 

    return $RGB; 
} 

function getHSL($R = 255, $G = 255, $B = 255) { 
    $hsl = (max($R, $G, $B) + min($R, $G, $B))/510.0; 
    return $hsl; 
} 
?> 

Bây giờ gọi điện thoại:

$color = 0000FF; //Blue 
$RGBcode = getRGB($color); //Returns 0 0 255 
$RGBcode = str_replace(' ', ', ', $RGBcode); //Replaces an empty space with a , 
$val_HSL = getHSL($RGBcode); //Returns value from 0.5 to 1 
if ($val_HSL >= 0.8) { 
    //Reject color 
} else { 
    //Accept Color 
    $color = '#'.$color; //Sets it to html: #0000FF 
} 
0

cách ngắn nếu bạn có màu RGB:

$hex = "4488BB"; 
if(hexdec(substr($hex,0,2))+hexdec(substr($hex,2,2))+hexdec(substr($hex,4,2))> 382){ 
    //bright color 
}else{ 
    //dark color 
} 
Các vấn đề liên quan