Passed
Push — master ( 4761c2...696f77 )
by
unknown
05:50 queued 19s
created

class/Common/Resizer.php (14 issues)

1
<?php
2
3
declare(strict_types=1);
4
5
namespace XoopsModules\Suico\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
    public $endFile       = '';
31
    public $maxWidth      = 0;
32
    public $maxHeight     = 0;
33
    public $imageMimetype = '';
34
    public $jpgQuality    = 90;
35
    public $mergeType     = 0;
36
    public $mergePos      = 0;
37
    public $degrees       = 0;
38
    public $error         = '';
39
40
    /**
41
     * resize image if size exceed given width/height
42
     * @return string|bool
43
     */
44
    public function resizeImage()
45
    {
46
        // check file extension
47
        switch ($this->imageMimetype) {
48
            case 'image/png':
49
                $img = \imagecreatefrompng($this->sourceFile);
50
                break;
51
            case 'image/jpeg':
52
                $img = \imagecreatefromjpeg($this->sourceFile);
53
                if (!$img) {
54
                    $img = \imagecreatefromstring(file_get_contents($this->sourceFile));
55
                }
56
                break;
57
            case 'image/gif':
58
                $img = \imagecreatefromgif($this->sourceFile);
59
                break;
60
            default:
61
                return 'Unsupported format';
62
        }
63
        $width  = \imagesx($img);
0 ignored issues
show
It seems like $img can also be of type false; however, parameter $image of imagesx() does only seem to accept resource, 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

63
        $width  = \imagesx(/** @scrutinizer ignore-type */ $img);
Loading history...
64
        $height = \imagesy($img);
0 ignored issues
show
It seems like $img can also be of type false; however, parameter $image of imagesy() does only seem to accept resource, 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

64
        $height = \imagesy(/** @scrutinizer ignore-type */ $img);
Loading history...
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
                    $newWidth = $width;
70
                } else {
71
                    $newWidth  = $this->maxWidth;
72
                    $divisor   = $width / $newWidth;
73
                    $newHeight = (int)\floor($height / $divisor);
74
                }
75
            } elseif ($height < $this->maxHeight) {
76
                $newHeight = (int)$height;
77
            } else {
78
                $newHeight = $this->maxHeight;
79
                $divisor   = $height / $newHeight;
80
                $newWidth  = (int)\floor($width / $divisor);
81
            }
82
            // Create a new temporary image.
83
            $tmpimg = \imagecreatetruecolor($newWidth, $newHeight);
84
            imagealphablending($tmpimg, false);
0 ignored issues
show
It seems like $tmpimg can also be of type false; however, parameter $image of imagealphablending() does only seem to accept resource, 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

84
            imagealphablending(/** @scrutinizer ignore-type */ $tmpimg, false);
Loading history...
85
            imagesavealpha($tmpimg, true);
0 ignored issues
show
It seems like $tmpimg can also be of type false; however, parameter $image of imagesavealpha() does only seem to accept resource, 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

85
            imagesavealpha(/** @scrutinizer ignore-type */ $tmpimg, true);
Loading history...
86
            // Copy and resize old image into new image.
87
            \imagecopyresampled(
88
                $tmpimg,
0 ignored issues
show
It seems like $tmpimg can also be of type false; however, parameter $dst_image of imagecopyresampled() does only seem to accept resource, 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

88
                /** @scrutinizer ignore-type */ $tmpimg,
Loading history...
89
                $img,
0 ignored issues
show
It seems like $img can also be of type false; however, parameter $src_image of imagecopyresampled() does only seem to accept resource, 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

89
                /** @scrutinizer ignore-type */ $img,
Loading history...
90
                0,
91
                0,
92
                0,
93
                0,
94
                $newWidth,
95
                $newHeight,
96
                $width,
97
                $height
98
            );
99
            \unlink($this->endFile);
100
            //compressing the file
101
            switch ($this->imageMimetype) {
102
                case 'image/png':
103
                    \imagepng($tmpimg, $this->endFile, 0);
0 ignored issues
show
It seems like $tmpimg can also be of type false; however, parameter $image of imagepng() does only seem to accept resource, 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

103
                    \imagepng(/** @scrutinizer ignore-type */ $tmpimg, $this->endFile, 0);
Loading history...
104
                    break;
105
                case 'image/jpeg':
106
                    \imagejpeg($tmpimg, $this->endFile, 100);
0 ignored issues
show
It seems like $tmpimg can also be of type false; however, parameter $image of imagejpeg() does only seem to accept resource, 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

106
                    \imagejpeg(/** @scrutinizer ignore-type */ $tmpimg, $this->endFile, 100);
Loading history...
107
                    break;
108
                case 'image/gif':
109
                    \imagegif($tmpimg, $this->endFile);
0 ignored issues
show
It seems like $tmpimg can also be of type false; however, parameter $image of imagegif() does only seem to accept resource, 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

109
                    \imagegif(/** @scrutinizer ignore-type */ $tmpimg, $this->endFile);
Loading history...
110
                    break;
111
            }
