Обнаруживать основные цвета в изображении с помощью PHP

Я пытаюсь воспроизвести функциональность, которую Dribbble.com делает с обнаружением преобладающих цветов в изображении. На изображении ниже вы можете увидеть скриншот от Dribbble.com, который показывает 8 преобладающих цветов на изображении слева. Вот фактическая страница на картинке http://dribbble.com/shots/528033-Fresh-Easy?list=following

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

После некоторых исследований о том, как получить эти цвета из изображения, некоторые люди сказали, что вы просто просматриваете пиксель изображения по пикселям, а затем сохраняете цвета, которые больше всего встречаются. Другие говорят, что есть больше, и что получение цветов, которые существуют наиболее часто, не даст желаемого эффекта. Говорят, что вам нужно квантифицировать изображение / цвета (я теряюсь на этом этапе).

На изображении ниже снимок Dribble ниже – это библиотека Javascript, которая делает то же самое, эту страницу можно посмотреть здесь http://lokeshdhakar.com/projects/color-thief/

Просмотр источника этой страницы я вижу, что есть файл Javascript с именем quantize.js и результаты действительно хороши. Поэтому я надеюсь, что смогу сделать то, что делает библиотека Javascript, но с PHP и GD / ImageMagick

введите описание изображения здесь


Я нашел эту функцию, которая вернет цвета и подсчет в изображении с PHP, но результаты отличаются от приведенной выше версии Javascript и результатов Dribble

 /** * Returns the colors of the image in an array, ordered in descending order, where the keys are the colors, and the values are the count of the color. * * @return array */ function Get_Color() { if (isset($this->image)) { $PREVIEW_WIDTH = 150; //WE HAVE TO RESIZE THE IMAGE, BECAUSE WE ONLY NEED THE MOST SIGNIFICANT COLORS. $PREVIEW_HEIGHT = 150; $size = GetImageSize($this->image); $scale=1; if ($size[0]>0) $scale = min($PREVIEW_WIDTH/$size[0], $PREVIEW_HEIGHT/$size[1]); if ($scale < 1) { $width = floor($scale*$size[0]); $height = floor($scale*$size[1]); } else { $width = $size[0]; $height = $size[1]; } $image_resized = imagecreatetruecolor($width, $height); if ($size[2]==1) $image_orig=imagecreatefromgif($this->image); if ($size[2]==2) $image_orig=imagecreatefromjpeg($this->image); if ($size[2]==3) $image_orig=imagecreatefrompng($this->image); imagecopyresampled($image_resized, $image_orig, 0, 0, 0, 0, $width, $height, $size[0], $size[1]); //WE NEED NEAREST NEIGHBOR RESIZING, BECAUSE IT DOESN'T ALTER THE COLORS $im = $image_resized; $imgWidth = imagesx($im); $imgHeight = imagesy($im); for ($y=0; $y < $imgHeight; $y++) { for ($x=0; $x < $imgWidth; $x++) { $index = imagecolorat($im,$x,$y); $Colors = imagecolorsforindex($im,$index); $Colors['red']=intval((($Colors['red'])+15)/32)*32; //ROUND THE COLORS, TO REDUCE THE NUMBER OF COLORS, SO THE WON'T BE ANY NEARLY DUPLICATE COLORS! $Colors['green']=intval((($Colors['green'])+15)/32)*32; $Colors['blue']=intval((($Colors['blue'])+15)/32)*32; if ($Colors['red']>=256) $Colors['red']=240; if ($Colors['green']>=256) $Colors['green']=240; if ($Colors['blue']>=256) $Colors['blue']=240; $hexarray[]=substr("0".dechex($Colors['red']),-2).substr("0".dechex($Colors['green']),-2).substr("0".dechex($Colors['blue']),-2); } } $hexarray=array_count_values($hexarray); natsort($hexarray); $hexarray=array_reverse($hexarray,true); return $hexarray; } else die("You must enter a filename! (\$image parameter)"); } 

Поэтому я спрашиваю, знает ли кто, как я могу сделать такую ​​задачу с PHP? Возможно, что-то уже существует, что вы знаете или какие-либо советы, чтобы поставить меня на шаг ближе к этому, было бы оценено

Related of "Обнаруживать основные цвета в изображении с помощью PHP"

Вот именно то, что вы ищете в PHP: https://github.com/thephpleague/color-extractor

Пример :

 require 'vendor/autoload.php'; use League\ColorExtractor\Client as ColorExtractor; $client = new ColorExtractor; $image = $client->loadPng('./some/image.png'); // Get the most used color hexadecimal codes from image.png $palette = $image->extract(); 

Это мой простой способ получить основной цвет изображения

 <?php $image=imagecreatefromjpeg('image.jpg'); $thumb=imagecreatetruecolor(1,1); imagecopyresampled($thumb,$image,0,0,0,0,1,1,imagesx($image),imagesy($image)); $mainColor=strtoupper(dechex(imagecolorat($thumb,0,0))); echo $mainColor; ?> 

Вам нужно уменьшить масштаб изображения, и вы получите основные цвета изображения. Если вам нужно 4 цвета в поддоне, уменьшите его до примерно 8x8 , 6 цветов примерно до 12x8 и так далее …

imagecopyresized для уменьшенного изображения, затем проверяет каждый пиксель и сохраняет их в массиве imagecolorat($image,px,py)

Попробуйте это

 <?php // EXAMPLE PICTURE $url='http://img.ruphp.com/php/google.jpg'; //var_dump(getColorPallet($url)); echoColors(getColorPallet($url)); function echoColors($pallet){ // OUTPUT COLORSBAR foreach ($pallet as $key=>$val) echo '<div style="display:inline-block;width:50px;height:20px;background:#'.$val.'"> </div>'; } function getColorPallet($imageURL, $palletSize=[16,8]){ // GET PALLET FROM IMAGE PLAY WITH INPUT PALLET SIZE // SIMPLE CHECK INPUT VALUES if(!$imageURL) return false; // IN THIS EXEMPLE WE CREATE PALLET FROM JPG IMAGE $img = imagecreatefromjpeg($imageURL); // SCALE DOWN IMAGE $imgSizes=getimagesize($imageURL); $resizedImg=imagecreatetruecolor($palletSize[0],$palletSize[1]); imagecopyresized($resizedImg, $img , 0, 0 , 0, 0, $palletSize[0], $palletSize[1], $imgSizes[0], $imgSizes[1]); imagedestroy($img); //CHECK IMAGE /*header("Content-type: image/png"); imagepng($resizedImg); die();*/ //GET COLORS IN ARRAY $colors=[]; for($i=0;$i<$palletSize[1];$i++) for($j=0;$j<$palletSize[0];$j++) $colors[]=dechex(imagecolorat($resizedImg,$j,$i)); imagedestroy($resizedImg); //REMOVE DUPLICATES $colors= array_unique($colors); return $colors; } ?> 

Прекрасно подходит для меня.

На странице, на которую вы ссылались, есть ссылка на исходный код GitHub, поэтому, если вы хотите точно знать, как они это делают, вы можете реплицировать свой источник в PHP.

Большая разница между тем, как они это делают и как вы это делаете, заключается в том, что они используют кластеризацию для поиска цвета. Вместо округления цвета при их хранении они сохраняют все необработанные цвета в массиве. Затем они перемещаются по этому массиву, пока не найдут кластер, который имеет самое высокое отношение точек в кластере к количеству цветов в кластере. Центральная точка этого является наиболее распространенным цветом. Затем палитру определяют следующие высшие наборы кластеров, с некоторой логикой, чтобы предотвратить почти полное перекрытие кластеров.