Resize::getSizeByFixedWidth()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 3
dl 0
loc 5
rs 10
c 1
b 0
f 0
cc 1
nc 1
nop 1
1
<?php
2
/**
3
 * KNUT7 K7F (https://marciozebedeu.com/)
4
 * KNUT7 K7F (tm) : Rapid Development Framework (https://marciozebedeu.com/)
5
 *
6
 * Licensed under The MIT License
7
 * For full copyright and license information, please see the LICENSE.txt
8
 * Redistributions of files must retain the above copyright notice.
9
 *
10
 * @link      https://github.com/knut7/framework/ for the canonical source repository
11
 * @copyright (c) 2015.  KNUT7  Software Technologies AO Inc. (https://marciozebedeu.com/)
12
 * @license   https://marciozebedeu.com/license/new-bsd New BSD License
13
 * @author    Marcio Zebedeu - [email protected]
14
 * @version   1.0.2
15
 */
16
17
namespace Ballybran\Helpers\Images;
18
19
use Ballybran\Helpers\Images\ImageInterface\ResizeInterface;
20
21
class Resize implements ResizeInterface
22
{
23
24
25
    private $image;
26
    private $width;
27
    private $height;
28
    private $imageResized;
29
30
    public function upload($file)
31
    {
32
33
        // *** Open up the file
34
        $this->image = $this->openImage($file);
35
36
        // Get Width  and Height
37
        $this->width = imagesx($this->image);
0 ignored issues
show
Bug introduced by
It seems like $this->image can also be of type false; however, parameter $image of imagesx() does only seem to accept GdImage|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

37
        $this->width = imagesx(/** @scrutinizer ignore-type */ $this->image);
Loading history...
38
        $this->height = imagesy($this->image);
0 ignored issues
show
Bug introduced by
It seems like $this->image can also be of type false; however, parameter $image of imagesy() does only seem to accept GdImage|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

38
        $this->height = imagesy(/** @scrutinizer ignore-type */ $this->image);
Loading history...
39
    }
40
41
    private function openImage($file)
42
    {
43
        //*** get extendsion
44
        $extension = strtolower(strrchr($file, '.'));
45
46
        switch ($extension) {
47
            case '.jpg':
48
            case '.jpeg':
49
50
                $img = imagecreatefromjpeg($file);
51
                break;
52
            case '.gif':
53
                $img = imagecreatefromgif($file);
54
                break;
55
            case '.png':
56
                $img = imagecreatefrompng($file);
57
                break;
58
59
            default:
60
                $img = false;
61
                break;
62
        }
63
64
        return $img;
65
    }
66
67
    public function resizeImage($width, $height, $option = "auto")
68
    {
69
        $optionaArray = $this->getDimensions($width, $height, strtolower($option));
70
71
        // *** Get optional witdth and height - based on option
72
        $optionalWidth = $optionaArray['optionalWidth'];
73
        $optionalHeight = $optionaArray['optionalHeight'];
74
75
        $this->imageResized = imagecreatetruecolor($optionalWidth, $optionalHeight);
76
77
        // ***  Resample - create image canvas of x, y size
78
79
        imagecopyresampled($this->imageResized, $this->image, 0, 0, 0, 0, $optionalWidth, $optionalHeight, $this->width, $this->height);
80
81
        if ($option == 'crop') {
82
            $this->crop($optionalWidth, $optionalHeight, $width, $height);
83
        }
84
    }
85
86
    private function getDimensions($new_width, $new_height, $option)
87
    {
88
        $optionalWidth = "";
89
        $optionalHeight = "";
90
91
        switch ($option) {
92
            case 'exact':
93
                $optionalWidth = $new_width;
94
                $optionalHeight = $new_height;
95
                break;
96
            case 'portrait':
97
                $optionalWidth = $this->getSizeByFixedHeight($new_height);
98
                $optionalHeight = $new_width;
99
                break;
100
            case 'lendscape':
101
                $optionalWidth = $new_width;
102
                $optionalHeight = $this->getSizeByFixedWidth($new_width);
103
                break;
104
            case 'auto':
105
                $optionaArray = $this->getSizeByAuto($new_width, $new_height);
106
                $optionalWidth = $optionaArray['optionalWidth'];
107
                $optionalHeight = $optionaArray['optionalHeight'];
108
                break;
109
            case 'crop':
110
                $optionaArray = $this->getOptionalCrop($new_width, $new_height);
111
                $optionalWidth = $optionaArray['optionalWidth'];
112
                $optionalHeight = $optionaArray['optionalHeight'];
113
                break;
114
            case 'perfil':
115
                $optionaArray = $this->getOptionalPerfil($new_width, $new_height);
116
                $optionalWidth = $optionaArray['optionalWidth'];
117
                $optionalHeight = $optionaArray['optionalHeight'];
118
        }
119
120
        return array('optionalWidth' => $optionalWidth, 'optionalHeight' => $optionalHeight);
121
    }
122
123
    private function getOptionalPerfil($new_width, $new_height)
124
    {
125
        $heightRatio = $new_height;
126
        $widthRatio = $new_width;
127
128
        if (!$heightRatio < $widthRatio) {
129
            $optionalRatio = $heightRatio;
0 ignored issues
show
Unused Code introduced by
The assignment to $optionalRatio is dead and can be removed.
Loading history...
130
        }
131
        $optionalRatio = $widthRatio;
132
        $optionalHeight = $optionalRatio;
133
        $optionalWidth = $heightRatio;
134
        return array('optionalWidth' => $optionalWidth, 'optionalHeight' => $optionalHeight);
135
136
    }
137
138
    private function getSizeByFixedHeight($new_height)
139
    {
140
        $ratio = $this->width / $this->height;
141
        $new_width = $new_height * $ratio;
142
        return $new_width;
143
    }
144
145
    private function getSizeByFixedWidth($new_width)
146
    {
147
        $ratio = $this->height / $this->width;
148
        $new_height = $new_width * $ratio;
149
        return $new_height;
150
    }
151
152
    private function getSizeByAuto($new_width, $new_height)
153
    {
154
155
        if ($this->height < $this->width) {
156
            // *** image to be resized is taller (landscap)
157
158
            $optionalWidth = $new_width;
159
            $optionalHeight = $this->getSizeByFixedWidth($new_width);
160
        } elseif ($this->height > $this->width) {
161
            // *** image to be resized is taller (portrait)
162
163
            $optionalWidth = $this->getSizeByFixedHeight($new_height);
164
            $optionalHeight = $new_height;
165
        } else {
166
167
            // *** image to be Resized is a square
168
            if ($new_height < $new_width) {
169
                $optionalWidth = $new_width;
170
                $optionalHeight = $this->getSizeByFixedWidth($new_width);
171
            } else if ($new_height > $new_width) {
172
                $optionalWidth = $this->getSizeByFixedHeight($new_height);
173
                $optionalHeight = $new_height;
174
            } else {
175
                $optionalWidth = $new_width;
176
                $optionalHeight = $new_height;
177
            }
178
        }
179
        return array('optionalWidth' => $optionalWidth, 'optionalHeight' => $optionalHeight);
180
    }
181
182
    /**
183
     * @param $new_width
184
     * @param $new_height
185
     * @return array
186
     *  example  w = 512, h = 720 if 720 / 200 < 512 / 400
187
     */
188
    private function getOptionalCrop(int $new_width, int $new_height): array
189
    {
190
        $heightRatio = $this->height / $new_height;
191
        $widthRatio = $this->width / $new_width;
192
193
        if (!$heightRatio < $widthRatio) {
194
            $optionalRatio = $heightRatio;
0 ignored issues
show
Unused Code introduced by
The assignment to $optionalRatio is dead and can be removed.
Loading history...
195
        }
196
        $optionalRatio = $widthRatio;
197
        $optionalHeight = $this->height / $optionalRatio;
198
        $optionalWidth = $this->width / $optionalRatio;
199
        return array('optionalWidth' => $optionalWidth, 'optionalHeight' => $optionalHeight);
200
    }
201
202
    private function crop($optionalWidth, $optionalHeight, $new_width, $new_height)
203
    {
204
// *** find center - this will be used for the crop
205
        $cropStartX = ($optionalWidth / 2) - ($new_width / 2);
206
        $cropStartY = ($optionalHeight / 2) - ($new_height / 2);
207
208
        $crop = $this->imageResized;
209
        // imageDestroy($this->imageResçized);
210
        // *** Now crop from center to exact requested size
211
212
        $this->imageResized = imagecreatetruecolor($new_width, $new_height);
213
        imagecopyresampled($this->imageResized, $crop, 0, 0, $cropStartX, $cropStartY, $new_width, $new_height, $new_width, $new_height);
214
    }
215
216
    public function save(string $savePath, int $imageQuality = 100)
217
    {
218
        // *** Get extension
219
220
        $extension = strrchr($savePath, '.');
221
        $extension = strtolower($extension);
222
223
        switch ($extension) {
224
            case '.jpg':
225
            case '.jpeg':
226
                if (exif_imagetype($savePath) && imagetypes() & IMG_JPG) {
227
                    imagejpeg($this->imageResized, $savePath, $imageQuality);
228
                }
229
                break;
230
231
            case '.gif':
232
                if (exif_imagetype($savePath) && imagetypes() & IMG_GIF) {
233
                    imagegif($this->imageResized, $savePath);
234
                }
235
                break;
236
237
            case '.png':
238
239
                // *** scale quality from 0-100 to 0-9
240
                $scaleQuality = round(($imageQuality / 100) * 9);
241
242
                $invertScaleQuality = 9 - $scaleQuality;
243
244
                if (exif_imagetype($savePath) && imagetypes() & IMG_PNG) {
245
246
                    imagepng($this->imageResized, $savePath, $invertScaleQuality);
0 ignored issues
show
Bug introduced by
$invertScaleQuality of type double is incompatible with the type integer expected by parameter $quality of imagepng(). ( Ignorable by Annotation )

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

246
                    imagepng($this->imageResized, $savePath, /** @scrutinizer ignore-type */ $invertScaleQuality);
Loading history...
247
                }
248
                break;
249
250
            // .... etc
251
            default:
252
                // *** No extension - No Save
253
                echo "no save";
254
                break;
255
        }
256
        imagedestroy($this->imageResized);
257
    }
258
259
    public function imageRotate(int $degree, $colorHexType = '000000')
260
    {
261
        $rgb = $this->html2rgb($colorHexType);
262
263
        $this->image = imagerotate($this->image, $degree, imagecolorallocate($this->image, $rgb[0], $rgb[1], $rgb[2]));
0 ignored issues
show
Bug introduced by
It seems like $rgb[1] can also be of type double; however, parameter $green of imagecolorallocate() 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

263
        $this->image = imagerotate($this->image, $degree, imagecolorallocate($this->image, $rgb[0], /** @scrutinizer ignore-type */ $rgb[1], $rgb[2]));
Loading history...
Bug introduced by
It seems like $rgb[0] can also be of type double; however, parameter $red of imagecolorallocate() 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

263
        $this->image = imagerotate($this->image, $degree, imagecolorallocate($this->image, /** @scrutinizer ignore-type */ $rgb[0], $rgb[1], $rgb[2]));
Loading history...
Bug introduced by
It seems like $rgb[2] can also be of type double; however, parameter $blue of imagecolorallocate() 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

263
        $this->image = imagerotate($this->image, $degree, imagecolorallocate($this->image, $rgb[0], $rgb[1], /** @scrutinizer ignore-type */ $rgb[2]));
Loading history...
264
265
        $this->width = imagesx($this->image);
266
        $this->height = imagesy($this->image);
267
268
    }
269
270
    private function html2rgb($color): array
271
    {
272
        if ($color[0] == '#') {
273
            $color = substr($color, 1);
274
        }
275
276
        if (strlen($color) == 6) {
277
            list($r, $g, $b) = array($color[0] . $color[1], $color[2] . $color[3], $color[4] . $color[5]);
278
        } elseif (strlen($color) == 3) {
279
            list($r, $g, $b) = array($color[0] . $color[0], $color[1] . $color[1], $color[2] . $color[2]);
280
        } else {
281
            return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the type-hinted return array.
Loading history...
282
        }
283
284
        $r = hexdec($r);
285
        $g = hexdec($g);
286
        $b = hexdec($b);
287
288
        return array($r, $g, $b);
289
    }
290
291
    public function text($text, $x = 0, $y = 0, $size = 5, $color = '000000')
292
    {
293
        $rgb = $this->html2rgb($color);
294
295
        return imagestring($this->image, $size, $x, $y, $text, imagecolorallocate($this->image, $rgb[0], $rgb[1], $rgb[2]));
0 ignored issues
show
Bug introduced by
It seems like $rgb[1] can also be of type double; however, parameter $green of imagecolorallocate() 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

295
        return imagestring($this->image, $size, $x, $y, $text, imagecolorallocate($this->image, $rgb[0], /** @scrutinizer ignore-type */ $rgb[1], $rgb[2]));
Loading history...
Bug introduced by
It seems like $rgb[0] can also be of type double; however, parameter $red of imagecolorallocate() 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

295
        return imagestring($this->image, $size, $x, $y, $text, imagecolorallocate($this->image, /** @scrutinizer ignore-type */ $rgb[0], $rgb[1], $rgb[2]));
Loading history...
Bug introduced by
It seems like $rgb[2] can also be of type double; however, parameter $blue of imagecolorallocate() 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

295
        return imagestring($this->image, $size, $x, $y, $text, imagecolorallocate($this->image, $rgb[0], $rgb[1], /** @scrutinizer ignore-type */ $rgb[2]));
Loading history...
296
    }
297
298
}
299