php image-processing imagemagick gd

Detecta los colores principales en una imagen con PHP



image-processing imagemagick (5)

Estoy tratando de replicar la funcionalidad que Dribbble.com hace con la detección de los colores predominantes en una imagen. En la imagen a continuación, puede ver una captura de pantalla de Dribbble.com que muestra los 8 colores predominantes en la imagen a la izquierda. Aquí está la página real en la imagen http://dribbble.com/shots/528033-Fresh-Easy?list=following

Necesito poder hacer esto en PHP, una vez que obtenga los colores que necesito los guardaré en una base de datos, por lo que no es necesario que el proceso se ejecute en cada carga de página.

Después de algunas investigaciones sobre cómo obtener estos colores de una Imagen, algunas personas dijeron que simplemente examina una imagen píxel por píxel y luego guarda los colores que ocurren más. Otros dicen que hay más y que obtener los colores que existen con mayor frecuencia no dará el efecto deseado. Dicen que necesita cuantizar la imagen / los colores (estoy perdido en este momento).

En la imagen de abajo, la imagen de Dribble que se muestra a continuación es una biblioteca de Javascript que hace lo mismo, esa página se puede ver aquí http://lokeshdhakar.com/projects/color-thief/

Viendo la fuente de esa página, puedo ver que hay un archivo Javascript llamado quantize.js y los resultados son realmente buenos. Así que espero poder hacer lo que hace esa biblioteca Javascript pero con PHP y GD / ImageMagick

Encontré esta función que devolverá los colores y contará en una imagen con PHP pero los resultados son diferentes a los de la versión de JavaScript anterior y los resultados de 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)"); }

Entonces, ¿estoy preguntando si alguien sabe cómo puedo hacer esa tarea con PHP? Posiblemente ya exista algo que usted conozca o cualquier consejo para acercarme un poco más a esto sería apreciado


Este es mi método simple para obtener el color principal de una imagen

<?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; ?>


Esto es exactamente lo que está buscando en PHP: https://github.com/thephpleague/color-extractor

Ejemplo:

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();


La página a la que se ha vinculado tiene un enlace al código fuente en GitHub, por lo que si quiere saber exactamente cómo lo están haciendo, podría replicar su fuente en PHP.

La gran diferencia entre cómo lo están haciendo y cómo lo están haciendo es que están usando la agrupación para encontrar el color. En lugar de redondear el color cuando lo almacenan, están almacenando todos los colores en bruto en una matriz. Luego recorren esta matriz hasta que encuentran un clúster que tiene la mayor proporción de puntos en el clúster y el número de colores en el clúster. El punto central de este es el color más común. Luego, la paleta se define mediante los siguientes conjuntos más altos de clústeres, con cierta lógica para evitar la superposición casi completa de los clústeres.


Necesita reducir la escala de la imagen y obtendrá los colores principales de la imagen. Si necesita 4 colores en la paleta, reduzca la escala a aproximadamente 8x8 , 6 colores a aproximadamente 12x8 y así sucesivamente ...

imagecopyresized para una imagen reducida, luego verifique cada imagecolorat($image,px,py) y guárdelos en una matriz imagecolorat($image,px,py)

Probar esto

<?php // EXAMPLE PICTURE $url=''https://www.nordoff-robbins.org.uk/sites/default/files/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; } ?>

Funciona perfecto para mi


Pruebe esto: http://www.coolphptools.com/color_extract

Funciona con JPEG y PNG.

¡Y lo mejor !: sin alboroto con el compositor, solo require_once

require_once ''colorextract/colors.inc.php''; $ex=new GetMostCommonColors(); $num_results=20; $reduce_brightness=1; $reduce_gradients=1; $delta=24; $colors=$ex->Get_Color( ''image.png'', $num_results, $reduce_brightness, $reduce_gradients, $delta); print_r($colors);

darte algo como esto:

Matriz ([3060a8] => 0.55827380952381 [f0a848] => 0.19791666666667 [000000] => 0.069642857142857 [483018] => 0.02047619047619 [786018] => 0.01827380952381 [183060] => 0.01797619047619 [4878a8] => 0.016011904761905 [181800] => 0.015119047619048 [a87830] => 0.014345238095238 [a8c0d8] => 0.011904761904762 [6090c0] => 0.01172619047619 [d89030] => 0.011011904761905 [90a8d8] => 0.0071428571428571 [ffffff] => 0.0070238095238095 [604830] => 0.006547619047619 [f0f0f0] => 0.0063095238095238 [d8d8f0 ] => 0.005297619047619 [c0d8d8] => 0.0044047619047619 [f0f0ff] => 0.00041666666666667 [181830] => 0.00011904761904762)

Lo intenté con diferentes imágenes y parece confiable.