2012-04-24 12 views
20

Sto cercando di replicare la funzionalità che Dribbble.com esegue con il rilevamento dei colori predominanti in un'immagine. Nell'immagine qui sotto puoi vedere uno screenshot di Dribbble.com che mostra gli 8 colori predominanti nell'immagine a sinistra. Ecco la pagina reale nell'immagine http://dribbble.com/shots/528033-Fresh-Easy?list=followingRileva i colori principali in un'immagine con PHP

Ho bisogno di essere in grado di farlo in PHP, una volta che ottengo i colori di cui ho bisogno io li salva in un database in modo che il trattamento non ha bisogno di essere eseguito su ogni pagina caricare.

Dopo alcune ricerche su come ottenere questi colori da un'immagine, alcune persone hanno detto che si esamina semplicemente un'immagine pixel per pixel e quindi si salvano i colori che si verificano maggiormente. Altri dicono che c'è di più e che ottenere i colori più frequenti non darà l'effetto desiderato. Dicono che è necessario quantizzare l'immagine/i colori (sono perso a questo punto).

Nell'immagine sottostante il colpo Dribble sotto è una libreria JavaScript che fa la stessa cosa, la pagina può essere vista qui http://lokeshdhakar.com/projects/color-thief/

Visualizza la fonte di quella pagina posso vedere c'è un file JavaScript denominato quantize.js e i risultati sono davvero buoni. Quindi spero di essere in grado di fare ciò che libreria Javascript fa, ma con PHP e GD/ImageMagick

enter image description here


avevo trovato questa funzione che restituirà i colori e contare in un'immagine con PHP ma i risultati sono diversi dalla versione Javascript sopra e la Dribble risultati

/** 
* 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)"); 
} 

Così mi chiedo se qualcuno sa come posso fare un tale compito con PHP? Probabilmente esiste già qualcosa che conosci o qualche consiglio per farmi un passo avanti.

+0

http://stackoverflow.com/questions/3468500/detect-overall-average-color-of-the-picture –

+0

@aSeptik sembra che stia facendo lo stesso del codice che ho già postato – JasonDavis

+0

hai provato per cercare google per "php get color palette from image" "Ho fondato molti risultati; solo chiedendo ... –

risposta

24

Qui è esattamente quello che stai cercando in PHP: https://github.com/thephpleague/color-extractor

Esempio:

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

Sembra un buon caducato per una porta a C :) – quickshiftin

3

La pagina a cui ti sei collegato ha un link al codice sorgente su GitHub quindi se vuoi sapere esattamente come stai facendo potresti replicare la loro fonte in PHP.

La grande differenza tra il modo in cui lo fanno e il modo in cui lo stai facendo è che utilizzano il clustering per trovare il colore. Invece di arrotondare il colore quando lo memorizzano, stanno memorizzando tutti i colori grezzi in un array. Quindi eseguono il ciclo attraverso questa matrice finché non trovano un cluster con il più alto rapporto di punti nel cluster rispetto al numero di colori nel cluster. Il punto centrale di questo è il colore più comune. La tavolozza viene quindi definita dai successivi gruppi più alti di cluster, con una logica che impedisce la sovrapposizione quasi completa dei cluster.

5

Questo è il mio metodo semplice per ottenere il colore principale di un'immagine

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

?> 
5

È è necessario ridimensionare l'immagine e otterrete i colori principali dell'immagine. Se sono necessari 4 colori nel pallet, ridimensionarlo a circa 8x8, 6 colori a circa 12x8 e così via ...

imagecopyresized per un'immagine rimpicciolita in modo che poi controllare ogni pixel e memorizzarli in serie imagecolorat($image,px,py)

Prova questo

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

} 
?> 

Opere perfetto per me.

+0

Questa è una bella esempio leggero di come ottenere i colori. C'è un modo per limitarlo ai colori usati più in alto. Ad esempio, la top 8 ha usato i colori in un'immagine? – JasonDavis

0

Prova questo: http://www.coolphptools.com/color_extract

Funziona con JPEG e PNG.

E meglio !: senza fretta con il compositore, appena 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); 

darvi qualcosa di simile:

Array ( [3060a8] => ,55827380952381 [f0a848] => ,19791666666667 [000000] => ,069642857142857 [483.018] => ,02047619047619 [786.018] => ,01827380952381 [183060] => ,01797619047619 012.351.641.061.[4878a8] => 0,016011904761905 [181.800] => 0,015119047619048 [a87830] => 0,014345238095238 [a8c0d8] => 0,011904761904762 [6090c0] => ,01172619047619 [d89030] => 0,011011904761905 [90a8d8] => ,0071428571428571 [ffffff] => ,0070238095238095 [604.830] => 0,006547619047619 [f0f0f0] => ,0063095238095238 [d8d8f0] => 0,005297619047619 [c0d8d8] => ,0044047619047619 [f0f0ff] => ,00041666666666667 [181.830] => ,00011904761904762)

L'ho provato con immagini diverse e sembra affidabile.