2012-01-04 13 views
18

quiero encontrar el color dominante en la imagen, ¿cómo puedo hacerlo?¿Cómo encontrar el color dominante en la imagen?

que sería genial si puedo conseguir esto en código hexadecimal (EXM: #eeeeee)

+0

¿por qué PHP? ¿Es parte de una aplicación web? – Alnitak

+1

y defina "dominante": podría ser el promedio de toda la imagen o el triple RGB particular más común encontrado. – Alnitak

+0

Qué color dominante en una imagen es, es subjetivo y depende del espectador de la imagen. Entonces, la gente que no ve rojo, nunca encontraría ese color dominante, por ejemplo. – hakre

Respuesta

16

Para encontrar el color más "dominante" en una imagen, es decir, el color que prevalece más en la imagen: necesitaría crear un histograma de la imagen.

Aquí hay un código de este article on how to create a histogram in PHP. (La página web ha ido fuera de línea varias veces)

<?php 
$source_file = "test_image.jpg"; 

// histogram options 

$maxheight = 300; 
$barwidth = 2; 

$im = ImageCreateFromJpeg($source_file); 

$imgw = imagesx($im); 
$imgh = imagesy($im); 

// n = total number or pixels 

$n = $imgw*$imgh; 

$histo = array(); 

for ($i=0; $i<$imgw; $i++) 
{ 
     for ($j=0; $j<$imgh; $j++) 
     { 

       // get the rgb value for current pixel 

       $rgb = ImageColorAt($im, $i, $j); 

       // extract each value for r, g, b 

       $r = ($rgb >> 16) & 0xFF; 
       $g = ($rgb >> 8) & 0xFF; 
       $b = $rgb & 0xFF; 

       // get the Value from the RGB value 

       $V = round(($r + $g + $b)/3); 

       // add the point to the histogram 

       $histo[$V] += $V/$n; 

     } 
} 

// find the maximum in the histogram in order to display a normated graph 

$max = 0; 
for ($i=0; $i<255; $i++) 
{ 
     if ($histo[$i] > $max) 
     { 
       $max = $histo[$i]; 
     } 
} 

echo "<div style='width: ".(256*$barwidth)."px; border: 1px solid'>"; 
for ($i=0; $i<255; $i++) 
{ 
     $val += $histo[$i]; 

     $h = ($histo[$i]/$max)*$maxheight; 

     echo "<img src=\"img.gif\" width=\"".$barwidth."\" 
height=\"".$h."\" border=\"0\">"; 
} 
echo "</div>"; 
?> 

En ese ejemplo $max es su color más "dominante".

+0

Este enlace va a un sitio web para adultos ahora :( –

+6

@RichBradshaw aw man. The f'ing internet. – tkone

+0

Tenga en cuenta que el código vinculado básicamente convierte la imagen a b/w y no distingue entre colores, es decir, una imagen completamente azul dará como resultado el mismo histograma que un rojo Para obtener el color dominante, recomiendo convertir primero los valores RGB a HSL y crear el histograma para el valor de matiz. –

3

Hay una clase PHP desarrollado que se encarga de esto, llamado color extract. Sin embargo, sepa que hacer esto en el lado del servidor requerirá recursos sustanciales del sistema. En su lugar, puede hacer esto con canvas.

+0

Si está buscando hacerlo en JavScript, aquí hay una respuesta pregunta de desbordamiento de pila que responde exactamente eso: http://stackoverflow.com/questions/8329765/determine-if-image-is-grayscale-or-color-using-javascript/8329821#8329821 – tkone

2

¡Suena como un delicioso código para escribir! Hice una función un tiempo atrás que recorre cada píxel y agrega un tono a cada uno. Lo que podría hacer es:

para cada píxel, encontrar el color más alta (r, g, o b) y hacer los cálculos ($ colorG ++ o algo así)

al final, descubrir lo que uno es el más grande, y habría su sombra rgb más alta.

Me pregunto de qué color saldría si se ha utilizado el valor RGB resultante ...

2

En cuanto a la respuesta tkone, $ max es solo un parámetro que muestra la densidad del color en la imagen. yo cambiará el código un poco para devolver el color hexadecimal:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
<title>Empty Document</title> 
</head> 

<body> 
<?php 

error_reporting(0); 
function rgb2hex($rgb) { 
    $hex = "#"; 
    $hex .= str_pad(dechex($rgb[0]), 2, "0", STR_PAD_LEFT); 
    $hex .= str_pad(dechex($rgb[1]), 2, "0", STR_PAD_LEFT); 
    $hex .= str_pad(dechex($rgb[2]), 2, "0", STR_PAD_LEFT); 

    return $hex; // returns the hex value including the number sign (#) 
} 


$source_file = "image.jpg"; 

// histogram options 

$maxheight = 300; 
$barwidth = 2; 

$im = ImageCreateFromJpeg($source_file); 

$imgw = imagesx($im); 
$imgh = imagesy($im); 

// n = total number or pixels 

$n = $imgw*$imgh; 

$histo = array(); 

for ($i=0; $i<$imgw; $i++) 
{ 
     for ($j=0; $j<$imgh; $j++) 
     { 

       // get the rgb value for current pixel 

       $rgb = ImageColorAt($im, $i, $j); 
       //echo $rgb."<br>"; 
       // extract each value for r, g, b 

       $r = ($rgb >> 16) & 0xFF; 
       $g = ($rgb >> 8) & 0xFF; 
       $b = $rgb & 0xFF; 

       // get the Value from the RGB value 

       $V = round(($r + $g + $b)/3); 
       //echo $V."<br>"; 
       // add the point to the histogram 

       $histo[$V] += $V/$n; 
       $histo_color[$V] = rgb2hex([$r,$g,$b]); 

     } 
} 

// find the maximum in the histogram in order to display a normated graph 

$max = 0; 
for ($i=0; $i<255; $i++) 
{ 
     if ($histo[$i] > $max) 
     { 
       $max = $histo[$i]; 
     } 
} 

echo "<div style='width: ".(256*$barwidth)."px; border: 1px solid'>"; 
for ($i=0; $i<255; $i++) 
{ 
     $val += $histo[$i]; 

     $h = ($histo[$i]/$max)*$maxheight; 

     echo "<img src=\"img.gif\" width=\"".$barwidth."\" 
height=\"".$h."\" border=\"0\">"; 
} 
echo "</div>"; 

$key = array_search ($max, $histo); 
$col = $histo_color[$key]; 
?> 

<p style="min-width:100px; min-height:100px; background-color:<?php echo $col?>;"></p> 
<img src="<?php echo $source_file?>"> 
</body> 
</html> 

También debería decir que esto es sólo el color que más se repite en la imagen que no se considera "dominantes".

Cuestiones relacionadas