Completed
Push — master ( e44baf...dee4cd )
by Gabriel
12:09 queued 11s
created

Nip_File_Image::unsharpMask()   F

Complexity

Conditions 24
Paths 312

Size

Total Lines 110

Duplication

Lines 110
Ratio 100 %

Importance

Changes 0
Metric Value
dl 110
loc 110
c 0
b 0
f 0
rs 1.5466
cc 24
nc 312
nop 3

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
2
3
/**
4
 * Nip Framework.
5
 *
6
 * @category   Nip
7
 *
8
 * @copyright  2009 Nip Framework
9
 * @license    http://www.opensource.org/licenses/mit-license.php The MIT License
10
 *
11
 * @version    SVN: $Id: Image.php 193 2009-06-23 23:11:53Z victorstanciu $
12
 */
13 View Code Duplication
class Nip_File_Image extends Nip_File_Handler
0 ignored issues
show
Duplication introduced by
This class seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
14
{
15
    public $extensions = ['jpg', 'jpeg', 'gif', 'png'];
16
    public $quality = 90;
17
    public $type = 'jpg';
18
    public $max_width = false;
19
    public $errors = [];
20
21
    protected $_resource;
22
    protected $_file;
23
    protected $_upload;
24
    protected $_width;
25
    protected $_height;
26
27
    /**
28
     * @param array $upload
29
     */
30
    public function setResourceFromUpload($upload)
31
    {
32
        $this->_upload = $upload;
33
        $this->setResourceFromFile($upload['tmp_name']);
34
    }
35
36
    /**
37
     * @param string $path
38
     *
39
     * @return bool
40
     */
41
    public function setResourceFromFile($path)
42
    {
43
        $this->_file = $path;
44
        if (file_exists($path)) {
45
            $details = getimagesize($path);
46
47
            switch ($details['mime']) {
48
                case 'image/gif':
49
                    $this->type = 'gif';
50
                    if (imagetypes() & IMG_GIF) {
51
                        $this->_resource = imagecreatefromgif($path);
52
                    }
53
                    break;
54
                case 'image/jpeg':
55
                    $this->type = 'jpg';
56
                    if (imagetypes() & IMG_JPG) {
57
                        $this->_resource = imagecreatefromjpeg($path);
58
                    }
59
                    break;
60
                case 'image/png':
61
                    $this->type = 'png';
62
                    if (imagetypes() & IMG_PNG) {
63
                        $this->_resource = imagecreatefrompng($path);
64
                    }
65
                    break;
66
            }
67
68
            $this->getWidth();
69
            $this->getHeight();
70
71
            return true;
72
        } else {
73
            trigger_error("Cannot find file $path", E_USER_ERROR);
74
        }
75
76
        return false;
77
    }
78
79
    /**
80
     * @return int
81
     */
82
    public function getWidth()
83
    {
84
        if (!$this->_width && $this->_resource) {
85
            $this->setWidth(imagesx($this->_resource));
86
        }
87
88
        return $this->_width;
89
    }
90
91
    /**
92
     * @param int $width
93
     */
94
    public function setWidth($width)
95
    {
96
        $this->_width = $width;
97
    }
98
99
    /**
100
     * @return int
101
     */
102
    public function getHeight()
103
    {
104
        if (!$this->_height && $this->_resource) {
105
            $this->setHeight(imagesy($this->_resource));
106
        }
107
108
        return $this->_height;
109
    }
110
111
    /**
112
     * @param int $height
113
     */
114
    public function setHeight($height)
115
    {
116
        $this->_height = $height;
117
    }
118
119
    /**
120
     * @param string $name
121
     */
122
    public function setBaseName($name)
123
    {
124
        $name = $name.'.'.$this->type;
125
        $this->setName($name);
126
    }
127
128
    /**
129
     * @param string $name
130
     */
131
    public function setName($name)
132
    {
133
        $this->name = $name;
134
        $this->url = dirname($this->url).'/'.$this->name;
135
        $this->path = dirname($this->path).'/'.$this->name;
136
    }
137
138
    /**
139
     * @return bool
140
     */
141
    public function save()
142
    {
143
        if (Nip_File_System::instance()->createDirectory(dirname($this->path))) {
144
            switch ($this->type) {
145
                case 'png':
146
                    if ($this->quality > 9) {
147
                        if ($this->quality < 100) {
148
                            $this->quality = $this->quality / 10;
149
                        } else {
150
                            $this->quality = 9;
151
                        }
152
                    }
153
                    $this->quality = abs($this->quality - 9);
0 ignored issues
show
Documentation Bug introduced by
It seems like abs($this->quality - 9) can also be of type double. However, the property $quality is declared as type integer. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
154
                    $this->quality = 0;
155
156
                    $newImg = imagecreatetruecolor($this->_width, $this->_height);
157
                    imagealphablending($newImg, false);
158
                    imagesavealpha($newImg, true);
159
160
                    imagecopyresampled($newImg, $this->_resource, 0, 0, 0, 0, $this->_width, $this->_height, $this->_width, $this->_height);
161
162
                    $return = imagepng($newImg, $this->path, $this->quality);
163
                    break;
164
                case 'jpg':
165
                default:
166
                    $return = imagejpeg($this->_resource, $this->path, $this->quality);
167
                    break;
168
            }
169
170
            if ($return) {
171
                chmod($this->path, 0777);
172
173
                return true;
174
            }
175
            $this->errors[] = 'Error saving file';
176
        } else {
177
            $this->errors[] = 'Error creating directory';
178
        }
179
180
        return false;
181
    }
182
183
    public function grayscaleFade()
184
    {
185
        $this->grayscaleFilter();
186
        imagefilter($this->_resource, IMG_FILTER_BRIGHTNESS, 50);
187
    }
188
189
    public function grayscaleFilter()
190
    {
191
        imagefilter($this->_resource, IMG_FILTER_GRAYSCALE);
192
    }
193
194
    public function resize($max_width = false, $max_height = false)
195
    {
196
        if (!$max_width) {
197
            if ($this->max_width) {
198
                $max_width = $this->max_width;
199
            } else {
200
                $max_width = $this->getWidth();
201
            }
202
        }
203
204
        if (!$max_height) {
205
            if ($this->max_height) {
206
                $max_height = $this->max_height;
207
            } else {
208
                $max_height = $this->getHeight();
209
            }
210
        }
211
212
        $ratio = $this->getRatio();
213
        $target_ratio = $max_width / $max_height;
214
215
        if ($ratio > $target_ratio) {
216
            $new_width = $max_width;
217
            $new_height = round($max_width / $ratio);
218
        } else {
219
            $new_height = $max_height;
220
            $new_width = round($max_height * $ratio);
221
        }
222
223
        $image = imagecreatetruecolor($new_width, $new_height);
224
        imagealphablending($image, false);
225
        imagesavealpha($image, true);
226
227
        imagecopyresampled($image, $this->_resource, 0, 0, 0, 0, $new_width, $new_height, $this->getWidth(), $this->getHeight());
228
229
        $this->_width = $new_width;
230
        $this->_height = $new_height;
231
        $this->_resource = $image;
232
233
        return $this;
234
    }
235
236
    public function getRatio()
237
    {
238
        return $this->getWidth() / $this->getHeight();
239
    }
240
241
    public function cropToCenter($cWidth, $cHeight)
242
    {
243
        $this->resizeToLarge($cWidth, $cHeight);
244
245
        $width = $this->getWidth();
246
        $height = $this->getHeight();
247
248
        $x0 = round(abs(($width - $cWidth) / 2), 0);
249
        $y0 = round(abs(($height - $cHeight) / 2), 0);
250
251
        $this->crop($x0, $y0, $cWidth, $cHeight, $cWidth, $cHeight);
252
    }
253
254
    /**
255
     * @param bool|int $max_width
256
     * @param bool|int $max_height
257
     *
258
     * @return $this
259
     */
260
    public function resizeToLarge($max_width = false, $max_height = false)
261
    {
262
        if (!$max_width) {
263
            $max_width = $this->getWidth();
264
        }
265
266
        if (!$max_height) {
267
            $max_height = $this->getHeight();
268
        }
269
270
        $sourceRatio = $this->getRatio();
271
        $target_ratio = $max_width / $max_height;
272
273
        if ($sourceRatio > $target_ratio) {
274
            $new_height = $max_height;
275
            $new_width = (int) ($max_height * $sourceRatio);
276
        } else {
277
            $new_width = $max_width;
278
            $new_height = (int) ($max_width / $sourceRatio);
279
        }
280
281
        $image = imagecreatetruecolor($new_width, $new_height);
282
        imagealphablending($image, false);
283
        imagesavealpha($image, true);
284
285
        imagecopyresampled($image, $this->_resource, 0, 0, 0, 0, $new_width, $new_height, $this->getWidth(), $this->getHeight());
286
287
        $this->_width = $new_width;
288
        $this->_height = $new_height;
289
        $this->_resource = $image;
290
291
        return $this;
292
    }
293
294
    /**
295
     * @param $x
296
     * @param $y
297
     * @param $dwidth
298
     * @param $dheight
299
     * @param $swidth
300
     * @param $sheight
301
     */
302
    public function crop($x, $y, $dwidth, $dheight, $swidth, $sheight)
303
    {
304
        $image = imagecreatetruecolor($dwidth, $dheight);
305
        imagealphablending($image, false);
306
        imagesavealpha($image, true);
307
308
        imagecopyresampled($image, $this->_resource,
309
            0, 0,
310
            $x, $y,
311
            $dwidth, $dheight,
312
            $swidth, $sheight);
313
314
        $this->_width = $dwidth;
315
        $this->_height = $dheight;
316
        $this->_resource = $image;
317
    }
318
319
    /**
320
     * @param int   $amount
321
     * @param float $radius
322
     * @param int   $threshold
323
     *
324
     * @return $this
325
     */
326
    public function unsharpMask($amount = 80, $radius = 0.5, $threshold = 3)
327
    {
328
        $img = &$this->_resource;
329
330
        if ($amount > 500) {
331
            $amount = 500;
332
        }
333
        $amount = $amount * 0.016;
334
        if ($radius > 50) {
335
            $radius = 50;
336
        }
337
        $radius = $radius * 2;
338
        if ($threshold > 255) {
339
            $threshold = 255;
340
        }
341
342
        $radius = abs(round($radius));
343
        if ($radius == 0) {
344
            return;
345
        }
346
347
        $w = $this->_width;
348
        $h = $this->_height;
349
350
        $imgCanvas = imagecreatetruecolor($w, $h);
351
        $imgBlur = imagecreatetruecolor($w, $h);
352
353
        if (function_exists('imageconvolution')) {
354
            $matrix = [[1, 2, 1], [2, 4, 2], [1, 2, 1]];
355
            imagecopy($imgBlur, $img, 0, 0, 0, 0, $w, $h);
356
            imageconvolution($imgBlur, $matrix, 16, 0);
357
        } else {
358
            for ($i = 0; $i < $radius; $i++) {
359
                imagecopy($imgBlur, $img, 0, 0, 1, 0, $w - 1, $h);
360
                imagecopymerge($imgBlur, $img, 1, 0, 0, 0, $w, $h, 50);
361
                imagecopymerge($imgBlur, $img, 0, 0, 0, 0, $w, $h, 50);
362
                imagecopy($imgCanvas, $imgBlur, 0, 0, 0, 0, $w, $h);
363
364
                imagecopymerge($imgBlur, $imgCanvas, 0, 0, 0, 1, $w, $h - 1, 33.33333);
365
                imagecopymerge($imgBlur, $imgCanvas, 0, 1, 0, 0, $w, $h, 25);
366
            }
367
        }
368
369
        if ($threshold > 0) {
370
            for ($x = 0; $x < $w - 1; $x++) {
371
                for ($y = 0; $y < $h; $y++) {
372
                    $rgbOrig = imagecolorat($img, $x, $y);
373
                    $rOrig = (($rgbOrig >> 16) & 0xFF);
374
                    $gOrig = (($rgbOrig >> 8) & 0xFF);
375
                    $bOrig = ($rgbOrig & 0xFF);
376
377
                    $rgbBlur = imagecolorat($imgBlur, $x, $y);
378
379
                    $rBlur = (($rgbBlur >> 16) & 0xFF);
380
                    $gBlur = (($rgbBlur >> 8) & 0xFF);
381
                    $bBlur = ($rgbBlur & 0xFF);
382
383
                    $rNew = (abs($rOrig - $rBlur) >= $threshold) ? max(0, min(255, ($amount * ($rOrig - $rBlur)) + $rOrig)) : $rOrig;
384
                    $gNew = (abs($gOrig - $gBlur) >= $threshold) ? max(0, min(255, ($amount * ($gOrig - $gBlur)) + $gOrig)) : $gOrig;
385
                    $bNew = (abs($bOrig - $bBlur) >= $threshold) ? max(0, min(255, ($amount * ($bOrig - $bBlur)) + $bOrig)) : $bOrig;
386
387
                    if (($rOrig != $rNew) || ($gOrig != $gNew) || ($bOrig != $bNew)) {
388
                        $pixCol = imagecolorallocate($img, $rNew, $gNew, $bNew);
389
                        imagesetpixel($img, $x, $y, $pixCol);
390
                    }
391
                }
392
            }
393
        } else {
394
            for ($x = 0; $x < $w; $x++) {
395
                for ($y = 0; $y < $h; $y++) {
396
                    $rgbOrig = imagecolorat($img, $x, $y);
397
                    $rOrig = (($rgbOrig >> 16) & 0xFF);
398
                    $gOrig = (($rgbOrig >> 8) & 0xFF);
399
                    $bOrig = ($rgbOrig & 0xFF);
400
401
                    $rgbBlur = imagecolorat($imgBlur, $x, $y);
402
403
                    $rBlur = (($rgbBlur >> 16) & 0xFF);
404
                    $gBlur = (($rgbBlur >> 8) & 0xFF);
405
                    $bBlur = ($rgbBlur & 0xFF);
406
407
                    $rNew = ($amount * ($rOrig - $rBlur)) + $rOrig;
408
                    if ($rNew > 255) {
409
                        $rNew = 255;
410
                    } elseif ($rNew < 0) {
411
                        $rNew = 0;
412
                    }
413
                    $gNew = ($amount * ($gOrig - $gBlur)) + $gOrig;
414
                    if ($gNew > 255) {
415
                        $gNew = 255;
416
                    } elseif ($gNew < 0) {
417
                        $gNew = 0;
418
                    }
419
                    $bNew = ($amount * ($bOrig - $bBlur)) + $bOrig;
420
                    if ($bNew > 255) {
421
                        $bNew = 255;
422
                    } elseif ($bNew < 0) {
423
                        $bNew = 0;
424
                    }
425
                    $rgbNew = ($rNew << 16) + ($gNew << 8) + $bNew;
426
                    imagesetpixel($img, $x, $y, $rgbNew);
427
                }
428
            }
429
        }
430
431
        imagedestroy($imgCanvas);
432
        imagedestroy($imgBlur);
433
434
        return $this;
435
    }
436
437
    /**
438
     * @param Nip_File_Image $image
439
     *
440
     * @return $this
441
     */
442
    public function copyResource(self $image)
443
    {
444
        $this->_width = $image->getWidth();
445
        $this->_height = $image->getHeight();
446
        $this->_resource = $image->getResource();
447
448
        return $this;
449
    }
450
451
    public function getResource()
452
    {
453
        return $this->_resource;
454
    }
455
456
    public function setResource($gdImage)
457
    {
458
        $this->_resource = $gdImage;
459
    }
460
461
    /**
462
     * @return mixed
463
     */
464
    public function getFile()
465
    {
466
        return $this->_file;
467
    }
468
469
    /**
470
     * @return string
471
     */
472
    public function getExtension()
473
    {
474
        return Nip_File_System::instance()->getExtension($this->path);
475
    }
476
}
477