Passed
Branch master (eaaf18)
by compolom
03:27 queued 01:32
created

Imagick::grayscale()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
nc 1
cc 1
eloc 3
nop 0
1
<?php declare(strict_types=1);
2
3
namespace Compolomus\Compomage;
4
5
use Compolomus\Compomage\Interfaces\ImageInterface;
6
7
class Imagick extends AbstractImage implements ImageInterface
8
{
9
    /**
10
     * Imagick constructor.
11
     * @param string $image
12
     * @throws \Exception
13
     */
14
    public function __construct(string $image)
15
    {
16
        $this->init($image);
17
    }
18
19
    /**
20
     * @param int $width
21
     * @param int $height
22
     * @return ImageInterface
23
     */
24
    public function resize(int $width, int $height): ImageInterface
25
    {
26
        $this->getImage()->scaleImage($width, $height, false);
27
        $this->setSizes();
28
29
        return $this;
30
    }
31
32
    /**
33
     * @param int $angle
34
     * @return ImageInterface
35
     */
36
    public function rotate(int $angle = 90): ImageInterface
37
    {
38
        $this->getImage()->rotateImage(new \ImagickPixel('transparent'), $angle);
39
        $this->setSizes();
40
41
        return $this;
42
    }
43
44
    /**
45
     * @return ImageInterface
46
     */
47
    public function flip(): ImageInterface
48
    {
49
        $this->getImage()->flipImage();
50
51
        return $this;
52
    }
53
54
    /**
55
     * @return ImageInterface
56
     */
57
    public function flop(): ImageInterface
58
    {
59
        $this->getImage()->flopImage();
60
61
        return $this;
62
    }
63
64
    public function grayscale(): ImageInterface
65
    {
66
        $this->getImage()->modulateImage(100, 0, 100);
67
68
        return $this;
69
    }
70
71
    /**
72
     * @param string $text
73
     * @param string $position
74
     * @param string $font
75
     * @return $this
76
     * @throws \Exception
77
     */
78
    public function copyright(string $text, string $font = 'Courier', string $position = 'SouthWest')
79
    {
80
        $positions = [
81
            'NORTHWEST' => \Imagick::GRAVITY_NORTHWEST,
82
            'NORTH' => \Imagick::GRAVITY_NORTH,
83
            'NORTHEAST' => \Imagick::GRAVITY_NORTHEAST,
84
            'WEST' => \Imagick::GRAVITY_WEST,
85
            'CENTER' => \Imagick::GRAVITY_CENTER,
86
            'SOUTHWEST' => \Imagick::GRAVITY_SOUTHWEST,
87
            'SOUTH' => \Imagick::GRAVITY_SOUTH,
88
            'SOUTHEAST' => \Imagick::GRAVITY_SOUTHEAST,
89
            'EAST' => \Imagick::GRAVITY_EAST
90
        ];
91
        if (!\in_array($font, $this->getFontsList(), true)) {
92
            throw new \InvalidArgumentException('Does not support font');
93
        }
94
        if (!array_key_exists(strtoupper($position), $positions)) {
95
            throw new \InvalidArgumentException('Wrong position');
96
        }
97
        $this->getImage()->compositeImage($this->prepareImage($text, $positions[strtoupper($position)], $font),
98
            \Imagick::COMPOSITE_DISSOLVE, 0, 0);
99
100
        return $this;
101
    }
102
103
    public function getFontsList(): array
104
    {
105
        return $this->getImage()->queryFonts();
106
    }
107
108
    /**
109
     * @param string $text
110
     * @param int $position
111
     * @param string $font
112
     * @return \Imagick
113
     * @throws \ImagickException
114
     */
115
    private function prepareImage(string $text, int $position, string $font): \Imagick
116
    {
117
        $image = new \Imagick();
118
        $mask = new \Imagick();
119
        $draw = new \ImagickDraw();
120
        $image->newImage($this->getWidth(), $this->getHeight(), new \ImagickPixel('grey30'));
121
        $mask->newImage($this->getWidth(), $this->getHeight(), new \ImagickPixel('black'));
122
        $draw->setFont($font);
123
        $draw->setFontSize(20);
124
        $draw->setFillColor(new \ImagickPixel('grey70'));
125
        $draw->setGravity($position);
126
        $image->annotateImage($draw, 10, 12, 0, $text);
127
        $draw->setFillColor(new \ImagickPixel('white'));
128
        $mask->annotateImage($draw, 11, 13, 0, $text);
129
        $mask->annotateImage($draw, 10, 12, 0, $text);
130
        $draw->setFillColor(new \ImagickPixel('black'));
131
        $mask->annotateImage($draw, 9, 11, 0, $text);
132
        $mask->setImageMatte(false);
133
        $image->compositeImage($mask, \Imagick::COMPOSITE_COPYOPACITY, 0, 0);
134
135
        return $image;
136
    }
137
138
    /**
139
     * @param int $width
140
     * @param int $height
141
     * @param int $startX
142
     * @param int $startY
143
     * @return ImageInterface
144
     */
145
    public function crop(int $width, int $height, int $startX, int $startY): ImageInterface
146
    {
147
        $this->getImage()->cropImage($width, $height, $startX, $startY);
148
        $this->setSizes();
149
150
        return $this;
151
    }
152
153
    public function save(string $filename): bool
154
    {
155
        return true;
156
    }
157
158
    public function __toString(): string
159
    {
160
        return $this->getImage()->getImageBlob();
161
    }
162
163
    /**
164
     * @param string $source
165
     * @return ImageInterface
166
     * @throws \Exception
167
     */
168
    protected function tmp(string $source): ImageInterface
169
    {
170
        $image = new \Imagick;
171
        if ($image->readImageBlob($source)) {
172
            if ($image->getImageAlphaChannel() !== \Imagick::ALPHACHANNEL_ACTIVATE) {
173
                $image->setImageAlphaChannel(\Imagick::ALPHACHANNEL_SET);
174
            }
175
        }
176
        $background = $this->newImage($image->getImageWidth(), $image->getImageHeight());
177
        $image->compositeImage($background, \imagick::COMPOSITE_OVER, 0, 0); //Imagick::COMPOSITE_DISSOLVE
178
        $this->setImage($image);
179
        $this->getImage()->setFormat('png'); // save transparent
180
        $this->setSizes();
181
182
        return $this;
183
    }
184
185
    /**
186
     * @param int $width
187
     * @param int $height
188
     * @return \Imagick
189
     * @throws \ImagickException
190
     */
191
    private function newImage(int $width, int $height): \Imagick
192
    {
193
        $background = new \Imagick;
194
        $background->newImage($width, $height, new \ImagickPixel('transparent'));
195
        $background->setImageBackgroundColor(new \ImagickPixel('transparent'));
196
197
        return $background;
198
    }
199
200
    protected function setSizes(): void
201
    {
202
        $args = $this->getImage()->getImageGeometry();
203
        $this->setWidth($args['width']);
204
        $this->setHeight($args['height']);
205
    }
206
207
    /**
208
     * @param Image $watermark
209
     * @param int $x
210
     * @param int $y
211
     * @return ImageInterface
212
     * @throws \Exception
213
     */
214
    protected function prepareWatermark(Image $watermark, int $x, int $y): ImageInterface
215
    {
216
        $watermark->getImage()->evaluateImage(\Imagick::EVALUATE_MULTIPLY, 1, \Imagick::CHANNEL_ALPHA);
0 ignored issues
show
Documentation Bug introduced by
The method evaluateImage does not exist on object<Compolomus\Compomage\Image>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
217
        $this->getImage()->compositeImage($watermark->getImage(), \Imagick::COMPOSITE_DISSOLVE, $x, $y);
218
219
        return $this;
220
    }
221
}
222