Resizer   B
last analyzed

Complexity

Total Complexity 48

Size/Duplication

Total Lines 272
Duplicated Lines 0 %

Importance

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

4 Methods

Rating   Name   Duplication   Size   Complexity  
C resizeImage() 0 73 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\Wgevents\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      module for xoops
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
 * @version        $Id: 1.0 Resizer.php 1 Mon 2019-02-09 10:04:49Z XOOPS Project (www.xoops.org) $
25
 */
26
class Resizer
27
{
28
    public $sourceFile    = '';
29
    public $endFile       = '';
30
    public $maxWidth      = 0;
31
    public $maxHeight     = 0;
32
    public $imageMimetype = '';
33
    public $jpgQuality    = 80;
34
    public $mergeType     = 0;
35
    public $mergePos      = 0;
36
    public $degrees       = 0;
37
    public $error         = '';
38
39
    /**
40
     * resize image if size exceed given width/height
41
     * @return string|bool
42
     */
43
    public function resizeImage()
44
    {
45
        // check file extension
46
        switch ($this->imageMimetype) {
47
            case 'image/png':
48
                $img = \imagecreatefrompng($this->sourceFile);
49
                break;
50
            case 'image/jpeg':
51
                $img = \imagecreatefromjpeg($this->sourceFile);
52
                if (!$img) {
53
                    $img = \imagecreatefromstring(\file_get_contents($this->sourceFile));
54
                }
55
                break;
56
            case 'image/gif':
57
                $img = \imagecreatefromgif($this->sourceFile);
58
                break;
59
            default:
60
                return 'Unsupported format';
61
        }
62
63
        $width  = \imagesx($img);
64
        $height = \imagesy($img);
65
66
        if ($width > $this->maxWidth || $height > $this->maxHeight) {
67
            // recalc image size based on this->maxWidth/this->maxHeight
68
            $new_width  = 0;
69
            $new_height = 0;
70
            if ($width > $height) {
71
                if ($width < $this->maxWidth) {
72
                    $new_width = $width;
73
                } else {
74
                    $new_width  = $this->maxWidth;
75
                    $divisor    = $width / $new_width;
76
                    $new_height = \floor($height / $divisor);
77
                }
78
            } elseif ($height < $this->maxHeight) {
79
                $new_height = $height;
80
            } else {
81
                $new_height = $this->maxHeight;
82
                $divisor    = $height / $new_height;
83
                $new_width  = \floor($width / $divisor);
84
            }
85
86
            // Create a new temporary image.
87
            $tmpimg = \imagecreatetruecolor($new_width, $new_height);
0 ignored issues
show
Bug introduced by
It seems like $new_height can also be of type double; however, parameter $height of imagecreatetruecolor() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

87
            $tmpimg = \imagecreatetruecolor($new_width, /** @scrutinizer ignore-type */ $new_height);
Loading history...
Bug introduced by
It seems like $new_width can also be of type double; however, parameter $width of imagecreatetruecolor() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

87
            $tmpimg = \imagecreatetruecolor(/** @scrutinizer ignore-type */ $new_width, $new_height);
Loading history...
88
            \imagealphablending($tmpimg, false);
89
            \imagesavealpha($tmpimg, true);
90
91
            // Copy and resize old image into new image.
92
            \imagecopyresampled($tmpimg, $img, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
0 ignored issues
show
Bug introduced by
It seems like $new_height can also be of type double; however, parameter $dst_h of imagecopyresampled() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

92
            \imagecopyresampled($tmpimg, $img, 0, 0, 0, 0, $new_width, /** @scrutinizer ignore-type */ $new_height, $width, $height);
Loading history...
Bug introduced by
It seems like $new_width can also be of type double; however, parameter $dst_w of imagecopyresampled() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

92
            \imagecopyresampled($tmpimg, $img, 0, 0, 0, 0, /** @scrutinizer ignore-type */ $new_width, $new_height, $width, $height);
Loading history...
93
94
            \unlink($this->endFile);
95
            //compressing the file
96
            switch ($this->imageMimetype) {
97
                case 'image/png':
98
                    \imagepng($tmpimg, $this->endFile, 0);
99
                    break;
100
                case 'image/jpeg':
101
                    \imagejpeg($tmpimg, $this->endFile, 100);
102
                    break;
103
                case 'image/gif':
104
                    \imagegif($tmpimg, $this->endFile);
105
                    break;
106
            }
107
108
            // release the memory
109
            \imagedestroy($tmpimg);
110
        } else {
111
            return 'copy';
112
        }
113
        \imagedestroy($img);
114
115
        return true;
116
    }
117
118
    /**
119
     * @return bool|string
120
     */
121
    public function resizeAndCrop()
122
    {
123
        // check file extension
124
        switch ($this->imageMimetype) {
125
            case 'image/png':
126
                $original = \imagecreatefrompng($this->sourceFile);
127
                break;
128
            case 'image/jpeg':
129
                $original = \imagecreatefromjpeg($this->sourceFile);
130
                break;
131
            case 'image/gif':
132
                $original = \imagecreatefromgif($this->sourceFile);
133
                break;
134
            default:
135
                return 'Unsupported format';
136
        }
137
138
        if (!$original) {
139
            return false;
140
        }
141
        // GET ORIGINAL IMAGE DIMENSIONS
142
        [$original_w, $original_h] = \getimagesize($this->sourceFile);
143
144
        // RESIZE IMAGE AND PRESERVE PROPORTIONS
145
        $max_width_resize  = $this->maxWidth;
146
        $max_height_resize = $this->maxHeight;
147
        if ($original_w > $original_h) {
148
            $max_height_ratio = $this->maxHeight / $original_h;
149
            $max_width_resize = (int)\round($original_w * $max_height_ratio);
150
        } else {
151
            $max_width_ratio   = $this->maxWidth / $original_w;
152
            $max_height_resize = (int)\round($original_h * $max_width_ratio);
153
        }
154
        if ($max_width_resize < $this->maxWidth) {
155
            $max_height_ratio  = $this->maxWidth / $max_width_resize;
156
            $max_height_resize = (int)\round($this->maxHeight * $max_height_ratio);
157
            $max_width_resize  = $this->maxWidth;
158
        }
159
160
        // CREATE THE PROPORTIONAL IMAGE RESOURCE
161
        $thumb = \imagecreatetruecolor($max_width_resize, $max_height_resize);
162
        if (!\imagecopyresampled($thumb, $original, 0, 0, 0, 0, $max_width_resize, $max_height_resize, $original_w, $original_h)) {
163
            return false;
164
        }
165
        // CREATE THE CENTERED CROPPED IMAGE TO THE SPECIFIED DIMENSIONS
166
        $final = \imagecreatetruecolor($this->maxWidth, $this->maxHeight);
167
168
        $max_width_offset  = 0;
169
        $max_height_offset = 0;
170
        if ($this->maxWidth < $max_width_resize) {
171
            $max_width_offset = (int)\round(($max_width_resize - $this->maxWidth) / 2);
172
        } else {
173
            $max_height_offset = (int)\round(($max_height_resize - $this->maxHeight) / 2);
174
        }
175
176
        if (!\imagecopy($final, $thumb, 0, 0, $max_width_offset, $max_height_offset, $max_width_resize, $max_height_resize)) {
177
            return false;
178
        }
179
        // STORE THE FINAL IMAGE - WILL OVERWRITE $this->endFile
180
        if (!\imagejpeg($final, $this->endFile, $this->jpgQuality)) {
181
            return false;
182
        }
183
184
        return true;
185
    }
186
187
    /**
188
     * @return void
189
     */
190
    public function mergeImage()
191
    {
192
        $dest = \imagecreatefromjpeg($this->endFile);
193
        $src  = \imagecreatefromjpeg($this->sourceFile);
194
        if (4 === $this->mergeType) {
195
            $imgWidth  = (int)\round($this->maxWidth / 2 - 1);
196
            $imgHeight = (int)\round($this->maxHeight / 2 - 1);
197
            $posCol2   = (int)\round($this->maxWidth / 2 + 1);
198
            $posRow2   = (int)\round($this->maxHeight / 2 + 1);
199
            switch ($this->mergePos) {
200
                case 1:
201
                    \imagecopy($dest, $src, 0, 0, 0, 0, $imgWidth, $imgHeight); //top left
202
                    break;
203
                case 2:
204
                    \imagecopy($dest, $src, $posCol2, 0, 0, 0, $imgWidth, $imgHeight); //top right
205
                    break;
206
                case 3:
207
                    \imagecopy($dest, $src, 0, $posRow2, 0, 0, $imgWidth, $imgHeight); //bottom left
208
                    break;
209
                case 4:
210
                    \imagecopy($dest, $src, $posCol2, $posRow2, 0, 0, $imgWidth, $imgHeight); //bottom right
211
                    break;
212
            }
213
        }
214
        if (6 === $this->mergeType) {
215
            $imgWidth  = (int)\round($this->maxWidth / 3 - 1);
216
            $imgHeight = (int)\round($this->maxHeight / 2 - 1);
217
            $posCol2   = (int)\round($this->maxWidth / 3 + 1);
218
            $posCol3   = $posCol2 + (int)\round($this->maxWidth / 3 + 1);
219
            $posRow2   = (int)\round($this->maxHeight / 2 + 1);
220
221
            switch ($this->mergePos) {
222
                case 1:
223
                    \imagecopy($dest, $src, 0, 0, 0, 0, $imgWidth, $imgHeight); //top left
224
                    break;
225
                case 2:
226
                    \imagecopy($dest, $src, $posCol2, 0, 0, 0, $imgWidth, $imgHeight); //top center
227
                    break;
228
                case 3:
229
                    \imagecopy($dest, $src, $posCol3, 0, 0, 0, $imgWidth, $imgHeight); //top right
230
                    break;
231
                case 4:
232
                    \imagecopy($dest, $src, 0, $posRow2, 0, 0, $imgWidth, $imgHeight); //bottom left
233
                    break;
234
                case 5:
235
                    \imagecopy($dest, $src, $posCol2, $posRow2, 0, 0, $imgWidth, $imgHeight); //bottom center
236
                    break;
237
                case 6:
238
                    \imagecopy($dest, $src, $posCol3, $posRow2, 0, 0, $imgWidth, $imgHeight); //bottom right
239
                    break;
240
            }
241
        }
242
        \imagejpeg($dest, $this->endFile);
243
244
        \imagedestroy($src);
245
        \imagedestroy($dest);
246
    }
247
248
    /**
249
     * @return bool|string
250
     */
251
    public function rotateImage()
252
    {
253
        // check file extension
254
        switch ($this->imageMimetype) {
255
            case 'image/png':
256
                $original = \imagecreatefrompng($this->sourceFile);
257
                break;
258
            case 'image/jpeg':
259
                $original = \imagecreatefromjpeg($this->sourceFile);
260
                break;
261
            case 'image/gif':
262
                $original = \imagecreatefromgif($this->sourceFile);
263
                break;
264
            default:
265
                return 'Unsupported format';
266
        }
267
268
        if (!$original) {
269
            return false;
270
        }
271
        // Rotate
272
        $tmpimg = \imagerotate($original, $this->degrees, 0);
273
274
        \unlink($this->endFile);
275
        //compressing the file
276
        switch ($this->imageMimetype) {
277
            case 'image/png':
278
                if (!\imagepng($tmpimg, $this->endFile, 0)) {
279
                    return false;
280
                }
281
                break;
282
            case 'image/jpeg':
283
                if (!\imagejpeg($tmpimg, $this->endFile, $this->jpgQuality)) {
284
                    return false;
285
                }
286
                break;
287
            case 'image/gif':
288
                if (!\imagegif($tmpimg, $this->endFile)) {
289
                    return false;
290
                }
291
                break;
292
        }
293
294
        // release the memory
295
        \imagedestroy($tmpimg);
296
297
        return true;
298
    }
299
}
300