2010-08-12 27 views
42

我有一個jpg圖像。檢測圖片的「整體平均」顏色

我需要知道「整體平均」圖像的顏色。乍一看,可以使用圖像的直方圖(通道RGB)。

在工作中,我主要使用JavaScript和PHP(一個小Python),因此歡迎這些語言的決定。也許它是用於處理類似問題的圖像的庫。

我不需要動態確定圖片的顏色。我只需要瀏覽整個圖像陣列並分別確定每個圖像的顏色(我將記住這些信息供將來使用)。

+1

JS無法訪問二進制圖像的顏色信息 – mplungjan 2010-08-12 14:05:39

+0

@mplungjan,有這樣一個JavaScript庫'http:// www.pixastic.com/lib/docs /',它們以某種方式獲取有關顏色的信息。還是我誤會了? – Kalinin 2010-08-12 14:08:14

+1

他們使用新的'Canvas'元素。 – 2010-08-12 14:11:46

回答

66

您可以使用PHP 得到調色板的數組,像這樣:

<?php 
function colorPalette($imageFile, $numColors, $granularity = 5) 
{ 
    $granularity = max(1, abs((int)$granularity)); 
    $colors = array(); 
    $size = @getimagesize($imageFile); 
    if($size === false) 
    { 
     user_error("Unable to get image size data"); 
     return false; 
    } 
    $img = @imagecreatefromjpeg($imageFile); 
    // Andres mentioned in the comments the above line only loads jpegs, 
    // and suggests that to load any file type you can use this: 
    // $img = @imagecreatefromstring(file_get_contents($imageFile)); 

    if(!$img) 
    { 
     user_error("Unable to open image file"); 
     return false; 
    } 
    for($x = 0; $x < $size[0]; $x += $granularity) 
    { 
     for($y = 0; $y < $size[1]; $y += $granularity) 
     { 
     $thisColor = imagecolorat($img, $x, $y); 
     $rgb = imagecolorsforindex($img, $thisColor); 
     $red = round(round(($rgb['red']/0x33)) * 0x33); 
     $green = round(round(($rgb['green']/0x33)) * 0x33); 
     $blue = round(round(($rgb['blue']/0x33)) * 0x33); 
     $thisRGB = sprintf('%02X%02X%02X', $red, $green, $blue); 
     if(array_key_exists($thisRGB, $colors)) 
     { 
      $colors[$thisRGB]++; 
     } 
     else 
     { 
      $colors[$thisRGB] = 1; 
     } 
     } 
    } 
    arsort($colors); 
    return array_slice(array_keys($colors), 0, $numColors); 
} 
// sample usage: 
$palette = colorPalette('rmnp8.jpg', 10, 4); 
echo "<table>\n"; 
foreach($palette as $color) 
{ 
    echo "<tr><td style='background-color:#$color;width:2em;'>&nbsp;</td><td>#$color</td></tr>\n"; 
} 
echo "</table>\n"; 

它給你一個數組,其值是如何往往是顏色已經使用更高。

編輯 一個評論者被問及如何在目錄中使用的所有文件,那就是:

if ($handle = opendir('./path/to/images')) { 

     while (false !== ($file = readdir($handle))) { 
      $palette = colorPalette($file, 10, 4); 
      echo "<table>\n"; 
      foreach($palette as $color) { 
       echo "<tr><td style='background-color:#$color;width:2em;'>&nbsp;</td><td>#$color</td></tr>\n"; 
      } 
      echo "</table>\n"; 
     } 
     closedir($handle); 
    } 

可能不希望這樣做太多的文件,但它是你的服務器。

或者,如果您願意使用JavascriptLokesh's Color-Theif圖書館完全符合您的要求。

+1

讓它轟!改變'$ img = @imagecreatefromgif($ imageFile);'到'$ img = @imagecreatefromstring(file_get_contents($ imageFile));'你現在可以處理不同的圖像類型... – Andres 2012-02-07 16:21:50

+0

改變的代碼實際上是'@imagecreatefromjpeg ($ imageFile);'它現在假設你使用jpgs。 – JKirchartz 2012-02-07 18:42:05

