Completed
Push — master ( 0cc18a...3e458d )
by Derek Stephen
02:05
created

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