112
            // release the memory
113
            \imagedestroy($tmpimg);
0 ignored issues
show
It seems like $tmpimg can also be of type false; however, parameter $image of imagedestroy() does only seem to accept resource, 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

113
            \imagedestroy(/** @scrutinizer ignore-type */ $tmpimg);
Loading history...
114
        } else {
115
            return 'copy';
116
        }
117
        \imagedestroy($img);
118
        return true;
119
    }
120
121
    /**
122
     * @return bool|string
123
     */
124
    public function resizeAndCrop()
125
    {
126
        // check file extension
127
        switch ($this->imageMimetype) {
128
            case 'image/png':
129
                $original = \imagecreatefrompng($this->sourceFile);
130
                break;
131
            case 'image/jpeg':
132
                $original = \imagecreatefromjpeg($this->sourceFile);
133
                break;
134
            case 'image/gif':
135
                $original = \imagecreatefromgif($this->sourceFile);
136
                break;
137
            default:
138
                return 'Unsupported format';
139
        }
140
        if (!$original) {
141
            return false;
142
        }
143
        // GET ORIGINAL IMAGE DIMENSIONS
144
        [$original_w, $original_h] = \getimagesize($this->sourceFile);
145
        // RESIZE IMAGE AND PRESERVE PROPORTIONS
146
        $max_width_resize  = $this->maxWidth;
147
        $max_height_resize = $this->maxHeight;
148
        if ($original_w > $original_h) {
149
            $max_height_ratio = $this->maxHeight / $original_h;
150
            $max_width_resize = (int)\round($original_w * $max_height_ratio);
151
        } else {
152
            $max_width_ratio   = $this->maxWidth / $original_w;
153
            $max_height_resize = (int)\round($original_h * $max_width_ratio);
154
        }
155
        if ($max_width_resize < $this->maxWidth) {
156
            $max_height_ratio  = $this->maxWidth / $max_width_resize;
157
            $max_height_resize = (int)\round($this->maxHeight * $max_height_ratio);
158
            $max_width_resize  = $this->maxWidth;
159
        }
160
        // CREATE THE PROPORTIONAL IMAGE RESOURCE
161
        $thumb = \imagecreatetruecolor($max_width_resize, $max_height_resize);
162
        if (!\imagecopyresampled(
163
            $thumb,
164
            $original,
165
            0,
166
            0,
167
            0,
168
            0,
169
            $max_width_resize,
170
            $max_height_resize,
171
            $original_w,
172
            $original_h
173
        )) {
174
            return false;
175
        }
176
        // CREATE THE CENTERED CROPPED IMAGE TO THE SPECIFIED DIMENSIONS
177
        $final             = \imagecreatetruecolor(
178
            $this->maxWidth,
179
            $this->maxHeight
180
        );
181
        $max_width_offset  = 0;
182
        $max_height_offset = 0;
183
        if ($this->maxWidth < $max_width_resize) {
184
            $max_width_offset = (int)\round(($max_width_resize - $this->maxWidth) / 2);
185
        } else {
186
            $max_height_offset = (int)\round(($max_height_resize - $this->maxHeight) / 2);
187
        }
188
        if (!\imagecopy(
189
            $final,
190
            $thumb,
191
            0,
192
            0,
193
            $max_width_offset,
194
            $max_height_offset,
195
            $max_width_resize,
196
            $max_height_resize
197
        )) {
198
            return false;
199
        }
200
        // STORE THE FINAL IMAGE - WILL OVERWRITE $this->endFile
201
        if (!\imagejpeg(
202
            $final,
203
            $this->endFile,
204
            $this->jpgQuality
205
        )) {
206
            return false;
207
        }
208
        return true;
209
    }
210
211
    public function mergeImage()
