> ------------------------------------------------------------------------------ See main.inc.php for release information Provided classes : --------------------------------------------------------------------------- */ if(!defined('PHPWG_ROOT_PATH')) die('Hacking attempt!'); class Histogram { static public $fileHistogram = Array( 'pixels' => 0, 'analyzed' => 0, 'time' => 0, 'fileName' => "", ); /** * returns histogram values for an image * * * @param String $fileName : the picture's filename * @return : -1 if file doesn't exist * -2 if file is not a PNG, a JPEG or a GIF file * -3 if a fatal error occurs * Array of L, R, G, and B values (% for values from 0 to 255) */ static function read($fileName) { self::$fileHistogram=Array( 'pixels' => 0, 'analyzed' => 0, 'time' => 0, 'pps' =>0, ); $returned=array( 'L' => array(), 'A' => array(), 'M' => array(), 'R' => array(), 'G' => array(), 'B' => array() ); for($i=0;$i<256;$i++) { $returned['L'][$i]=0; $returned['A'][$i]=0; $returned['M'][$i]=0; $returned['R'][$i]=0; $returned['G'][$i]=0; $returned['B'][$i]=0; } if(file_exists($fileName)) { $time=microtime(true); try { if(preg_match('/.*\.gif$/i', $fileName)) { $image = imagecreatefromgif($fileName); } elseif(preg_match('/.*\.(jpg|jpeg)$/i', $fileName)) { $image = imagecreatefromjpeg($fileName); } elseif(preg_match('/.*\.png$/i', $fileName)) { $image = imagecreatefrompng($fileName); } else { return(-2); } $imageWidth=imagesx($image); $imageHeight=imagesy($image); $i=0; for($px=0;$px<$imageWidth;$px++) { for($py=0;$py<$imageHeight;$py++) { $i++; $value=imagecolorat($image, $px, $py); $rgb=self::IntToRGB($value); $l=self::RGBtoL($rgb); $a=self::RGBtoA($rgb); $m=self::RGBtoM($rgb); $returned['L'][$l]++; $returned['A'][$a]++; $returned['M'][$m]++; $returned['R'][$rgb['R']]++; $returned['G'][$rgb['G']]++; $returned['B'][$rgb['B']]++; unset($rgb); } } imagedestroy($image); self::$fileHistogram=Array( 'pixels' => $imageWidth*$imageHeight, 'analyzed' => $i, 'time' => microtime(true)-$time, 'pps' => $i/(microtime(true)-$time), ); ksort($returned['L']); ksort($returned['A']); ksort($returned['M']); ksort($returned['R']); ksort($returned['G']); ksort($returned['B']); foreach($returned as $key => $val) { $m=max($returned[$key]); foreach($returned[$key] as $key2 => $val2) { $returned[$key][$key2]=round($val2/$m,4); } } return($returned); } catch (Exception $e) { //echo "ERROR!
".print_r($e, true); return(-3); } } else { return(-1); } } /** * build the histogram and save it in an image file * * @param String $fileName : the histogram filename * @param Array $values : array('L', 'R', 'G', 'B') of values * @param Array $options : array of options for histogram rendering * 'color_bg' : background color * 'color_l' : color for luminance drawing * 'color_r' : color for red drawing * 'color_g' : color for green drawing * 'color_b' : color for blue drawing * 'color_ticks' : color for ticks drawing * 'mode_l' : drawing mode for luminance * 'mode_r' : drawing mode for luminance * 'mode_g' : drawing mode for luminance * 'mode_b' : drawing mode for luminance * => modes can takes 'line' or 'bar' or 'surface' or 'none' values * 'mode_ticks_h' : drawing mode for horizontal ticks * 'mode_ticks_v' : drawing mode for vertical ticks * => can takes 'none' or 'dot' or 'solid' * 'histo_width' : histogram width * 'histo_height' : histogram height */ static function build($fileName, $values, $options=array()) { $options=self::checkHistoOptions($options); $image=imagecreatetruecolor($options['histo_width'], $options['histo_height']); $options['color_bg']=self::colorAllocate($image, $options['color_bg']); $options['color_v']=self::colorAllocate($image, $options['color_v']); $options['color_r']=self::colorAllocate($image, $options['color_r']); $options['color_g']=self::colorAllocate($image, $options['color_g']); $options['color_b']=self::colorAllocate($image, $options['color_b']); imagefilledrectangle($image,0,0,$options['histo_width'], $options['histo_height'], $options['color_bg']); $histoList=array('v', 'r', 'g', 'b'); foreach($histoList as $histo) { switch($options['mode_'.$histo]) { case 'line': case 'surface': $points=array(0,$options['histo_height']); if($histo=='v') { $histoKey=$options['histo_method']; } else { $histoKey=$histo; } foreach($values[strtoupper($histoKey)] as $key => $histoValue) { $points[]=$key * $options['histo_width']/255; $points[]=$options['histo_height'] - $histoValue * $options['histo_height']; } $points[]=$options['histo_width']; $points[]=$options['histo_height']; if($options['mode_'.$histo]=='line') { imagepolygon($image,$points, count($points)/2, $options['color_'.$histo]); } else { imagefilledpolygon($image,$points, count($points)/2, $options['color_'.$histo]); } break; case 'bar': break; } } imagepng($image, $fileName); imagedestroy($image); } /** * Calculate the Luminance value from a RGB value * * @param Array $RGB : RGB object * @return Integer : luminance color */ static public function RGBtoL($RGB) { return(round($RGB['R']*0.299+$RGB['G']*0.587+$RGB['B']*0.114,0)); } /** * Calculate the average grey value from a RGB value * * @param Array $RGB : RGB object * @return Integer : average grey color */ static public function RGBtoA($RGB) { return(round(($RGB['R']+$RGB['G']+$RGB['B'])/3,0)); } /** * Calculate the max value from a RGB value * * @param Array $RGB : RGB object * @return Integer : the max value */ static public function RGBtoM($RGB) { return(max($RGB)); } /** * * @param Int $rgb : an integer &hRRGGBB * @return RGB : a RGB object */ static public function IntToRGB($rgb) { return( Array( 'R' => ($rgb >> 16) & 0xFF, 'G' => ($rgb >> 8) & 0xFF, 'B' => $rgb & 0xFF ) ); } /** * convert a string like #rrggbb into a RGB array * * @param String $rgb : a #rrggbb string * @return Array */ static public function StringToRGB($rgb) { $returned=array( 'R' => 0, 'G' => 0, 'B' => 0 ); if(preg_match_all('/^#([A-F0-9]{2})([A-F0-9]{2})([A-F0-9]{2})$/i', $rgb, $values, PREG_SET_ORDER)>0) { $returned['R']=intval('0x'.$values[0][1],0); $returned['G']=intval('0x'.$values[0][2],0); $returned['B']=intval('0x'.$values[0][3],0); } return($returned); } /** * convert a RGB array ('R'=>r, 'G'=>g, 'B'=>b ) into integer value * * @param Array $rgb : rgb array * @return Integer */ static public function RGBToInt($rgb) { return($rgb['R']*65536 + $rgb['G']*256 + $rgb['B']); } /** * convert a RGB array ('R'=>r, 'G'=>g, 'B'=>b ) into string #rrggbb value * * @param Array $rgb : rgb array * @return String */ static public function RGBToString($rgb) { return( sprintf('#%02X%02X%02X', $rgb['R'], $rgb['G'], $rgb['B']) ); } static public function checkHistoOptions($options) { if(!isset($options['color_bg']) or !is_numeric($options['color_bg'])) $options['color_bg']=0xffffff; if(!isset($options['color_v']) or !is_numeric($options['color_v'])) $options['color_v']=0x808080; if(!isset($options['color_r']) or !is_numeric($options['color_r'])) $options['color_r']=0xA00000; if(!isset($options['color_g']) or !is_numeric($options['color_g'])) $options['color_g']=0x00A000; if(!isset($options['color_b']) or !is_numeric($options['color_b'])) $options['color_b']=0x0000A0; $modes=array('surface', 'line', 'bar', 'none'); if(!isset($options['mode_v']) or !in_array($options['mode_v'], $modes)) $options['mode_v']='surface'; if(!isset($options['mode_r']) or !in_array($options['mode_r'], $modes)) $options['mode_r']='line'; if(!isset($options['mode_g']) or !in_array($options['mode_g'], $modes)) $options['mode_g']='line'; if(!isset($options['mode_b']) or !in_array($options['mode_b'], $modes)) $options['mode_b']='line'; if(!isset($options['histo_width']) or !is_numeric($options['histo_width']) or $options['histo_width']<=0) $options['histo_width']=256; if(!isset($options['histo_height']) or !is_numeric($options['histo_height']) or $options['histo_height']<=0) $options['histo_height']=100; if(!isset($options['histo_method']) or !in_array($options['histo_method'], array('L', 'A', 'M'))) $options['histo_method']='L'; return($options); } static public function colorAllocate($im, $color) { $rgb=self::IntToRGB($color); return(imagecolorallocate($im, $rgb['R'], $rgb['G'], $rgb['B'])); } static public function colorAllocateA($im, $color, $alpha) { $rgb=self::IntToRGB($color); return(imagecolorallocatealpha($im, $rgb['R'], $rgb['G'], $rgb['B'], $alpha)); } } ?>