Resizer::resizeAndCrop()   C
last analyzed

Complexity

Conditions 11
Paths 88

Size

Total Lines 86
Code Lines 59

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 11
eloc 59
nc 88
nop 0
dl 0
loc 86
rs 6.7478
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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