• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • Imagick::getImageHistogram()

    (PECL imagick 2.0.0)

    Gets the image histogram

    说明

    Imagick::getImageHistogram(void): array

    Returns the image histogram as an array of ImagickPixel objects.

    返回值

    Returns the image histogram as an array of ImagickPixel objects.

    错误/异常

    错误时抛出 ImagickException。

    范例

    Example #1 Generates Imagick::getImageHistogram()

    <?php
    function getColorStatistics($histogramElements, $colorChannel) {
        $colorStatistics = [];
        foreach ($histogramElements as $histogramElement) {
            $color = $histogramElement->getColorValue($colorChannel);
            $color = intval($color * 255);
            $count = $histogramElement->getColorCount();
            if (array_key_exists($color, $colorStatistics)) {
                $colorStatistics[$color] += $count;
            }
            else {
                $colorStatistics[$color] = $count;
            }
        }
        ksort($colorStatistics);
        
        return $colorStatistics;
    }
        
    function getImageHistogram($imagePath) {
        $backgroundColor = 'black';
        $draw = new \ImagickDraw();
        $draw->setStrokeWidth(0); //make the lines be as thin as possible
        $imagick = new \Imagick();
        $imagick->newImage(500, 500, $backgroundColor);
        $imagick->setImageFormat("png");
        $imagick->drawImage($draw);
        $histogramWidth = 256;
        $histogramHeight = 100; // the height for each RGB segment
        $imagick = new \Imagick(realpath($imagePath));
        //Resize the image to be small, otherwise PHP tends to run out of memory
        //This might lead to bad results for images that are pathologically 'pixelly'
        $imagick->adaptiveResizeImage(200, 200, true);
        $histogramElements = $imagick->getImageHistogram();
        $histogram = new \Imagick();
        $histogram->newpseudoimage($histogramWidth, $histogramHeight * 3, 'xc:black');
        $histogram->setImageFormat('png');
        $getMax = function ($carry, $item)  {
            if ($item > $carry) {
                return $item;
            }
            return $carry;
        };
        $colorValues = [
            'red' => getColorStatistics($histogramElements, \Imagick::COLOR_RED),
            'lime' => getColorStatistics($histogramElements, \Imagick::COLOR_GREEN),
            'blue' => getColorStatistics($histogramElements, \Imagick::COLOR_BLUE),
        ];
        $max = array_reduce($colorValues['red'] , $getMax, 0);
        $max = array_reduce($colorValues['lime'] , $getMax, $max);
        $max = array_reduce($colorValues['blue'] , $getMax, $max);
        $scale =  $histogramHeight / $max;
        $count = 0;
        foreach ($colorValues as $color => $values) {
            $draw->setstrokecolor($color);
            $offset = ($count + 1) * $histogramHeight;
            foreach ($values as $index => $value) {
                $draw->line($index, $offset, $index, $offset - ($value * $scale));
            }
            $count++;
        }
        $histogram->drawImage($draw);
        
        header( "Content-Type: image/png" );
        echo $histogram;
    }
    ?>
    
    Scratched my head for a while trying to figure out why this only returned a list of coloured pixels, and seemingly no colour count. Well it turns out that for some reason, the ImagickPixel class has a "getColorCount" method, which seems a strange place for it but hey.
    <?php
    $image = new Imagick("thing.png");
    $pixels=$image->getImageHistogram();
    foreach($pixels as $p){
     $colors = $p->getColor();
     foreach($colors as $c){
        print( "$c\t" );
     }
     print( "\t:\t" . $p->getColorCount() . "\n" );
    }
    ?>
    This will print out something like:
    252  250  252  1  :  125
    194  156  182  1  :  126
    109  18  79  1  :  11440
    2  117  162  1  :  12761
    255  255  255  1  :  40769
    ...where the colums are red, green, blue, alpha, followed by the number of times that colour appears in the image.