Passed
Branch master (d2dc0d)
by compolom
04:15 queued 01:44
created

Imagick::getImage()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

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