tutorial php javascript python image-processing

php - tutorial - opencv.js download



Detecta el color "promedio general" de la imagen (6)

Tengo una imagen jpg.

Necesito saber el "promedio general" del color de la imagen. A primera vista, puede usar el histograma de la imagen (canal RGB).

En el trabajo, uso principalmente JavaScript y PHP (un poco de Python), por lo tanto, recibí con agrado la decisión en estos idiomas. Tal vez hay una biblioteca para trabajar con imágenes que abordan problemas similares.

No necesito determinar dinámicamente el color de la imagen. Necesito pasar una vez por todo el conjunto de imágenes y determinar el color de cada una por separado (esta información la recordaré para uso futuro).


Combinando JKirchartz y Alexander Hugestrand responden:

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

Probado y probado, devuelve cadena hexagonal.



Creé el paquete de compositor que proporciona la biblioteca para elegir un color promedio de la imagen dada por su ruta.

Puede instalarlo ejecutando el siguiente comando dentro del directorio de su proyecto:

composer require tooleks/php-avg-color-picker

Ejemplo de uso:

<?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).

Ver la documentation .


Puede usar PHP para obtener una matriz de la paleta de colores de esta manera:

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

Lo que le proporciona una matriz cuyos valores son más altos para la frecuencia con la que se ha usado ese color.

EDITAR Un comentarista preguntó cómo usar esto en todos los archivos en un directorio, aquí está:

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

Puede que no quiera hacer esto en demasiados archivos, pero es su servidor.

Alternativamente, si prefiere usar Javascript, la biblioteca Color-Theif de Lokesh hace exactamente lo que está buscando.


Una solución más corta para una imagen en color real sería escalarla a un tamaño de píxel de 1x1 y muestrear el color en ese píxel:

$ escalado = imagescale ($ img, 1, 1, IMG_BICUBIC); $ meanColor = imagecolorat ($ img, 0, 0);

... pero no lo he probado yo mismo.


$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>'';

usted puede obtener el valor del color promedio con un remuestreo de $ r, $ g, & $ b ¡la imagen es mucho mejor que solo escalarla!