Completed
Push — master ( 8ba72f...a2bda9 )
by Derek Stephen
01:51
created

Image::resizeToWidth()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 1
dl 0
loc 5
ccs 4
cts 4
cp 1
crap 1
rs 9.4285
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
use Del\Image\Strategy\GifStrategy;
8
use Del\Image\Strategy\ImageTypeStrategyInterface;
9
use Del\Image\Strategy\JpegStrategy;
10
use Del\Image\Strategy\PngStrategy;
11
12
class Image 
13
{
14
    /** @var resource $image */
15
    private $image;
16
17
    /** @var string $fileName */
18
    private $fileName;
19
20
    /** @var ImageTypeStrategyInterface $strategy */
21
    private $strategy;
22
23
    /** @var array $strategies */
24
    private $strategies = [
25
        IMAGETYPE_JPEG => JpegStrategy::class,
26
        IMAGETYPE_GIF => GifStrategy::class,
27
        IMAGETYPE_PNG => PngStrategy::class,
28
    ];
29
30
    /**
31
     * @param string $filename
32
     */
33 21
    public function __construct($filename = null)
34
    {
35 21
        if ($filename !== null) {
36 1
            $this->fileName = $filename;
37 1
            $this->load($filename);
38
        }
39 21
    }
40
41
    /**
42
     * @param $path
43
     * @throws NotFoundException
44
     */
45 20
    private function checkFileExists($path)
46
    {
47 20
        if (!file_exists($path)) {
48 1
            throw new NotFoundException("$path does not exist");
49
        }
50 19
    }
51
52
53
    /**
54
     * @param string $filename
55
     * @throws NotFoundException
56
     */
57 20
    public function load($filename)
58
    {
59 20
        $this->checkFileExists($filename);
60 19
        $this->strategy = new $this->strategies[getimagesize($filename)[2]]();
61 19
        $this->image = $this->strategy->create($filename);
62 19
    }
63
64
65
    /**
66
     *  @param string $filename
67
     *  @param int $compression
68
     *  @param string $permissions
69
     */
70 3
    public function save($filename = null, $compression = 100, $permissions = null)
71
    {
72 3
        $filename = ($filename) ?: $this->fileName;
73 3
        $this->strategy->save($this->image, $filename, $compression);
74 3
        $this->setPermissions($filename, $permissions);
75 3
    }
76
77
    /**
78
     * @param $filename
79
     * @param $permissions
80
     */
81 3
    private function setPermissions($filename, $permissions)
82
    {
83 3
        if ($permissions !== null) {
84 1
            chmod($filename, (int) $permissions);
85
        }
86 3
    }
87
88
89
    /**
90
     * @param bool $return either output directly
91
     * @return void|string image contents
92
     */
93 14
    public function output($return = false)
94
    {
95 14
        if ($return) {
96 14
            ob_start();
97
        }
98
99 14
        $this->renderImage();
100
101 14
        if ($return) {
102 14
            $contents = ob_get_flush();
103 14
            return $contents;
104
        }
105
    }
106
107 14
    private function renderImage()
108
    {
109 14
        $this->strategy->render($this->image);
110 14
    }
111
112
    /**
113
     * @return int
114
     */
115 8
    public function getWidth()
116
    {
117 8
        return imagesx($this->image);
118
    }
119
120
    /**
121
     * @return int
122
     */
123 8
    public function getHeight()
124
    {
125 8
        return imagesy($this->image);
126
    }
127
128
    /**
129
     * @param int $height
130
     */
131 2
    public function resizeToHeight($height)
132
    {
133 2
        $ratio = $height / $this->getHeight();
134 2
        $width = $this->getWidth() * $ratio;
135 2
        $this->resize($width, $height);
136 2
    }
137
138
    /**
139
     * @param int $width
140
     */
141 2
    public function resizeToWidth($width)
142
    {
143 2
        $ratio = $width / $this->getWidth();
144 2
        $height = $this->getHeight() * $ratio;
145 2
        $this->resize($width, $height);
146 2
    }
147
148
    /**
149
     * @param int $scale %
150
     */
151 1
    public function scale($scale)
152
    {
153 1
        $width = $this->getWidth() * $scale / 100;
154 1
        $height = $this->getHeight() * $scale / 100;
155 1
        $this->resize($width, $height);
156 1
    }
157
158
    /**
159
     * @param int $width
160
     * @param int $height
161
     */
162 3
    public function resizeAndCrop($width, $height)
163
    {
164 3
        $targetRatio = $width / $height;
165 3
        $actualRatio = $this->getWidth() / $this->getHeight();
166
167 3
        if ($targetRatio == $actualRatio) {
168
            // Scale to size
169 1
            $this->resize($width, $height);
170 2
        } elseif ($targetRatio > $actualRatio) {
171
            // Resize to width, crop extra height
172 1
            $this->resizeToWidth($width);
173 1
            $this->crop($width, $height);
174
        } else {
175
            // Resize to height, crop additional width
176 1
            $this->resizeToHeight($height);
177 1
            $this->crop($width, $height);
178
        }
179 3
    }
180
181
182
    /**
183
     *  Now with added Transparency resizing feature
184
     *  @param int $width
185
     *  @param int $height
186
     */
187 6
    public function resize($width, $height)
188
    {
189 6
        $newImage = imagecreatetruecolor($width, $height);
190
191 6
        $this->strategy->handleTransparency($newImage, $this->image);
192
193
        // Now resample the image
194 6
        imagecopyresampled($newImage, $this->image, 0, 0, 0, 0, $width, $height, $this->getWidth(), $this->getHeight());
195
196
        // And allocate to $this
197 6
        $this->image = $newImage;
198 6
    }
199
200
201
202
203
    /**
204
     * @param int $width
205
     * @param int $height
206
     * @param string $trim
207
     */
208 3
    public function crop($width, $height, $trim = 'center')
209
    {
210 3
        $offsetX = 0;
211 3
        $offsetY = 0;
212 3
        $currentWidth = $this->getWidth();
213 3
        $currentHeight = $this->getHeight();
214
215 3
        if ($trim != 'left') {
216 3
            $offsetX = $this->getOffsetX($currentWidth, $width, $trim);
217 3
            $offsetY = $this->getOffsetY($currentHeight, $height, $trim);
218
        }
219
220 3
        $newImage = imagecreatetruecolor($width, $height);
221 3
        imagecopyresampled($newImage, $this->image, 0, 0, $offsetX, $offsetY, $width, $height, $width, $height);
222 3
        $this->image = $newImage;
223 3
    }
224
225
    /**
226
     * @param $currentWidth
227
     * @param $width
228
     * @param $trim
229
     * @return float|int
230
     */
231 3
    private function getOffsetX($currentWidth, $width, $trim)
232
    {
233 3
        $offsetX = 0;
234 3
        if ($currentWidth > $width) {
235 2
            $diff = $currentWidth - $width;
236 2
            $offsetX = ($trim == 'center') ? $diff / 2 : $diff; //full diff for trim right
237
        }
238 3
        return $offsetX;
239
    }
240
241
    /**
242
     * @param $currentHeight
243
     * @param $height
244
     * @param $trim
245
     * @return float|int
246
     */
247 3
    private function getOffsetY($currentHeight, $height, $trim)
248
    {
249 3
        $offsetY = 0;
250 3
        if ($currentHeight > $height) {
251 2
            $diff = $currentHeight - $height;
252 2
            $offsetY = ($trim == 'center') ? $diff / 2 : $diff;
253
        }
254 3
        return $offsetY;
255
    }
256
257
    /**
258
     * @return mixed
259
     * @throws NothingLoadedException
260
     */
261 4
    public function getHeader()
262
    {
263 4
        if (!$this->strategy) {
264 1
            throw new NothingLoadedException();
265
        }
266 3
        return $this->strategy->getContentType();
267
    }
268
269
    /**
270
     *  Frees up memory
271
     */
272 1
    public function destroy()
273
    {
274 1
        imagedestroy($this->image);
275 1
    }
276
}
277