Advertisement
Guest User

Colours.Inc.Php

a guest
Aug 19th, 2012
157
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 8.19 KB | None | 0 0
  1. <?php
  2. /**
  3.  * This class can be used to get the most common colors in an image.
  4.  * It needs one parameter:
  5.  *  $image - the filename of the image you want to process.
  6.  * Optional parameters:
  7.  *
  8.  *  $count - how many colors should be returned. 0 mmeans all. default=20
  9.  *  $reduce_brightness - reduce (not eliminate) brightness variants? default=true
  10.  *  $reduce_gradients - reduce (not eliminate) gradient variants? default=true
  11.  *  $delta - the amount of gap when quantizing color values.
  12.  *      Lower values mean more accurate colors. default=16
  13.  *
  14.  * Author:  Csongor Zalatnai
  15.  *
  16.  * Modified By: Kepler Gelotte - Added the gradient and brightness variation
  17.  *  reduction routines. Kudos to Csongor for an excellent class. The original
  18.  *  version can be found at:
  19.  *
  20.  *  http://www.phpclasses.org/browse/package/3370.html
  21.  *
  22.  */
  23. class GetMostCommonColors
  24. {
  25.     var $PREVIEW_WIDTH    = 150;
  26.     var $PREVIEW_HEIGHT   = 150;
  27.  
  28.     var $error;
  29.  
  30.     /**
  31.      * 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.
  32.      *
  33.      * @return array
  34.      */
  35.     function Get_Color( $img, $count=20, $reduce_brightness=true, $reduce_gradients=true, $delta=16 )
  36.     {
  37.         if (is_readable( $img ))
  38.         {
  39.             if ( $delta > 2 )
  40.             {
  41.                 $half_delta = $delta / 2 - 1;
  42.             }
  43.             else
  44.             {
  45.                 $half_delta = 0;
  46.             }
  47.             // WE HAVE TO RESIZE THE IMAGE, BECAUSE WE ONLY NEED THE MOST SIGNIFICANT COLORS.
  48.             $size = GetImageSize($img);
  49.             $scale = 1;
  50.             if ($size[0]>0)
  51.             $scale = min($this->PREVIEW_WIDTH/$size[0], $this->PREVIEW_HEIGHT/$size[1]);
  52.             if ($scale < 1)
  53.             {
  54.                 $width = floor($scale*$size[0]);
  55.                 $height = floor($scale*$size[1]);
  56.             }
  57.             else
  58.             {
  59.                 $width = $size[0];
  60.                 $height = $size[1];
  61.             }
  62.             $image_resized = imagecreatetruecolor($width, $height);
  63.             if ($size[2] == 1)
  64.             $image_orig = imagecreatefromgif($img);
  65.             if ($size[2] == 2)
  66.             $image_orig = imagecreatefromjpeg($img);
  67.             if ($size[2] == 3)
  68.             $image_orig = imagecreatefrompng($img);
  69.             // WE NEED NEAREST NEIGHBOR RESIZING, BECAUSE IT DOESN'T ALTER THE COLORS
  70.             imagecopyresampled($image_resized, $image_orig, 0, 0, 0, 0, $width, $height, $size[0], $size[1]);
  71.             $im = $image_resized;
  72.             $imgWidth = imagesx($im);
  73.             $imgHeight = imagesy($im);
  74.             $total_pixel_count = 0;
  75.             for ($y=0; $y < $imgHeight; $y++)
  76.             {
  77.                 for ($x=0; $x < $imgWidth; $x++)
  78.                 {
  79.                     $total_pixel_count++;
  80.                     $index = imagecolorat($im,$x,$y);
  81.                     $colors = imagecolorsforindex($im,$index);
  82.                     // ROUND THE COLORS, TO REDUCE THE NUMBER OF DUPLICATE COLORS
  83.                     if ( $delta > 1 )
  84.                     {
  85.                         $colors['red'] = intval((($colors['red'])+$half_delta)/$delta)*$delta;
  86.                         $colors['green'] = intval((($colors['green'])+$half_delta)/$delta)*$delta;
  87.                         $colors['blue'] = intval((($colors['blue'])+$half_delta)/$delta)*$delta;
  88.                         if ($colors['red'] >= 256)
  89.                         {
  90.                             $colors['red'] = 255;
  91.                         }
  92.                         if ($colors['green'] >= 256)
  93.                         {
  94.                             $colors['green'] = 255;
  95.                         }
  96.                         if ($colors['blue'] >= 256)
  97.                         {
  98.                             $colors['blue'] = 255;
  99.                         }
  100.  
  101.                     }
  102.  
  103.                     $hex = substr("0".dechex($colors['red']),-2).substr("0".dechex($colors['green']),-2).substr("0".dechex($colors['blue']),-2);
  104.  
  105.                     if ( ! isset( $hexarray[$hex] ) )
  106.                     {
  107.                         $hexarray[$hex] = 1;
  108.                     }
  109.                     else
  110.                     {
  111.                         $hexarray[$hex]++;
  112.                     }
  113.                 }
  114.             }
  115.  
  116.             // Reduce gradient colors
  117.             if ( $reduce_gradients )
  118.             {
  119.                 // if you want to *eliminate* gradient variations use:
  120.                 // ksort( &$hexarray );
  121.                 arsort( &$hexarray, SORT_NUMERIC );
  122.  
  123.                 $gradients = array();
  124.                 foreach ($hexarray as $hex => $num)
  125.                 {
  126.                     if ( ! isset($gradients[$hex]) )
  127.                     {
  128.                         $new_hex = $this->_find_adjacent( $hex, $gradients, $delta );
  129.                         $gradients[$hex] = $new_hex;
  130.                     }
  131.                     else
  132.                     {
  133.                         $new_hex = $gradients[$hex];
  134.                     }
  135.  
  136.                     if ($hex != $new_hex)
  137.                     {
  138.                         $hexarray[$hex] = 0;
  139.                         $hexarray[$new_hex] += $num;
  140.                     }
  141.                 }
  142.             }
  143.  
  144.             // Reduce brightness variations
  145.             if ( $reduce_brightness )
  146.             {
  147.                 // if you want to *eliminate* brightness variations use:
  148.                 // ksort( &$hexarray );
  149.                 arsort( &$hexarray, SORT_NUMERIC );
  150.  
  151.                 $brightness = array();
  152.                 foreach ($hexarray as $hex => $num)
  153.                 {
  154.                     if ( ! isset($brightness[$hex]) )
  155.                     {
  156.                         $new_hex = $this->_normalize( $hex, $brightness, $delta );
  157.                         $brightness[$hex] = $new_hex;
  158.                     }
  159.                     else
  160.                     {
  161.                         $new_hex = $brightness[$hex];
  162.                     }
  163.  
  164.                     if ($hex != $new_hex)
  165.                     {
  166.                         $hexarray[$hex] = 0;
  167.                         $hexarray[$new_hex] += $num;
  168.                     }
  169.                 }
  170.             }
  171.  
  172.             arsort( &$hexarray, SORT_NUMERIC );
  173.  
  174.             // convert counts to percentages
  175.             foreach ($hexarray as $key => $value)
  176.             {
  177.                 $hexarray[$key] = (float)$value / $total_pixel_count;
  178.             }
  179.  
  180.             if ( $count > 0 )
  181.             {
  182.                 // only works in PHP5
  183.                 // return array_slice( $hexarray, 0, $count, true );
  184.  
  185.                 $arr = array();
  186.                 foreach ($hexarray as $key => $value)
  187.                 {
  188.                     if ($count == 0)
  189.                     {
  190.                         break;
  191.                     }
  192.                     $count--;
  193.                     $arr[$key] = $value;
  194.                 }
  195.                 return $arr;
  196.             }
  197.             else
  198.             {
  199.                 return $hexarray;
  200.             }
  201.  
  202.         }
  203.         else
  204.         {
  205.             $this->error = "Image ".$img." does not exist or is unreadable";
  206.             return false;
  207.         }
  208.     }
  209.  
  210.     function _normalize( $hex, $hexarray, $delta )
  211.     {
  212.         $lowest = 255;
  213.         $highest = 0;
  214.         $colors['red'] = hexdec( substr( $hex, 0, 2 ) );
  215.         $colors['green']  = hexdec( substr( $hex, 2, 2 ) );
  216.         $colors['blue'] = hexdec( substr( $hex, 4, 2 ) );
  217.  
  218.         if ($colors['red'] < $lowest)
  219.         {
  220.             $lowest = $colors['red'];
  221.         }
  222.         if ($colors['green'] < $lowest )
  223.         {
  224.             $lowest = $colors['green'];
  225.         }
  226.         if ($colors['blue'] < $lowest )
  227.         {
  228.             $lowest = $colors['blue'];
  229.         }
  230.  
  231.         if ($colors['red'] > $highest)
  232.         {
  233.             $highest = $colors['red'];
  234.         }
  235.         if ($colors['green'] > $highest )
  236.         {
  237.             $highest = $colors['green'];
  238.         }
  239.         if ($colors['blue'] > $highest )
  240.         {
  241.             $highest = $colors['blue'];
  242.         }
  243.  
  244.         // Do not normalize white, black, or shades of grey unless low delta
  245.         if ( $lowest == $highest )
  246.         {
  247.             if ($delta <= 32)
  248.             {
  249.                 if ( $lowest == 0 || $highest >= (255 - $delta) )
  250.                 {
  251.                     return $hex;
  252.                 }
  253.             }
  254.             else
  255.             {
  256.                 return $hex;
  257.             }
  258.         }
  259.  
  260.         for (; $highest < 256; $lowest += $delta, $highest += $delta)
  261.         {
  262.             $new_hex = substr("0".dechex($colors['red'] - $lowest),-2).substr("0".dechex($colors['green'] - $lowest),-2).substr("0".dechex($colors['blue'] - $lowest),-2);
  263.  
  264.             if ( isset( $hexarray[$new_hex] ) )
  265.             {
  266.                 // same color, different brightness - use it instead
  267.                 return $new_hex;
  268.             }
  269.         }
  270.  
  271.         return $hex;
  272.     }
  273.  
  274.     function _find_adjacent( $hex, $gradients, $delta )
  275.     {
  276.         $red = hexdec( substr( $hex, 0, 2 ) );
  277.         $green  = hexdec( substr( $hex, 2, 2 ) );
  278.         $blue = hexdec( substr( $hex, 4, 2 ) );
  279.  
  280.         if ($red > $delta)
  281.         {
  282.             $new_hex = substr("0".dechex($red - $delta),-2).substr("0".dechex($green),-2).substr("0".dechex($blue),-2);
  283.             if ( isset($gradients[$new_hex]) )
  284.             {
  285.                 return $gradients[$new_hex];
  286.             }
  287.         }
  288.         if ($green > $delta)
  289.         {
  290.             $new_hex = substr("0".dechex($red),-2).substr("0".dechex($green - $delta),-2).substr("0".dechex($blue),-2);
  291.             if ( isset($gradients[$new_hex]) )
  292.             {
  293.                 return $gradients[$new_hex];
  294.             }
  295.         }
  296.         if ($blue > $delta)
  297.         {
  298.             $new_hex = substr("0".dechex($red),-2).substr("0".dechex($green),-2).substr("0".dechex($blue - $delta),-2);
  299.             if ( isset($gradients[$new_hex]) )
  300.             {
  301.                 return $gradients[$new_hex];
  302.             }
  303.         }
  304.  
  305.         if ($red < (255 - $delta))
  306.         {
  307.             $new_hex = substr("0".dechex($red + $delta),-2).substr("0".dechex($green),-2).substr("0".dechex($blue),-2);
  308.             if ( isset($gradients[$new_hex]) )
  309.             {
  310.                 return $gradients[$new_hex];
  311.             }
  312.         }
  313.         if ($green < (255 - $delta))
  314.         {
  315.             $new_hex = substr("0".dechex($red),-2).substr("0".dechex($green + $delta),-2).substr("0".dechex($blue),-2);
  316.             if ( isset($gradients[$new_hex]) )
  317.             {
  318.                 return $gradients[$new_hex];
  319.             }
  320.         }
  321.         if ($blue < (255 - $delta))
  322.         {
  323.             $new_hex = substr("0".dechex($red),-2).substr("0".dechex($green),-2).substr("0".dechex($blue + $delta),-2);
  324.             if ( isset($gradients[$new_hex]) )
  325.             {
  326.                 return $gradients[$new_hex];
  327.             }
  328.         }
  329.  
  330.         return $hex;
  331.     }
  332. }
  333. ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement