Passed
Push — master ( 1a28e9...0cc18a )
by Derek Stephen
01:49
created

Image::destroy()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Del;
4
5
use Del\Image\Exception\NotFoundException;
6
use Del\Image\Exception\NothingLoadedException;
7
8
class Image 
9
{
10
    /** @var resource $image */
11
    private $image;
12
13
    /** @var int $imageType */
14
    private $imageType;
15
16
    /** @var string $fileName */
17
    private $fileName;
18
19
    /** @var array  */
20
    private $contentType = [
21
        IMAGETYPE_JPEG => 'image/jpeg',
22
        IMAGETYPE_GIF => 'image/gif',
23
        IMAGETYPE_PNG =>'image/png',
24
    ];
25
26
    /** @var array  */
27
    private $createCommand = [
28
        IMAGETYPE_JPEG => 'imagecreatefromjpeg',
29
        IMAGETYPE_GIF => 'imagecreatefromgif',
30
        IMAGETYPE_PNG =>'imagecreatefrompng',
31
    ];
32
33
    /** @var array  */
34
    private $saveMethod = [
35
        IMAGETYPE_JPEG => 'saveJpg',
36
        IMAGETYPE_GIF => 'saveGif',
37
        IMAGETYPE_PNG => 'savePng',
38
    ];
39
40
    /**
41
     * @param string $filename
42
     */
43 21
    public function __construct($filename = null)
44
    {
45 21
        if ($filename !== null) {
46 1
            $this->fileName = $filename;
47 1
            $this->load($filename);
48
        }
49 21
    }
50
51
    /**
52
     * @param $path
53
     * @throws NotFoundException
54
     */
55 20
    private function checkFileExists($path)
56
    {
57 20
        if (!file_exists($path)) {
58 1
            throw new NotFoundException("$path does not exist");
59
        }
60 19
    }
61
62
63
    /**
64
     * @param string $filename
65
     * @throws NotFoundException
66
     */
67 20
    public function load($filename)
68
    {
69 20
        $this->checkFileExists($filename);
70 19
        $imageInfo = getimagesize($filename);
71 19
        $this->imageType = $imageInfo[2];
72 19
        $this->image = $this->createCommand[$this->imageType]($filename);
73 19
    }
74
75
76
    /**
77
     *  @param string $filename
78
     *  @param int $compression
79
     *  @param string $permissions
80
     */
81 3
    public function save($filename = null, $compression = 100, $permissions = null)
82
    {
83 3
        $filename = ($filename) ?: $this->fileName;
84 3
        $this->saveMethod[$this->imageType]($this->image, $filename, $compression);
85
        $this->setPermissions($filename, $permissions);
86
    }
87
88
    /**
89
     * @param $resource
90
     * @param $filename
91
     * @param $compression
92
     */
93
    private function saveJpg($resource, $filename, $compression)
1 ignored issue
show
Unused Code introduced by
The parameter $resource is not used and could be removed. ( Ignorable by Annotation )

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

93
    private function saveJpg(/** @scrutinizer ignore-unused */ $resource, $filename, $compression)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The method saveJpg() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
94
    {
95
        imagejpeg($this->image, $filename, $compression);
96
    }
97
98
    /**
99
     * @param $resource
100
     * @param $filename
101
     * @param $compression
102
     */
103
    private function saveGif($resource, $filename, $compression)
1 ignored issue
show
Unused Code introduced by
The method saveGif() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
Unused Code introduced by
The parameter $compression is not used and could be removed. ( Ignorable by Annotation )

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

103
    private function saveGif($resource, $filename, /** @scrutinizer ignore-unused */ $compression)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $resource is not used and could be removed. ( Ignorable by Annotation )

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

103
    private function saveGif(/** @scrutinizer ignore-unused */ $resource, $filename, $compression)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
104
    {
105
        imagegif($this->image, $filename);
106
    }
107
108
    /**
109
     * @param $resource
110
     * @param $filename
111
     * @param $compression
112
     */
113
    private function savePng($resource, $filename, $compression)
1 ignored issue
show
Unused Code introduced by
The parameter $compression is not used and could be removed. ( Ignorable by Annotation )

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

113
    private function savePng($resource, $filename, /** @scrutinizer ignore-unused */ $compression)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $resource is not used and could be removed. ( Ignorable by Annotation )

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

113
    private function savePng(/** @scrutinizer ignore-unused */ $resource, $filename, $compression)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The method savePng() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
114
    {
115
        imagepng($this->image, $filename);
116
    }
117
118
    /**
119
     * @param $filename
120
     * @param $permissions
121
     */
122
    private function setPermissions($filename, $permissions)
123
    {
124
        if ($permissions !== null) {
125
            chmod($filename, (int) $permissions);
126
        }
127
    }
128
129
130
    /**
131
     * @param bool $return either output directly
132
     * @return void|string image contents
133
     */
134 11
    public function output($return = false)
135
    {
136 11
        if ($return) {
137 11
            ob_start();
138
        }
139
140 11
        $this->renderImage();
141
142 11
        if ($return) {
143 11
            $contents = ob_get_flush();
144 11
            return $contents;
145
        }
146
    }
147
148 11
    private function renderImage()
149
    {
150 11
        switch ($this->imageType) {
151 11
            case IMAGETYPE_JPEG:
152 2
                imagejpeg($this->image);
153 2
                break;
154 9
            case IMAGETYPE_GIF:
155 1
                imagegif($this->image);
156 1
                break;
157 8
            case IMAGETYPE_PNG:
158 8
                imagealphablending($this->image, true);
159 8
                imagesavealpha($this->image, true);
160 8
                imagepng($this->image);
161 8
                break;
162
        }
163 11
    }
164
165
    /**
166
     * @return int
167
     */
168 8
    public function getWidth()
169
    {
170 8
        return imagesx($this->image);
171
    }
172
173
    /**
174
     * @return int
175
     */
176 8
    public function getHeight()
177
    {
178 8
        return imagesy($this->image);
179
    }
180
181
    /**
182
     * @param int $height
183
     */
184 2
    public function resizeToHeight($height)
185
    {
186 2
        $ratio = $height / $this->getHeight();
187 2
        $width = $this->getWidth() * $ratio;
188 2
        $this->resize($width, $height);
189 2
    }
190
191
    /**
192
     * @param int $width
193
     */
194 2
    public function resizeToWidth($width)
195
    {
196 2
        $ratio = $width / $this->getWidth();
197 2
        $height = $this->getHeight() * $ratio;
198 2
        $this->resize($width, $height);
199 2
    }
200
201
    /**
202
     * @param int $scale %
203
     */
204 1
    public function scale($scale)
205
    {
206 1
        $width = $this->getWidth() * $scale / 100;
207 1
        $height = $this->getHeight() * $scale / 100;
208 1
        $this->resize($width, $height);
209 1
    }
210
211
    /**
212
     * @param int $width
213
     * @param int $height
214
     */
215 3
    public function resizeAndCrop($width, $height)
216
    {
217 3
        $targetRatio = $width / $height;
218 3
        $actualRatio = $this->getWidth() / $this->getHeight();
219
220 3
        if ($targetRatio == $actualRatio) {
221
            // Scale to size
222 1
            $this->resize($width, $height);
223 2
        } elseif ($targetRatio > $actualRatio) {
224
            // Resize to width, crop extra height
225 1
            $this->resizeToWidth($width);
226 1
            $this->crop($width, $height);
227
        } else {
228
            // Resize to height, crop additional width
229 1
            $this->resizeToHeight($height);
230 1
            $this->crop($width, $height);
231
        }
232 3
    }
233
234
235
    /**
236
     *  Now with added Transparency resizing feature
237
     *  @param int $width
238
     *  @param int $height
239
     */
240 6
    public function resize($width, $height)
241
    {
242 6
        $newImage = imagecreatetruecolor($width, $height);
243
244 6
        if (($this->getImageType() == IMAGETYPE_GIF) || ($this->getImageType() == IMAGETYPE_PNG)) {
245
246
            // Get transparency color's index number
247 6
            $transparency = imagecolortransparent($this->image);
248
249
            // Is a strange index other than -1 set?
250 6
            if ($transparency >= 0) {
251
252
                // deal with alpha channels
253
                $this->prepWithExistingIndex($newImage, $transparency);
254
255 6
            } elseif ($this->getImageType() == IMAGETYPE_PNG) {
256
257
                // deal with alpha channels
258 6
                $this->prepTransparentPng($newImage);
259
            }
260
        }
261
262
        // Now resample the image
263 6
        imagecopyresampled($newImage, $this->image, 0, 0, 0, 0, $width, $height, $this->getWidth(), $this->getHeight());
264
265
        // And allocate to $this
266 6
        $this->image = $newImage;
267 6
    }
268
269
    /**
270
     * @param $resource
271
     * @param $index
272
     */
273
    private function prepWithExistingIndex($resource, $index)
274
    {
275
        // Get the array of RGB vals for the transparency index
276
        $transparentColor = imagecolorsforindex($this->image, $index);
277
278
        // Now allocate the color
279
        $transparency = imagecolorallocate($resource, $transparentColor['red'], $transparentColor['green'], $transparentColor['blue']);
280
281
        // Fill the background with the color
282
        imagefill($resource, 0, 0, $transparency);
283
284
        // And set that color as the transparent one
285
        imagecolortransparent($resource, $transparency);
286
    }
287
288
    /**
289
     * @param $resource
290
     */
291 6
    private function prepTransparentPng($resource)
292
    {
293
        // Set blending mode as false
294 6
        imagealphablending($resource, false);
295
296
        // Tell it we want to save alpha channel info
297 6
        imagesavealpha($resource, true);
298
299
        // Set the transparent color
300 6
        $color = imagecolorallocatealpha($resource, 0, 0, 0, 127);
301
302
        // Fill the image with nothingness
303 6
        imagefill($resource, 0, 0, $color);
304 6
    }
305
306
307
    /**
308
     * @param int $width
309
     * @param int $height
310
     * @param string $trim
311
     */
312 3
    public function crop($width, $height, $trim = 'center')
313
    {
314 3
        $offsetX = 0;
315 3
        $offsetY = 0;
316 3
        $currentWidth = $this->getWidth();
317 3
        $currentHeight = $this->getHeight();
318
319 3
        if ($trim != 'left') {
320 3
            if ($currentWidth > $width) {
321 2
                $diff = $currentWidth - $width;
322 2
                $offsetX = ($trim == 'center') ? $diff / 2 : $diff; //full diff for trim right
323
            }
324 3
            if ($currentHeight > $height) {
325 2
                $diff = $currentHeight - $height;
326 2
                $offsetY = ($trim == 'center') ? $diff / 2 : $diff;
327
            }
328
        }
329
330 3
        $newImage = imagecreatetruecolor($width, $height);
331 3
        imagecopyresampled($newImage, $this->image, 0, 0, $offsetX, $offsetY, $width, $height, $width, $height);
332 3
        $this->image = $newImage;
333 3
    }
334
335
    /**
336
     * @return mixed
337
     */
338 6
    public function getImageType()
339
    {
340 6
        return $this->imageType;
341
    }
342
343
    /**
344
     * @return mixed
345
     * @throws NothingLoadedException
346
     */
347 4
    public function getHeader()
348
    {
349 4
        if (!$this->imageType) {
350 1
            throw new NothingLoadedException();
351
        }
352 3
        return $this->contentType[$this->imageType];
353
    }
354
355
    /**
356
     *  Frees up memory
357
     */
358 1
    public function destroy()
359
    {
360 1
        imagedestroy($this->image);
361 1
    }
362
}
363