/** * Calculate histograms for each color channel for the given image */ function GetImageHistogram($image_file, $options, $histograms) { $histogram = null; $ext = strripos($image_file, '.jpg'); if ($ext !== false) { $histogram_file = substr($image_file, 0, $ext) . '.hist'; } else { $ext = strripos($image_file, '.png'); if ($ext !== false) { $histogram_file = substr($image_file, 0, $ext) . '.hist'; } } if (isset($histograms)) { // figure out the timestamp for the video frame in ms $ms = null; if (preg_match('/ms_(?P<ms>[0-9]+)\\.(png|jpg)/i', $image_file, $matches)) { $ms = intval($matches['ms']); } elseif (preg_match('/frame_(?P<ms>[0-9]+)\\.(png|jpg)/i', $image_file, $matches)) { $ms = intval($matches['ms']) * 100; } foreach ($histograms as &$hist) { if (isset($hist['histogram']) && isset($hist['time']) && $hist['time'] == $ms) { $histogram = $hist['histogram']; break; } } } // See if we have the old-style histograms (separate files) if (!isset($histogram) && !isset($options) && isset($histogram_file) && is_file($histogram_file)) { $histogram = json_decode(file_get_contents($histogram_file), true); if (!is_array($histogram) || !array_key_exists('r', $histogram) || !array_key_exists('g', $histogram) || !array_key_exists('b', $histogram) || count($histogram['r']) != 256 || count($histogram['g']) != 256 || count($histogram['b']) != 256) { unset($histogram); } } // generate a histogram from the image itself if (!isset($histogram)) { $im = imagecreatefromjpeg($image_file); if ($im !== false) { $width = imagesx($im); $height = imagesy($im); if ($width > 0 && $height > 0) { // default a resample to 1/4 in each direction which will significantly speed up processing with minimal impact to accuracy. // This is only for calculations done on the server. Histograms from the client look at every pixel $resample = 8; if (isset($options) && array_key_exists('resample', $options)) { $resample = $options['resample']; } if ($resample > 2) { $oldWidth = $width; $oldHeight = $height; $width = intval($width * 2 / $resample); $height = intval($height * 2 / $resample); $tmp = imagecreatetruecolor($width, $height); fastimagecopyresampled($tmp, $im, 0, 0, 0, 0, $width, $height, $oldWidth, $oldHeight, 3); imagedestroy($im); $im = $tmp; unset($tmp); } $histogram = array(); $histogram['r'] = array(); $histogram['g'] = array(); $histogram['b'] = array(); $buckets = 256; if (isset($options) && array_key_exists('buckets', $options) && $options['buckets'] >= 1 && $options['buckets'] <= 256) { $buckets = $options['buckets']; } for ($i = 0; $i < $buckets; $i++) { $histogram['r'][$i] = 0; $histogram['g'][$i] = 0; $histogram['b'][$i] = 0; } for ($y = 0; $y < $height; $y++) { for ($x = 0; $x < $width; $x++) { $rgb = ImageColorAt($im, $x, $y); $r = $rgb >> 16 & 0xff; $g = $rgb >> 8 & 0xff; $b = $rgb & 0xff; // ignore white pixels if ($r != 255 || $g != 255 || $b != 255) { if (isset($options) && array_key_exists('colorSpace', $options) && $options['colorSpace'] != 'RGB') { if ($options['colorSpace'] == 'HSV') { RGB_TO_HSV($r, $g, $b); } elseif ($options['colorSpace'] == 'YUV') { RGB_TO_YUV($r, $g, $b); } } $bucket = (int) (($r + 1.0) / 256.0 * $buckets) - 1; $histogram['r'][$bucket]++; $bucket = (int) (($g + 1.0) / 256.0 * $buckets) - 1; $histogram['g'][$bucket]++; $bucket = (int) (($b + 1.0) / 256.0 * $buckets) - 1; $histogram['b'][$bucket]++; } } } } imagedestroy($im); unset($im); } if (!isset($options) && isset($histogram_file) && !is_file($histogram_file) && isset($histogram)) { file_put_contents($histogram_file, json_encode($histogram)); } } return $histogram; }
/** * Calculate a RGB histogram excluding white pixels * * @param mixed $image_file * @param mixed $ignoreWhite - bool - should white pixels be ignored * @param mixed $colorSpace - string - RGB, HSV or YUV */ function Histogram($image_file, $ignoreWhite, $colorSpace = 'RGB') { global $viewport; $histogram = null; $nowhite = $ignoreWhite ? '.nowhite' : ''; $histogram_file = "{$image_file}{$nowhite}.{$colorSpace}.hist"; if (is_file($histogram_file)) { $histogram = json_decode(file_get_contents($histogram_file)); } else { $im = imagecreatefrompng($image_file); if ($im !== false) { $right = imagesx($im); $bottom = imagesy($im); $left = 0; $top = 0; if (isset($viewport)) { $left = $viewport['x']; $top = $viewport['y']; $right = $left + $viewport['width']; $bottom = $top + $viewport['height']; } $histogram = array(array(), array(), array()); $buckets = 256; for ($i = 0; $i < $buckets; $i++) { $histogram[0][$i] = 0; $histogram[1][$i] = 0; $histogram[2][$i] = 0; } for ($y = $top; $y < $bottom; $y++) { for ($x = $left; $x < $right; $x++) { $rgb = ImageColorAt($im, $x, $y); $r = $rgb >> 16 & 0xff; $g = $rgb >> 8 & 0xff; $b = $rgb & 0xff; // ignore white pixels if (!$ignoreWhite || $r != 255 || $g != 255 || $b != 255) { if ($colorSpace == 'HSV') { RGB_TO_HSV($r, $g, $b); } elseif ($colorSpace == 'YUV') { RGB_TO_YUV($r, $g, $b); } $histogram[0][$r]++; $histogram[1][$g]++; $histogram[2][$b]++; } } } imagedestroy($im); unset($im); file_put_contents($histogram_file, json_encode($histogram)); } } return $histogram; }