Passed
Push — master ( 4fa1fd...50ce38 )
by compolom
02:04
created

Imagick::prepareImage()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 22
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

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