212
    {
213
        $dest = \imagecreatefromjpeg($this->endFile);
214
        $src  = \imagecreatefromjpeg($this->sourceFile);
215
        if (4 === $this->mergeType) {
216
            $imgWidth  = (int)\round($this->maxWidth / 2 - 1);
217
            $imgHeight = (int)\round($this->maxHeight / 2 - 1);
218
            $posCol2   = (int)\round($this->maxWidth / 2 + 1);
219
            $posRow2   = (int)\round($this->maxHeight / 2 + 1);
220
            switch ($this->mergePos) {
221
                case 1:
222
                    \imagecopy($dest, $src, 0, 0, 0, 0, $imgWidth, $imgHeight); //top left
0 ignored issues
show
It seems like $src can also be of type false; however, parameter $src_im of imagecopy() does only seem to accept resource, 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

222
                    \imagecopy($dest, /** @scrutinizer ignore-type */ $src, 0, 0, 0, 0, $imgWidth, $imgHeight); //top left
Loading history...
It seems like $dest can also be of type false; however, parameter $dst_im of imagecopy() does only seem to accept resource, 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

222
                    \imagecopy(/** @scrutinizer ignore-type */ $dest, $src, 0, 0, 0, 0, $imgWidth, $imgHeight); //top left
Loading history...
223
                    break;
224
                case 2:
225
                    \imagecopy($dest, $src, $posCol2, 0, 0, 0, $imgWidth, $imgHeight); //top right
226
                    break;
227
                case 3:
228
                    \imagecopy($dest, $src, 0, $posRow2, 0, 0, $imgWidth, $imgHeight); //bottom left
229
                    break;
230
                case 4:
231
                    \imagecopy($dest, $src, $posCol2, $posRow2, 0, 0, $imgWidth, $imgHeight); //bottom right
232
                    break;
233
            }
234
        }
235
        if (6 === $this->mergeType) {
236
            $imgWidth  = (int)\round($this->maxWidth / 3 - 1);
237
            $imgHeight = (int)\round($this->maxHeight / 2 - 1);
238
            $posCol2   = (int)\round($this->maxWidth / 3 + 1);
239
            $posCol3   = $posCol2 + (int)\round($this->maxWidth / 3 + 1);
240
            $posRow2   = (int)\round($this->maxHeight / 2 + 1);
241
            switch ($this->mergePos) {
242
                case 1:
243
                    \imagecopy($dest, $src, 0, 0, 0, 0, $imgWidth, $imgHeight); //top left
244
                    break;
245
                case 2:
246
                    \imagecopy($dest, $src, $posCol2, 0, 0, 0, $imgWidth, $imgHeight); //top center
247
                    break;
248
                case 3:
249
                    \imagecopy($dest, $src, $posCol3, 0, 0, 0, $imgWidth, $imgHeight); //top right
250
                    break;
251
                case 4:
252
                    \imagecopy($dest, $src, 0, $posRow2, 0, 0, $imgWidth, $imgHeight); //bottom left
253
                    break;
254
                case 5:
255
                    \imagecopy($dest, $src, $posCol2, $posRow2, 0, 0, $imgWidth, $imgHeight); //bottom center
256
                    break;
257
                case 6:
258
                    \imagecopy($dest, $src, $posCol3, $posRow2, 0, 0, $imgWidth, $imgHeight); //bottom right
259
                    break;
260
            }
261
        }
262
        \imagejpeg($dest, $this->endFile);
0 ignored issues
show
It seems like $dest can also be of type false; however, parameter $image of imagejpeg() does only seem to accept resource, 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

262
        \imagejpeg(/** @scrutinizer ignore-type */ $dest, $this->endFile);
Loading history...
263
        \imagedestroy($src);
0 ignored issues
show
It seems like $src can also be of type false; however, parameter $image of imagedestroy() does only seem to accept resource, 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

263
        \imagedestroy(/** @scrutinizer ignore-type */ $src);
Loading history...
264
        \imagedestroy($dest);
265
    }
266
267
    /**
268
     * @return bool|string
269
     */
270
    public function rotateImage()
271
    {
272
        // check file extension
273
        switch ($this->imageMimetype) {
274
            case 'image/png':
275
                $original = \imagecreatefrompng($this->sourceFile);
276
                break;
277
            case 'image/jpeg':
278
                $original = \imagecreatefromjpeg($this->sourceFile);
279
                break;
280
            case 'image/gif':
281
                $original = \imagecreatefromgif($this->sourceFile);
282
                break;
283
            default:
284
                return 'Unsupported format';
285
        }
286
        if (!$original) {
287
            return false;
288
        }
289
        // Rotate
290
        $tmpimg = \imagerotate($original, $this->degrees, 0);
291
        \unlink($this->endFile);
292
        //compressing the file
293
        switch ($this->imageMimetype) {
294
            case 'image/png':
295
                if (!\imagepng($tmpimg, $this->endFile, 0)) {
296
                    return false;
297
                }
298
                break;
299
            case 'image/jpeg':
300
                if (!\imagejpeg($tmpimg, $this->endFile, $this->jpgQuality)) {
301
                    return false;
302
                }
303
                break;
304
            case 'image/gif':
305
                if (!\imagegif($tmpimg, $this->endFile)) {
306
                    return false;
307
                }
308
                break;
309
        }
310
        // release the memory
311
        \imagedestroy($tmpimg);
312
        return true;
313
    }
314
}
315