Passed
Pull Request — master (#81)
by Michael
02:58
created

class/Common/Resizer.php (2 issues)

1
<?php
2
3
declare(strict_types=1);
4
5
namespace XoopsModules\Yogurt\Common;
6
7
/*
8
 You may not change or alter any portion of this comment or credits
9
 of supporting developers from this source code or any supporting source code
10
 which is considered copyrighted (c) material of the original comment or credit authors.
11
12
 This program is distributed in the hope that it will be useful,
13
 but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
*/
16
17
/**
18
 * Image resizer class for xoops
19
 *
20
 * @copyright      2000-2020 XOOPS Project (https://xoops.org)
21
 * @license        GPL 2.0 or later
22
 * @package        XOOPS common
23
 * @since          1.0
24
 * @min_xoops      2.5.9
25
 * @author         Goffy - Wedega - Email:<[email protected]> - Website:<https://wedega.com>
26
 */
27
class Resizer
28
{
29
    public $sourceFile = '';
30
31
    public $endFile = '';
32
33
    public $maxWidth = 0;
34
35
    public $maxHeight = 0;
36
37
    public $imageMimetype = '';
38
39
    public $jpgQuality = 90;
40
41
    public $mergeType = 0;
42
43
    public $mergePos = 0;
44
45
    public $degrees = 0;
46
47
    public $error = '';
48
49
    /**
50
     * resize image if size exceed given width/height
51
     * @return string|bool
52
     */
53
54
    public function resizeImage()
55
    {
56
        // check file extension
57
58
        switch ($this->imageMimetype) {
59
            case 'image/png':
60
                $img = \imagecreatefrompng($this->sourceFile);
61
                break;
62
            case 'image/jpeg':
63
                $img = \imagecreatefromjpeg($this->sourceFile);
64
                if (!$img) {
65
                    $img = \imagecreatefromstring(file_get_contents($this->sourceFile));
66
                }
67
                break;
68
            case 'image/gif':
69
                $img = \imagecreatefromgif($this->sourceFile);
70
                break;
71
            default:
72
                return 'Unsupported format';
73
        }
74
75
        $width = \imagesx($img);
76
77
        $height = \imagesy($img);
78
79
        if ($width > $this->maxWidth || $height > $this->maxHeight) {
80
            // recalc image size based on this->maxWidth/this->maxHeight
81
82
            if ($width > $height) {
83
                if ($width < $this->maxWidth) {
84
                    $newWidth = $width;
85
                } else {
86
                    $newWidth = $this->maxWidth;
87
88
                    $divisor = $width / $newWidth;
89
90
                    $newHeight = (int)\floor($height / $divisor);
91
                }
92
            } elseif ($height < $this->maxHeight) {
93
                $newHeight = (int)$height;
94
            } else {
95
                $newHeight = $this->maxHeight;
96
97
                $divisor = $height / $newHeight;
98
99
                $newWidth = (int)\floor($width / $divisor);
100
            }
101
102
            // Create a new temporary image.
103
104
            $tmpimg = \imagecreatetruecolor($newWidth, $newHeight);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $newWidth does not seem to be defined for all execution paths leading up to this point.
Loading history...
Comprehensibility Best Practice introduced by
The variable $newHeight does not seem to be defined for all execution paths leading up to this point.
Loading history...
105
106
            imagealphablending($tmpimg, false);
107
108
            imagesavealpha($tmpimg, true);
109
110
            // Copy and resize old image into new image.
111
112
            \imagecopyresampled(
113
                $tmpimg,
114
                $img,
115
                0,
116
                0,
117
                0,
118
                0,
119
                $newWidth,
120
                $newHeight,
121
                $width,
122
                $height
123
            );
124
125
            \unlink($this->endFile);
126
127
            //compressing the file
128
129
            switch ($this->imageMimetype) {
130
                case 'image/png':
131
                    \imagepng($tmpimg, $this->endFile, 0);
132
                    break;
133
                case 'image/jpeg':
134
                    \imagejpeg($tmpimg, $this->endFile, 100);
135
                    break;
136
                case 'image/gif':
137
                    \imagegif($tmpimg, $this->endFile);
138
                    break;
139
            }
140
141
            // release the memory
142
143
            \imagedestroy($tmpimg);
144
        } else {
145
            return 'copy';
146
        }
147
148
        \imagedestroy($img);
149
150
        return true;
151
    }
152
153
    /**
154
     * @return bool|string
155
     */
156
157
    public function resizeAndCrop()
158
    {
159
        // check file extension
160
161
        switch ($this->imageMimetype) {
162
            case 'image/png':
163
                $original = \imagecreatefrompng($this->sourceFile);
164
                break;
165
            case 'image/jpeg':
166
                $original = \imagecreatefromjpeg($this->sourceFile);
167
                break;
168
            case 'image/gif':
169
                $original = \imagecreatefromgif($this->sourceFile);
170
                break;
171
            default:
172
                return 'Unsupported format';
173
        }
174
175
        if (!$original) {
176
            return false;
177
        }
178
179
        // GET ORIGINAL IMAGE DIMENSIONS
180
181
        [$original_w, $original_h] = \getimagesize($this->sourceFile);
182
183
        // RESIZE IMAGE AND PRESERVE PROPORTIONS
184
185
        $max_width_resize = $this->maxWidth;
186
187
        $max_height_resize = $this->maxHeight;
188
189
        if ($original_w > $original_h) {
190
            $max_height_ratio = $this->maxHeight / $original_h;
191
192
            $max_width_resize = (int)\round($original_w * $max_height_ratio);
193
        } else {
194
            $max_width_ratio = $this->maxWidth / $original_w;
195
196
            $max_height_resize = (int)\round($original_h * $max_width_ratio);
197
        }
198
199
        if ($max_width_resize < $this->maxWidth) {
200
            $max_height_ratio = $this->maxWidth / $max_width_resize;
201
202
            $max_height_resize = (int)\round($this->maxHeight * $max_height_ratio);
203
204
            $max_width_resize = $this->maxWidth;
205
        }
206
207
        // CREATE THE PROPORTIONAL IMAGE RESOURCE
208
209
        $thumb = \imagecreatetruecolor($max_width_resize, $max_height_resize);
210
211
        if (!\imagecopyresampled(
212
            $thumb,
213
            $original,
214
            0,
215
            0,
216
            0,
217
            0,
218
            $max_width_resize,
219
            $max_height_resize,
220
            $original_w,
221
            $original_h
222
        )) {
223
            return false;
224
        }
225
226
        // CREATE THE CENTERED CROPPED IMAGE TO THE SPECIFIED DIMENSIONS
227
228
        $final = \imagecreatetruecolor(
229
            $this->maxWidth,
230
            $this->maxHeight
231
        );
232
233
        $max_width_offset = 0;
234
235
        $max_height_offset = 0;
236
237
        if ($this->maxWidth < $max_width_resize) {
238
            $max_width_offset = (int)\round(($max_width_resize - $this->maxWidth) / 2);
239
        } else {
240
            $max_height_offset = (int)\round(($max_height_resize - $this->maxHeight) / 2);
241
        }
242
243
        if (!\imagecopy(
244
            $final,
245
            $thumb,
246
            0,
247
            0,
248
            $max_width_offset,
249
            $max_height_offset,
250
            $max_width_resize,
251
            $max_height_resize
252
        )) {
253
            return false;
254
        }
255
256
        // STORE THE FINAL IMAGE - WILL OVERWRITE $this->endFile
257
258
        if (!\imagejpeg(
259
            $final,
260
            $this->endFile,
261
            $this->jpgQuality
262
        )) {
263
            return false;
264
        }
265
266
        return true;
267
    }
268
269
    public function mergeImage()
270
    {
271
        $dest = \imagecreatefromjpeg($this->endFile);
272
273
        $src = \imagecreatefromjpeg($this->sourceFile);
274
275
        if (4 === $this->mergeType) {
276
            $imgWidth = (int)\round($this->maxWidth / 2 - 1);
277
278
            $imgHeight = (int)\round($this->maxHeight / 2 - 1);
279
280
            $posCol2 = (int)\round($this->maxWidth / 2 + 1);
281
282
            $posRow2 = (int)\round($this->maxHeight / 2 + 1);
283
284
            switch ($this->mergePos) {
285
                case 1:
286
                    \imagecopy($dest, $src, 0, 0, 0, 0, $imgWidth, $imgHeight); //top left
287
                    break;
288
                case 2:
289
                    \imagecopy($dest, $src, $posCol2, 0, 0, 0, $imgWidth, $imgHeight); //top right
290
                    break;
291
                case 3:
292
                    \imagecopy($dest, $src, 0, $posRow2, 0, 0, $imgWidth, $imgHeight); //bottom left
293
                    break;
294
                case 4:
295
                    \imagecopy($dest, $src, $posCol2, $posRow2, 0, 0, $imgWidth, $imgHeight); //bottom right
296
                    break;
297
            }
298
        }
299
300
        if (6 === $this->mergeType) {
301
            $imgWidth = (int)\round($this->maxWidth / 3 - 1);
302
303
            $imgHeight = (int)\round($this->maxHeight / 2 - 1);
304
305
            $posCol2 = (int)\round($this->maxWidth / 3 + 1);
306
307
            $posCol3 = $posCol2 + (int)\round($this->maxWidth / 3 + 1);
308
309
            $posRow2 = (int)\round($this->maxHeight / 2 + 1);
310
311
            switch ($this->mergePos) {
312
                case 1:
313
                    \imagecopy($dest, $src, 0, 0, 0, 0, $imgWidth, $imgHeight); //top left
314
                    break;
315
                case 2:
316
                    \imagecopy($dest, $src, $posCol2, 0, 0, 0, $imgWidth, $imgHeight); //top center
317
                    break;
318
                case 3:
319
                    \imagecopy($dest, $src, $posCol3, 0, 0, 0, $imgWidth, $imgHeight); //top right
320
                    break;
321
                case 4:
322
                    \imagecopy($dest, $src, 0, $posRow2, 0, 0, $imgWidth, $imgHeight); //bottom left
323
                    break;
324
                case 5:
325
                    \imagecopy($dest, $src, $posCol2, $posRow2, 0, 0, $imgWidth, $imgHeight); //bottom center
326
                    break;
327
                case 6:
328
                    \imagecopy($dest, $src, $posCol3, $posRow2, 0, 0, $imgWidth, $imgHeight); //bottom right
329
                    break;
330
            }
331
        }
332
333
        \imagejpeg($dest, $this->endFile);
334
335
        \imagedestroy($src);
336
337
        \imagedestroy($dest);
338
    }
339
340
    /**
341
     * @return bool|string
342
     */
343
344
    public function rotateImage()
345
    {
346
        // check file extension
347
348
        switch ($this->imageMimetype) {
349
            case 'image/png':
350
                $original = \imagecreatefrompng($this->sourceFile);
351
                break;
352
            case 'image/jpeg':
353
                $original = \imagecreatefromjpeg($this->sourceFile);
354
                break;
355
            case 'image/gif':
356
                $original = \imagecreatefromgif($this->sourceFile);
357
                break;
358
            default:
359
                return 'Unsupported format';
360
        }
361
362
        if (!$original) {
363
            return false;
364
        }
365
366
        // Rotate
367
368
        $tmpimg = \imagerotate($original, $this->degrees, 0);
369
370
        \unlink($this->endFile);
371
372
        //compressing the file
373
374
        switch ($this->imageMimetype) {
375
            case 'image/png':
376
                if (!\imagepng($tmpimg, $this->endFile, 0)) {
377
                    return false;
378
                }
379
                break;
380
            case 'image/jpeg':
381
                if (!\imagejpeg($tmpimg, $this->endFile, $this->jpgQuality)) {
382
                    return false;
383
                }
384
                break;
385
            case 'image/gif':
386
                if (!\imagegif($tmpimg, $this->endFile)) {
387
                    return false;
388
                }
389
                break;
390
        }
391
392
        // release the memory
393
394
        \imagedestroy($tmpimg);
395
396
        return true;
397
    }
398
}
399