2013-09-21 3 views
-2

Итак, я сделал этот скрипт, который получает наиболее часто используемый цвет в изображении. Проблема в том, что они меня закодировали, что делает ее очень бесполезной.Увеличьте производительность этого скрипта

Сценарий может найти только цвет на небольшом изображении. Большие создают эту ошибку:

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 36 bytes) 

Я вставляю значение HEX каждого пикселя в массив. Это проблема, как мне это сделать, чтобы не добираться до больших массивов?

Сценарий:

$im = imagecreatefromjpeg("images/2.jpg"); 

function common($img) { 
    $w = imagesx($img); 
    $h = imagesy($img); 
    $r = $g = $b = 0; 
    $count = 0; 

    $array = array(); 

    for($y = 0; $y < $h; $y++) { 
     for($x = 0; $x < $w; $x++) { 
      $rgb = imagecolorat($img, $x, $y); 
      $r += $rgb >> 16; 
      $g += $rgb >> 8 & 255; 
      $b += $rgb & 255; 
      $hex = "#"; 
      $hex.= str_pad(dechex($r), 2, "0", STR_PAD_LEFT); 
      $hex.= str_pad(dechex($g), 2, "0", STR_PAD_LEFT); 
      $hex.= str_pad(dechex($b), 2, "0", STR_PAD_LEFT); 
      $array[$count++] = $hex; 
     } 
    } 

    $result = array_count_values($array); 
    asort($result); 
    end($result); 
    $answer = key($result); 

    return $answer; 
} 

$common = common($im); 
echo $common; 
+0

Ошибка просто означает, что у PHP закончилась нехватка памяти. Работа с изображениями занимает довольно много памяти. Вы можете увеличить память, которую PHP может использовать [в вашем файле php.ini] (http://php.net/manual/en/ini.core.php#ini.sect.resource-limits). –

+1

Не поймите, почему этот парень получает -4. Ошибка не очень распространенная, и вопрос довольно сформулирован, хотя вопрос вроде как: «Сделай это для меня», но все же не плохая ошибка. – Loko

ответ

0

Вместо сохранения каждого пикселя в массиве, почему бы не вставить только один элемент для каждого другого цвета со счетчиком? Что-то вроде:

if (!isset($array[$hex])) 
{ 
    $array[$hex] = 1; 
} 
else 
{ 
    $array[$hex]++; 
} 

Таким образом, вы могли бы просто найти цвет в массиве с наибольшим кол:

$highest_hex = ""; 
$highest_count = 0; 
foreach($array AS $hex => $count) 
{ 
    if ($count > $highest_count) 
    { 
     $highest_hex = $hex; 
     $highest_count = $count; 
    } 
} 

echo "The most used color has hex code {$highest_hex} and was used {$highest_count} times."; 

Это словарь-подобный (ключ-значение) подход. Обратите внимание, что этот массив будет меньше вашего, в среднем, но его худший случай будет такой же длины, как ваш (когда все пиксели имеют разный цвет без повторений). В этом случае первый цвет, найденный на изображении (первый пиксель в верхнем левом углу), будет считаться «наиболее используемым».

0

Более эффективным для памяти способом сделать это было бы создание массива, содержащего цвета в документе, и приращения цвета каждый раз, когда он будет виден.

В псевдокоде:

$colors=array(); 
for(;$i<count($pixels);$i++){ 
    $pixel=$pixels[$i]; 
    if(isset($colors[getcolor($pixels[$i])]){ 
     $colors[getcolor($pixels[$i]++; 
    }else{ 
     $colors[getcolor($pixels[$i]=1; 
    } 
} 

, а затем получить элемент массива с наибольшим числом.

Смежные вопросы