// // --------------------------- below is RQuadling's code, with some traces added // echo"<h2>RQuadling's code</h2>"; //VGR22082009 ADDed echo 'Starting to read image<br>'; TimerStart(); // Try and open the image. $r_image = @imagecreatefromjpeg($s_image_filename); // If the image was opened successfully then continue. if ($r_image) { // Get the images dimensions. $am_image_data = getimagesize($s_image_filename); // Prepare an empty array to store the count. $ai_colour_count = array(); // Iterate the x and y of the image. for ($i_x = 0 ; $i_x < $am_image_data[0] ; $i_x++) { for ($i_y = 0 ; $i_y < $am_image_data[1] ; $i_y++) { // Get the colour or palette number at x,y. $i_rgb = imagecolorat($r_image, $i_x, $i_y); // Determine if the image is true colour or paletted. if (!imageistruecolor($r_image)) { // Convert the palette index into a real colour. $a_rgb = imagecolorsforindex($r_image, $i_rgb); $i_rgb = ((($a_rgb['red'] * 256) + $a_rgb['green']) * 256) + $a_rgb['blue']; } //echo "old value=$i_rgb<br>"; //echo (($i_rgb & 0xff0000) >> 16 ).', '. (($i_rgb & 0xff00) >> 8).', '.($i_rgb & 0xff).'<br>'; if ($REDUCERANGE) { // hash colour if (!imageistruecolor($r_image)) { $tt1=floor($a_rgb['red'] / 4)*4; $tt2=floor($a_rgb['green'] / 4)*4; $tt3=floor($a_rgb['blue'] / 4)*4; $newvalue=((($tt1 * 256) + $tt2) * 256) + $tt3; //echo "$tt1 $tt2 $tt3<br>"; } else { //echo "rgb=$i_rgb<br>"; $courant=$i_rgb%256; $reste=($i_rgb-$courant)/256; $tt3=floor($courant / 4)*4; $courant=$reste%256; $reste=($reste-$courant)/256; $tt2=floor($courant / 4)*4; $courant=$reste%256; $reste=($reste-$courant)/256; $tt1=floor($courant / 4)*4; //echo "$tt1 $tt2 $tt3 (reste=$reste)<br>"; $newvalue=((($tt1 * 256) + $tt2) * 256) + $tt3; } $i_rgb=$newvalue; } //echo "new value=$i_rgb<br>"; // Update the count array with the colour. if (!isset($ai_colour_count[$i_rgb])) { $ai_colour_count[$i_rgb] = 0; } ++$ai_colour_count[$i_rgb]; } } TimerStop(TRUE); echo 'Starting to sort colours<br>'; TimerStart(); // Sort the colour map preserving the colour/palette arsort($ai_colour_count); TimerStop(TRUE); echo count($ai_colour_count).' colours found.<br>'; echo 'Starting to get 3 most represented colours<br>'; TimerStart(); // Determine the number of colours to report. $i_colours_to_report = 3; // Reset the array to the beginning. reset($ai_colour_count); // Report the colours. while($i_colours_to_report > 0) { $i_rgb = key($ai_colour_count); $i_count = current($ai_colour_count); echo sprintf("%08X = rgb(%3d,%3d,%3d) occurs %8d{$eoln}", $i_rgb, ($i_rgb & 0xff0000) >> 16, ($i_rgb & 0xff00) >> 8, ($i_rgb & 0xff), $i_count); next($ai_colour_count); --$i_colours_to_report; } TimerStop(TRUE); } else { die('Could not open : ' . $s_image_filename); } // // --------------------------- below is VGR's code again, to demonstrate colours count reduction // $REDUCERANGE=TRUE; $diviser=2; // 1 = 256 colours (232 in web palette) ; 8 = 32 colours (ugly) echo '<hr>Starting to read image<br>'; TimerStart(); // Try and open the image. $r_image=@imagecreatefromjpeg($s_image_filename); // If the image was opened successfully then continue. if ($r_image) { // Get the images dimensions and colour depth $am_image_data=getimagesize($s_image_filename); // Determine if the image is true colour or paletted. $istruecolour=imageistruecolor($r_image); $nbcol=256/$diviser; echo (($REDUCERANGE)?'reducing colours range':'not reducing colours range').", nbcol (=256/diviser) = $nbcol, diviser=$diviser<br>"; // Prepare an empty array to store the count. $ai_colour_count = array(); // Iterate the x and y of the image. for ($i_x = 0 ; $i_x < $am_image_data[0] ; $i_x++) { for ($i_y = 0 ; $i_y < $am_image_data[1] ; $i_y++) { // Get the colour or palette number at x,y. $i_rgb = imagecolorat($r_image, $i_x, $i_y); if (!$istruecolour) { // Convert the palette index into a real colour. $a_rgb = imagecolorsforindex($r_image, $i_rgb); $i_rgb = ((($a_rgb['red'] * 256) + $a_rgb['green']) * 256) + $a_rgb['blue']; } if ($REDUCERANGE) { // hash colour if (!$istruecolour) { //VGR22082009 FIXed stupid réaffectation in test $tt1=floor($a_rgb['red'] / $diviser)*$diviser; $tt2=floor($a_rgb['green'] / $diviser)*$diviser; $tt3=floor($a_rgb['blue'] / $diviser)*$diviser; $newvalue=((($tt1 * 256) + $tt2) * 256) + $tt3; //test echo "not true colour : value $i_rgb becomes $newvalue<br>"; } else { $courant=$i_rgb%256; $reste=($i_rgb-$courant)/256; $tt3=floor($courant / $diviser)*$diviser; $courant=$reste%256; $reste=($reste-$courant)/256; $tt2=floor($courant / $diviser)*$diviser; $courant=$reste%256; $reste=($reste-$courant)/256; $tt1=floor($courant / $diviser)*$diviser; $newvalue=((($tt1 * 256) + $tt2) * 256) + $tt3; //test echo "true colour : value $i_rgb becomes $newvalue<br>"; } $i_rgb=$newvalue; } // Update the count array with the colour. @$ai_colour_count[$i_rgb]++; } } TimerStop(TRUE); echo 'No sort on colours<br>'; TimerStart(); $cMax=(($nbcol*256+$nbcol)*256+$nbcol); echo "Starting to get 3 most represented colours (cMax=$cMax)<br>"; // display results of most-occuring value $locMax=0; $locMax2=0; $locMax3=0; $locMaxI2=0; $locMaxI=0; for ($i=0;$i<=$cMax;$i++) { //if ($i%100000==0) echo "$i<br>"; //VGR22082009 MOD enhanced loop, was very slow [from 1min22s to 3s] : if (@$ai_colour_count[$i]>$locMax) { if (isset($ai_colour_count[$i])) if (@$ai_colour_count[$i]>$locMax) { $locMaxI3=$locMaxI2; $locMaxI2=$locMaxI; $locMaxI=$i; $locMax3=$locMax2; $locMax2=$locMax; $locMax=$ai_colour_count[$i]; } else if (@$ai_colour_count[$i]>$locMax2) { $locMaxI3=$locMaxI2; $locMaxI2=$i; $locMax3=$locMax2; $locMax2=$ai_colour_count[$i]; } else if (@$ai_colour_count[$i]>$locMax3) { $locMaxI3=$i; $locMax3=$ai_colour_count[$i]; } // else NOP, loop } //VGR22082009 MOD to display hex & rgb values echo "first maximum occuring value is : "; echo sprintf("%08X = rgb(%3d,%3d,%3d)", $locMaxI, ($locMaxI & 0xff0000) >> 16, ($locMaxI & 0xff00) >> 8, ($locMaxI & 0xff)); echo "( $locMax times)<br>"; echo "second maximum occuring value is : "; echo sprintf("%08X = rgb(%3d,%3d,%3d)", $locMaxI2, ($locMaxI2 & 0xff0000) >> 16, ($locMaxI2 & 0xff00) >> 8, ($locMaxI2 & 0xff)); echo "( $locMax2 times)<br>"; echo "third maximum occuring value is : "; echo sprintf("%08X = rgb(%3d,%3d,%3d)", $locMaxI3, ($locMaxI3 & 0xff0000) >> 16, ($locMaxI3 & 0xff00) >> 8, ($locMaxI3 & 0xff)); echo "( $locMax3 times)<br>"; echo '<br>'; TimerStop(TRUE); } else die("Could not open : $s_image_filename");
Ici, je comparais du code de RQuadling au mien pour l'extraction des 3 couleurs les plus utilisées d'une image. La différence principale tenait à la méthode de tri.
Maintenant que l'implémentation de asort() et al dans PHP a été améliorée, la solution utilisant ces fonctions est plus rapide que la mienne, à base de "tri instantané".
Néanmoins, mon code permet aussi, sur option, de réduire le nombre de couleurs de l'image "au mieux" pour s'accomoder d'une palette réduite.
Notez bien que théoriquement les deux solutions réduident le nombre de couleurs, mais qu'il ne me souvient plus de si la solution de RQuadling y réussit ;-)
Cordialement,
In here, was comparing RQuadling's code to mine to extract the three most used colours of an image.
Now, asort() has been optimized in PHP so the first solution is faster than the second.
This said, my solution also enables to reduce the colours count to fit a reduced palette.
Note that both solutions theoretically reduce the colours count, but I don't remember if RQuadling's works out nicely ;-)
Best regards,
for European Experts Exchange and Edaìn Works back to list of test scripts
Last update 2024-05-13 15:34:03
Copyright(©)(c) the respective authors. Licensed under the Creative Commons Attribution Share Alike 3.0 License .
These pages are served without commercial sponsorship. (No popup ads, etc...). Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE.
Please DO link to this page!