Passed
Push — master ( 4ba812...5a08e6 )
by compolom
02:04
created

Imagick::tmp()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 16
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

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