+0

糟糕!感謝@JKirchartz捕捉我的瘋狂。偉大的代碼順便說一下! – Andres 2012-02-08 15:51:46

2

真彩色圖像更短的溶液。將其縮小以1x1像素大小,並在該像素採樣的顏色:

$縮放= imagescale($ IMG,1,1, IMG_BICUBIC); $ meanColor = imagecolorat($ img,0,0);

...但我沒有自己測試過。

+0

幫助有趣,但需要進行測試。 – Kalinin 2013-07-15 06:49:35

+0

@Kalinin它被測試,請參閱[這裏](http://stackoverflow.com/a/1746564/3075942)。 – user 2014-03-22 14:07:46

+0

注意,這需要PHP與GD庫編譯 – 2015-06-12 21:27:14

4

結合JKirchartz和亞歷山大Hugestrand答案:

function getAverage($sourceURL){ 

    $image = imagecreatefromjpeg($sourceURL); 
    $scaled = imagescale($image, 1, 1, IMG_BICUBIC); 
    $index = imagecolorat($scaled, 0, 0); 
    $rgb = imagecolorsforindex($scaled, $index); 
    $red = round(round(($rgb['red']/0x33)) * 0x33); 
    $green = round(round(($rgb['green']/0x33)) * 0x33); 
    $blue = round(round(($rgb['blue']/0x33)) * 0x33); 
    return sprintf('#%02X%02X%02X', $red, $green, $blue); 
} 

屢試不爽,返回十六進制字符串。

+0

爲什麼要整理它?根據我的經驗,不捨入它可以提供更精確的結果,只需'''返回sprintf('#%02X%02X%02X',$ rgb ['red'],$ rgb ['green'],$ rgb [''藍色']);''' – Kevin 2016-09-26 05:17:11

+0

@凱文將不得不嘗試一下 - 謝謝你的提升。 – 2016-09-28 08:34:34

+0

這並不總是適合我 – Pons 2017-03-05 10:32:31

0

我創建了composer軟件包,該軟件包提供了用於通過路徑從給定圖像中選取平均顏色的庫。

你可以通過你的項目目錄中運行以下命令進行安裝:

composer require tooleks/php-avg-color-picker 

用例:

<?php 

use Tooleks\Php\AvgColorPicker\Gd\AvgColorPicker; 

$imageAvgHexColor = (new AvgColorPicker)->getImageAvgHexByPath('/absolute/path/to/the/image.(jpg|jpeg|png|gif)'); 

// The `$imageAvgHexColor` variable contains the average color of the given image in HEX format (#fffff). 

documentation

1
$img = glob('img/*'); 
foreach ($img as $key => $value) { 
    $info = getimagesize($value); 
    $mime = $info['mime']; 
    switch ($mime) { 
     case 'image/jpeg': 
      $image_create_func = 'imagecreatefromjpeg'; 
      break; 
     case 'image/png': 
      $image_create_func = 'imagecreatefrompng'; 
      break; 
     case 'image/gif': 
      $image_create_func = 'imagecreatefromgif'; 
      break; 
    } 
    $avg = $image_create_func($value); 
    list($width, $height) = getimagesize($value); 
    $tmp = imagecreatetruecolor(1, 1); 
    imagecopyresampled($tmp, $avg, 0, 0, 0, 0, 1, 1, $width, $height); 
    $rgb = imagecolorat($tmp, 0, 0); 
    $r = ($rgb >> 16) & 0xFF; 
    $g = ($rgb >> 8) & 0xFF; 
    $b = $rgb & 0xFF; 
    echo '<div style="text-align:center; vertical-align: top; display:inline-block; width:100px; height:150px; margin:5px; padding:5px; background-color:rgb('.$r.','.$g.','.$b.');">'; 
    echo '<img style="width:auto; max-height:100%; max-width: 100%; vertical-align:middle; height:auto; margin-bottom:5px;" src="'.$value.'">'; 
    echo '</div>'; 

你可以得到的平均顏色的值與$ R,$ G,& $ B 重採樣圖像比只有它的規模更加美好!