Imbo\Image\Transformation\Histogram::transform PHP Метод

transform() публичный Метод

Transform the image into a histogram
public transform ( Imbo\EventManager\EventInterface $event )
$event Imbo\EventManager\EventInterface
    public function transform(EventInterface $event)
    {
        $image = $event->getArgument('image');
        $params = $event->getArgument('params');
        $scale = !empty($params['scale']) ? max(1, min(8, (int) $params['scale'])) : $this->scale;
        $ratio = !empty($params['ratio']) ? max(0.1, min(8, (double) $params['ratio'])) : $this->ratio;
        // colors to use for each channel when drawing the histogram
        $colors = ['red' => !empty($params['red']) ? $this->formatColor($params['red']) : $this->red, 'green' => !empty($params['green']) ? $this->formatColor($params['green']) : $this->green, 'blue' => !empty($params['blue']) ? $this->formatColor($params['blue']) : $this->blue];
        // channels and their sequence when retrieving statistics
        $vals = ['red', 'green', 'blue'];
        // counts of each color intensity for each channel, initialize to zero
        $counts = [];
        foreach ($vals as $val) {
            $counts[$val] = array_fill(0, 256, 0);
        }
        try {
            // get each unique color in the image and their count
            foreach ($this->imagick->getImageHistogram() as $color) {
                $idx = 0;
                foreach ($color->getColor() as $c) {
                    if (isset($vals[$idx])) {
                        $counts[$vals[$idx++]][$c] += $color->getColorCount();
                    }
                }
            }
            // let's draw a histogram
            $origwidth = 256;
            $width = $origwidth * $scale;
            $height = floor($width / $ratio);
            // drawing surface for the histogram
            $this->imagick->clear();
            $this->imagick->newImage($width, $height, 'black');
            // get the max value across all arrays
            $max = 0;
            foreach ($vals as $val) {
                $max = max($max, max($counts[$val]));
            }
            // scale each count to the max value and the height of the resulting image
            foreach ($vals as $val) {
                $counts[$val] = array_map(function ($a) use($max, $height) {
                    return (int) ($height * $a / $max);
                }, $counts[$val]);
            }
            foreach ($vals as $val) {
                // draw a layer for each channel in the image
                $layer = new Imagick();
                $layer->newImage($width, $height, new ImagickPixel('none'));
                $draw = new ImagickDraw();
                $draw->setStrokeColor(new ImagickPixel($colors[$val]));
                $draw->setStrokeAntialias(false);
                foreach ($counts[$val] as $x => $y) {
                    // draw one vertical line for each value in our bucket
                    // if we want to do a scale factor for AA, we repeat it horizontally
                    $x = $x * $scale;
                    for ($i = 0; $i < $scale; $i++) {
                        $draw->line($x + $i, $height, $x + $i, $height - $y);
                    }
                }
                $layer->drawImage($draw);
                // make each layer slightly transparent and composite it into our end image
                $layer->evaluateImage(Imagick::EVALUATE_DIVIDE, 1.1, Imagick::CHANNEL_ALPHA);
                $this->imagick->compositeImage($layer, Imagick::COMPOSITE_BLEND, 0, 0);
                $layer->clear();
            }
            // set background as transparent before finishing, to allow for proper AA in later
            // transformations
            $this->imagick->transparentPaintImage('black', 0, 0, false);
            $this->imagick->setImageFormat('png');
            // Store the new image
            $size = $this->imagick->getImageGeometry();
            $image->setWidth($size['width'])->setHeight($size['height'])->hasBeenTransformed(true);
        } catch (ImagickException $e) {
            throw new TransformationException($e->getMessage(), 400, $e);
        } catch (ImagickPixelException $e) {
            throw new TransformationException($e->getMessage(), 400, $e);
        }
    }