Image::writeText()   A
last analyzed

Complexity

Conditions 4
Paths 8

Size

Total Lines 17
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 4
eloc 9
c 2
b 0
f 0
nc 8
nop 4
dl 0
loc 17
ccs 0
cts 10
cp 0
crap 20
rs 9.9666
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Suricate;
6
7
class Image
8
{
9
    use Traits\ImageFilter;
10
11
    public $source;
12
    private $destination;
13
14
    private $width;
15
    private $height;
16
17
    public function load($filename)
18
    {
19
        if (is_file($filename) && ($imgString = file_get_contents($filename))) {
20
            $imgString = imagecreatefromstring($imgString);
21
            if ($imgString !== false) {
22
                $this->source = $imgString;
23
                $this->destination = $this->source;
24
                $this->width = imagesx($this->source);
25
                $this->height = imagesy($this->source);
26
27
                return $this;
28
            }
29
30
            throw new \InvalidArgumentException(
31
                'Cannot load ' . $filename . ', not an image'
32
            );
33
        }
34
35
        throw new \InvalidArgumentException(
36
            'Cannot load ' . $filename . ', file unreadable'
37
        );
38
    }
39
40
    public function getWidth()
41
    {
42
        return $this->width;
43
    }
44
45
    public function getHeight()
46
    {
47
        return $this->height;
48
    }
49
50
    public function isPortrait()
51
    {
52
        return $this->width < $this->height;
53
    }
54
55
    public function isLandscape()
56
    {
57
        return $this->height < $this->width;
58
    }
59
60
    public function chain()
61
    {
62
        $this->source = $this->destination;
63
        $this->width = imagesx($this->source);
64
        $this->height = imagesy($this->source);
65
66
        return $this;
67
    }
68
69
    public function resize($width = null, $height = null)
70
    {
71
        if ($this->source) {
72
            if ($width == null) {
73
                $width = intval(
74
                    round(($height / $this->height) * $this->width, 0)
75
                );
76
            } elseif ($height == null) {
77
                $height = intval(
78
                    round(($width / $this->width) * $this->height, 0)
79
                );
80
            }
81
82
            $this->destination = imagecreatetruecolor($width, $height);
83
            if ($this->destination === false) {
84
                throw new \RuntimeException("Can't create destination image");
85
            }
86
            imagecopyresampled(
87
                $this->destination,
88
                $this->source,
89
                0,
90
                0,
91
                0,
92
                0,
93
                $width,
94
                $height,
95
                $this->width,
96
                $this->height
97
            );
98
99
            return $this->chain();
100
        }
101
        return $this;
102
    }
103
104
    public function crop($width, $height)
105
    {
106
        $centerX = round($this->width / 2);
107
        $centerY = round($this->height / 2);
108
109
        $cropWidthHalf = round($width / 2);
110
        $cropHeightHalf = round($height / 2);
111
112
        $x1 = intval(max(0, $centerX - $cropWidthHalf));
113
        $y1 = intval(max(0, $centerY - $cropHeightHalf));
114
115
        $this->destination = imagecreatetruecolor($width, $height);
116
        if ($this->destination === false) {
117
            throw new \RuntimeException("Can't create destination image");
118
        }
119
        imagecopy(
120
            $this->destination,
121
            $this->source,
122
            0,
123
            0,
124
            $x1,
125
            $y1,
126
            $width,
127
            $height
128
        );
129
130
        return $this->chain();
131
    }
132
133
    public function resizeCanvas(
134
        $width,
135
        $height,
136
        $position = null,
137
        $color = [0, 0, 0]
138
    ) {
139
        $this->destination = imagecreatetruecolor($width, $height);
140
        if ($this->destination === false) {
141
            throw new \RuntimeException("Can't create destination image");
142
        }
143
        $colorRes = imagecolorallocate(
144
            $this->destination,
145
            $color[0],
146
            $color[1],
147
            $color[2]
148
        );
149
        $imageObj = new Image();
150
        $imageObj->width = $width;
151
        $imageObj->height = $height;
152
        imagefill($this->destination, 0, 0, $colorRes);
153
154
        if ($position !== null) {
155
            list($x, $y) = $imageObj->getCoordinatesFromString(
156
                $position,
157
                $this->width,
158
                $this->height
159
            );
160
        } else {
161
            $x = 0;
162
            $y = 0;
163
        }
164
        imagecopy(
165
            $this->destination,
166
            $this->source,
167
            $x,
168
            $y,
169
            0,
170
            0,
171
            $this->width,
172
            $this->height
173
        );
174
175
        return $this->chain();
176
    }
177
178
    public function rotate()
179
    {
180
    }
181
182
    public function mirror()
183
    {
184
    }
185
186
    public function flip()
187
    {
188
    }
189
190
    public function merge(
191
        $source,
192
        $position = null,
193
        $x = null,
194
        $y = null,
195
        $percent = 100
196
    ) {
197
        if ($source instanceof \Suricate\Image) {
198
        } else {
199
            $source = with(new Image())->load($source);
200
        }
201
202
        if ($position !== null) {
203
            list($x, $y) = $this->getCoordinatesFromString(
204
                $position,
205
                $source->width,
206
                $source->height
207
            );
208
        }
209
        $x = $x !== null ? $x : 0;
210
        $y = $y !== null ? $y : 0;
211
212
        // Handle transparent image
213
        // creating a cut resource
214
        $cut = imagecreatetruecolor($source->getWidth(), $source->getHeight());
215
        if ($cut === false) {
216
            throw new \RuntimeException("Can't create destination image");
217
        }
218
        // copying relevant section from background to the cut resource
219
        imagecopy(
220
            $cut,
221
            $this->destination,
222
            0,
223
            0,
224
            $x,
225
            $y,
226
            $source->getWidth(),
227
            $source->getHeight()
228
        );
229
230
        // copying relevant section from watermark to the cut resource
231
        imagecopy(
232
            $cut,
233
            $source->source,
234
            0,
235
            0,
236
            0,
237
            0,
238
            $source->getWidth(),
239
            $source->getHeight()
240
        );
241
242
        imagecopymerge(
243
            $this->destination,
244
            $cut,
245
            $x,
246
            $y,
247
            0,
248
            0,
249
            $source->getWidth(),
250
            $source->getHeight(),
251
            $percent
252
        );
253
254
        return $this->chain();
255
    }
256
257
    public function writeText($text, $x = 0, $y = 0, \Closure $callback = null)
258
    {
259
        if ($x < 0) {
260
            $x = $this->width + $x;
261
        }
262
        if ($y < 0) {
263
            $y = $this->height + $y;
264
        }
265
        $imageFont = new ImageFont($text);
266
267
        if ($callback != null) {
268
            $callback($imageFont);
269
        }
270
271
        $imageFont->apply($this->source, $x, $y);
272
273
        return $this;
274
    }
275
276
    public function line($x1, $y1, $x2, $y2, \Closure $callback = null)
277
    {
278
        $imageShape = new ImageShape();
279
        $imageShape->setImage($this->source);
280
        if ($callback != null) {
281
            $callback($imageShape);
282
        }
283
284
        $imageShape->drawLine($x1, $y1, $x2, $y2);
285
286
        return $this;
287
    }
288
289
    public function save($filename, $outputType = null, $quality = 70)
290
    {
291
        $result = false;
292
        if ($outputType === null) {
293
            $extension = pathinfo($filename, PATHINFO_EXTENSION);
294
        } else {
295
            $extension = $outputType;
296
        }
297
        if ($extension !== false) {
298
            switch (strtolower($extension)) {
299
                case 'jpg':
300
                case 'jpeg':
301
                    $result = imagejpeg($this->source, $filename, $quality);
302
                    break;
303
                case 'png':
304
                    $result = imagepng($this->source, $filename);
305
                    break;
306
                case 'gif':
307
                    $result = imagegif($this->source, $filename);
308
                    break;
309
            }
310
        }
311
312
        return $result;
313
    }
314
315
    private function getCoordinatesFromString(
316
        $position,
317
        $offsetWidth = 0,
318
        $offsetHeight = 0
319
    ) {
320
        switch ($position) {
321
            case 'top':
322
                $x = floor($this->width / 2 - $offsetWidth / 2);
323
                $y = 0;
324
                break;
325
            case 'top-right':
326
                $x = $this->width - $offsetWidth;
327
                $y = 0;
328
                break;
329
            case 'left':
330
                $x = 0;
331
                $y = floor($this->height / 2 - $offsetHeight / 2);
332
                break;
333
            case 'center':
334
                $x = floor($this->width / 2 - $offsetWidth / 2);
335
                $y = floor($this->height / 2 - $offsetHeight / 2);
336
                break;
337
            case 'right':
338
                $x = $this->width - $offsetWidth;
339
                $y = floor($this->height / 2 - $offsetHeight / 2);
340
                break;
341
            case 'bottom-left':
342
                $x = 0;
343
                $y = $this->height - $offsetHeight;
344
                break;
345
            case 'bottom':
346
                $x = floor($this->width / 2 - $offsetWidth / 2);
347
                $y = $this->height - $offsetHeight;
348
                break;
349
            case 'bottom-right':
350
                $x = $this->width - $offsetWidth;
351
                $y = $this->height - $offsetHeight;
352
                break;
353
354
            case 'top-left':
355
            default:
356
                $x = 0;
357
                $y = 0;
358
                break;
359
        }
360
361
        return [intval($x), intval($y)];
362
    }
363
}
364