Resizer   B
last analyzed

Complexity

Total Complexity 48

Size/Duplication

Total Lines 270
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 48
eloc 182
c 1
b 0
f 0
dl 0
loc 270
rs 8.5599

4 Methods

Rating   Name   Duplication   Size   Complexity  
C resizeImage() 0 71 13
B resizeAndCrop() 0 64 11
B rotateImage() 0 47 11
C mergeImage() 0 56 13

How to fix   Complexity   

Complex Class

Complex classes like Resizer often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Resizer, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace XoopsModules\Groupmanager\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        GPL 2.0 or later
20
 * @package        XOOPS common
21
 * @since          1.0
22
 * @min_xoops      2.5.9
23
 * @author         Goffy - Wedega - Email:<[email protected]> - Website:<https://wedega.com>
24
 */
25
class Resizer
26
{
27
    public $sourceFile    = '';
28
    public $endFile       = '';
29
    public $maxWidth      = 0;
30
    public $maxHeight     = 0;
31
    public $imageMimetype = '';
32
    public $jpgQuality    = 90;
33
    public $mergeType     = 0;
34
    public $mergePos      = 0;
35
    public $degrees       = 0;
36
    public $error         = '';
37
38
    /**
39
     * resize image if size exceed given width/height
40
     * @return string|bool
41
     */
42
    public function resizeImage()
43
    {
44
        // check file extension
45
        switch ($this->imageMimetype) {
46
            case 'image/png':
47
                $img = \imagecreatefrompng($this->sourceFile);
48
                break;
49
            case 'image/jpeg':
50
                $img = \imagecreatefromjpeg($this->sourceFile);
51
                if (!$img) {
52
                    $img = \imagecreatefromstring(file_get_contents($this->sourceFile));
53
                }
54
                break;
55
            case 'image/gif':
56
                $img = \imagecreatefromgif($this->sourceFile);
57
                break;
58
            default:
59
                return 'Unsupported format';
60
        }
61
62
        $width  = \imagesx($img);
63
        $height = \imagesy($img);
64
65
        if ($width > $this->maxWidth || $height > $this->maxHeight) {
66
            // recalc image size based on this->maxWidth/this->maxHeight
67
            if ($width > $height) {
68
                if ($width < $this->maxWidth) {
69
                    $new_width = $width;
70
                } else {
71
                    $new_width  = $this->maxWidth;
72
                    $divisor    = $width / $new_width;
73
                    $new_height = \floor($height / $divisor);
74
                }
75
            } elseif ($height < $this->maxHeight) {
76
                $new_height = $height;
77
            } else {
78
                $new_height = $this->maxHeight;
79
                $divisor    = $height / $new_height;
80
                $new_width  = \floor($width / $divisor);
81
            }
82
83
            // Create a new temporary image.
84
            $tmpimg = \imagecreatetruecolor($new_width, $new_height);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $new_height does not seem to be defined for all execution paths leading up to this point.
Loading history...
Comprehensibility Best Practice introduced by
The variable $new_width does not seem to be defined for all execution paths leading up to this point.
Loading history...
85
            imagealphablending($tmpimg, false);
86
            imagesavealpha($tmpimg, true);
87
88
            // Copy and resize old image into new image.
89
            \imagecopyresampled($tmpimg, $img, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
90
91
            \unlink($this->endFile);
92
            //compressing the file
93
            switch ($this->imageMimetype) {
94
                case 'image/png':
95
                    \imagepng($tmpimg, $this->endFile, 0);
96
                    break;
97
                case 'image/jpeg':
98
                    \imagejpeg($tmpimg, $this->endFile, 100);
99
                    break;
100
                case 'image/gif':
101
                    \imagegif($tmpimg, $this->endFile);
102
                    break;
103
            }
104
105
            // release the memory
106
            \imagedestroy($tmpimg);
107
        } else {
108
            return 'copy';
109
        }
110
        \imagedestroy($img);
111
112
        return true;
113
    }
114
115
    /**
116
     * @return bool|string
117
     */
118
    public function resizeAndCrop()
119
    {
120
        // check file extension
121
        switch ($this->imageMimetype) {
122
            case 'image/png':
123
                $original = \imagecreatefrompng($this->sourceFile);
124
                break;
125
            case 'image/jpeg':
126
                $original = \imagecreatefromjpeg($this->sourceFile);
127
                break;
128
            case 'image/gif':
129
                $original = \imagecreatefromgif($this->sourceFile);
130
                break;
131
            default:
132
                return 'Unsupported format';
133
        }
134
135
        if (!$original) {
136
            return false;
137
        }
138
        // GET ORIGINAL IMAGE DIMENSIONS
139
        [$original_w, $original_h] = \getimagesize($this->sourceFile);
140
141
        // RESIZE IMAGE AND PRESERVE PROPORTIONS
142
        $max_width_resize  = $this->maxWidth;
143
        $max_height_resize = $this->maxHeight;
144
        if ($original_w > $original_h) {
145
            $max_height_ratio = $this->maxHeight / $original_h;
146
            $max_width_resize = (int)\round($original_w * $max_height_ratio);
147
        } else {
148
            $max_width_ratio   = $this->maxWidth / $original_w;
149
            $max_height_resize = (int)\round($original_h * $max_width_ratio);
150
        }
151
        if ($max_width_resize < $this->maxWidth) {
152
            $max_height_ratio  = $this->maxWidth / $max_width_resize;
153
            $max_height_resize = (int)\round($this->maxHeight * $max_height_ratio);
154
            $max_width_resize  = $this->maxWidth;
155
        }
156
157
        // CREATE THE PROPORTIONAL IMAGE RESOURCE
158
        $thumb = \imagecreatetruecolor($max_width_resize, $max_height_resize);
159
        if (!\imagecopyresampled($thumb, $original, 0, 0, 0, 0, $max_width_resize, $max_height_resize, $original_w, $original_h)) {
160
            return false;
161
        }
162
        // CREATE THE CENTERED CROPPED IMAGE TO THE SPECIFIED DIMENSIONS
163
        $final = \imagecreatetruecolor($this->maxWidth, $this->maxHeight);
164
165
        $max_width_offset  = 0;
166
        $max_height_offset = 0;
167
        if ($this->maxWidth < $max_width_resize) {
168
            $max_width_offset = (int)\round(($max_width_resize - $this->maxWidth) / 2);
169
        } else {
170
            $max_height_offset = (int)\round(($max_height_resize - $this->maxHeight) / 2);
171
        }
172
173
        if (!\imagecopy($final, $thumb, 0, 0, $max_width_offset, $max_height_offset, $max_width_resize, $max_height_resize)) {
174
            return false;
175
        }
176
        // STORE THE FINAL IMAGE - WILL OVERWRITE $this->endFile
177
        if (!\imagejpeg($final, $this->endFile, $this->jpgQuality)) {
178
            return false;
179
        }
180
181
        return true;
182
    }
183
184
    /**
185
     *
186
     */
187
    public function mergeImage()
188
    {
189
        $dest = \imagecreatefromjpeg($this->endFile);
190
        $src  = \imagecreatefromjpeg($this->sourceFile);
191
        if (4 == $this->mergeType) {
192
            $imgWidth  = (int)\round($this->maxWidth / 2 - 1);
193
            $imgHeight = (int)\round($this->maxHeight / 2 - 1);
194
            $posCol2   = (int)\round($this->maxWidth / 2 + 1);
195
            $posRow2   = (int)\round($this->maxHeight / 2 + 1);
196
            switch ($this->mergePos) {
197
                case 1:
198
                    \imagecopy($dest, $src, 0, 0, 0, 0, $imgWidth, $imgHeight); //top left
199
                    break;
200
                case 2:
201
                    \imagecopy($dest, $src, $posCol2, 0, 0, 0, $imgWidth, $imgHeight); //top right
202
                    break;
203
                case 3:
204
                    \imagecopy($dest, $src, 0, $posRow2, 0, 0, $imgWidth, $imgHeight); //bottom left
205
                    break;
206
                case 4:
207
                    \imagecopy($dest, $src, $posCol2, $posRow2, 0, 0, $imgWidth, $imgHeight); //bottom right
208
                    break;
209
            }
210
        }
211
        if (6 == $this->mergeType) {
212
            $imgWidth  = (int)\round($this->maxWidth / 3 - 1);
213
            $imgHeight = (int)\round($this->maxHeight / 2 - 1);
214
            $posCol2   = (int)\round($this->maxWidth / 3 + 1);
215
            $posCol3   = $posCol2 + (int)\round($this->maxWidth / 3 + 1);
216
            $posRow2   = (int)\round($this->maxHeight / 2 + 1);
217
218
            switch ($this->mergePos) {
219
                case 1:
220
                    \imagecopy($dest, $src, 0, 0, 0, 0, $imgWidth, $imgHeight); //top left
221
                    break;
222
                case 2:
223
                    \imagecopy($dest, $src, $posCol2, 0, 0, 0, $imgWidth, $imgHeight); //top center
224
                    break;
225
                case 3:
226
                    \imagecopy($dest, $src, $posCol3, 0, 0, 0, $imgWidth, $imgHeight); //top right
227
                    break;
228
                case 4:
229
                    \imagecopy($dest, $src, 0, $posRow2, 0, 0, $imgWidth, $imgHeight); //bottom left
230
                    break;
231
                case 5:
232
                    \imagecopy($dest, $src, $posCol2, $posRow2, 0, 0, $imgWidth, $imgHeight); //bottom center
233
                    break;
234
                case 6:
235
                    \imagecopy($dest, $src, $posCol3, $posRow2, 0, 0, $imgWidth, $imgHeight); //bottom right
236
                    break;
237
            }
238
        }
239
        \imagejpeg($dest, $this->endFile);
240
241
        \imagedestroy($src);
242
        \imagedestroy($dest);
243
    }
244
245
    /**
246
     * @return bool|string
247
     */
248
    public function rotateImage()
249
    {
250
        // check file extension
251
        switch ($this->imageMimetype) {
252
            case 'image/png':
253
                $original = \imagecreatefrompng($this->sourceFile);
254
                break;
255
            case 'image/jpeg':
256
                $original = \imagecreatefromjpeg($this->sourceFile);
257
                break;
258
            case 'image/gif':
259
                $original = \imagecreatefromgif($this->sourceFile);
260
                break;
261
            default:
262
                return 'Unsupported format';
263
        }
264
265
        if (!$original) {
266
            return false;
267
        }
268
        // Rotate
269
        $tmpimg = \imagerotate($original, $this->degrees, 0);
270
271
        \unlink($this->endFile);
272
        //compressing the file
273
        switch ($this->imageMimetype) {
274
            case 'image/png':
275
                if (!\imagepng($tmpimg, $this->endFile, 0)) {
276
                    return false;
277
                }
278
                break;
279
            case 'image/jpeg':
280
                if (!\imagejpeg($tmpimg, $this->endFile, $this->jpgQuality)) {
281
                    return false;
282
                }
283
                break;
284
            case 'image/gif':
285
                if (!\imagegif($tmpimg, $this->endFile)) {
286
                    return false;
287
                }
288
                break;
289
        }
290
291
        // release the memory
292
        \imagedestroy($tmpimg);
293
294
        return true;
295
    }
296
}
297