Completed
Push — 2.x-dev ( 5228a9...7776d6 )
by Oscar
02:17
created

Gd::createImage()   B

Complexity

Conditions 5
Paths 6

Size

Total Lines 22
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
c 3
b 0
f 0
dl 0
loc 22
rs 8.6737
cc 5
eloc 12
nc 6
nop 3

1 Method

Rating   Name   Duplication   Size   Complexity  
A Gd::getMimeType() 0 4 1
1
<?php
2
3
namespace Imagecow\Libs;
4
5
use Imagecow\ImageException;
6
7
/**
8
 * GD library.
9
 */
10
class Gd extends AbstractLib implements LibInterface
11
{
12
    public static $fallbackCropMethods = [
13
        'Entropy' => ['center', 'middle'],
14
        'Balanced' => ['center', 'middle'],
15
    ];
16
17
    protected $image;
18
    protected $type;
19
20
    /**
21
     * {@inheritdoc}
22
     */
23
    public static function checkCompatibility()
24
    {
25
        return extension_loaded('gd');
26
    }
27
28
    /**
29
     * {@inheritdoc}
30
     */
31
    public static function createFromFile($filename)
32
    {
33
        $data = @getImageSize($filename);
34
35
        if ($data && is_array($data)) {
36
            $function = 'imagecreatefrom'.image_type_to_extension($data[2], false);
37
38
            if (function_exists($function)) {
39
                return new static($function($filename), $data[2]);
40
            }
41
        }
42
43
        throw new ImageException("The image file '{$filename}' cannot be loaded");
44
    }
45
46
    /**
47
     * {@inheritdoc}
48
     */
49
    public static function createFromString($string)
50
    {
51
        if (($image = @imagecreatefromstring($string))) {
52
            return new static($image);
53
        }
54
55
        throw new ImageException('Error creating the image from string');
56
    }
57
58
    /**
59
     * Constructor of the class.
60
     *
61
     * @param resource $image The Gd resource.
62
     */
63
    public function __construct($image, $type = null)
64
    {
65
        $this->image = $image;
66
        $this->type = isset($type) ? $type : IMAGETYPE_PNG;
67
68
        imagealphablending($this->image, true);
69
        imagesavealpha($this->image, true);
70
        imagesetinterpolation($this->image, IMG_BICUBIC);
71
    }
72
73
    /**
74
     * Destroy the image.
75
     */
76
    public function __destruct()
77
    {
78
        imagedestroy($this->image);
79
    }
80
81
    /**
82
     * {@inheritdoc}
83
     */
84
    public function flip()
85
    {
86
        imageflip($this->image, IMG_FLIP_VERTICAL);
87
    }
88
89
    /**
90
     * {@inheritdoc}
91
     */
92
    public function flop()
93
    {
94
        imageflip($this->image, IMG_FLIP_HORIZONTAL);
95
    }
96
97
    /**
98
     * {@inheritdoc}
99
     */
100
    public function save($filename)
101
    {
102
        $extension = image_type_to_extension($this->type, false);
103
        $function = 'image'.$extension;
104
105
        if (!function_exists($function) || ($function($this->image, $filename) === false)) {
106
            throw new ImageException("The image format '{$extension}' cannot be saved to '{$filename}'");
107
        }
108
    }
109
110
    /**
111
     * {@inheritdoc}
112
     */
113
    public function getString()
114
    {
115
        $extension = image_type_to_extension($this->type, false);
116
        $function = 'image'.$extension;
117
118
        if (!function_exists($function)) {
119
            throw new ImageException("The image format '{$extension}' cannot be exported");
120
        }
121
122
        ob_start();
123
124
        if ($extension === 'jpeg') {
125
            $function($this->image, null, $this->quality);
126
        } else {
127
            $function($this->image);
128
        }
129
130
        return ob_get_clean();
131
    }
132
133
    /**
134
     * {@inheritdoc}
135
     */
136
    public function getMimeType()
137
    {
138
        return image_type_to_mime_type($this->type);
139
    }
140
141
    /**
142
     * {@inheritdoc}
143
     */
144
    public function getWidth()
145
    {
146
        return imagesx($this->image);
147
    }
148
149
    /**
150
     * {@inheritdoc}
151
     */
152
    public function getHeight()
153
    {
154
        return imagesy($this->image);
155
    }
156
157
    /**
158
     * {@inheritdoc}
159
     */
160
    public function format($format)
161
    {
162
        switch (strtolower($format)) {
163
            case 'jpg':
164
            case 'jpeg':
165
                $width = $this->getWidth();
166
                $height = $this->getHeight();
167
168
                if (($image = imagecreatetruecolor($width, $height)) === false) {
169
                    throw new ImageException('Error creating a image');
170
                }
171
172
                if (imagesavealpha($image, true) === false) {
173
                    throw new ImageException('Error saving the alpha chanel of the image');
174
                }
175
176
                if (isset($background[3])) {
0 ignored issues
show
Bug introduced by
The variable $background seems only to be defined at a later point. As such the call to isset() seems to always evaluate to false.

This check marks calls to isset(...) or empty(...) that are found before the variable itself is defined. These will always have the same result.

This is likely the result of code being shifted around. Consider removing these calls.

Loading history...
177
                    $background = imagecolorallocatealpha($image, $background[0], $background[1], $background[2], $background[3]);
178
                } else {
179
                    $background = imagecolorallocate($image, $background[0], $background[1], $background[2]);
0 ignored issues
show
Bug introduced by
The variable $background seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?

This error can happen if you refactor code and forget to move the variable initialization.

Let’s take a look at a simple example:

function someFunction() {
    $x = 5;
    echo $x;
}

The above code is perfectly fine. Now imagine that we re-order the statements:

function someFunction() {
    echo $x;
    $x = 5;
}

In that case, $x would be read before it is initialized. This was a very basic example, however the principle is the same for the found issue.

Loading history...
180
                }
181
182
                if (imagefill($image, 0, 0, $background) === false) {
183
                    throw new ImageException('Error filling the image');
184
                }
185
186
                imagecopy($image, $this->image, 0, 0, 0, 0, $width, $height);
187
188
                $this->image = $image;
189
                $this->type = IMAGETYPE_JPEG;
190
                break;
191
192
            case 'gif':
193
                $this->type = IMAGETYPE_GIF;
194
                break;
195
196
            case 'png':
197
                $this->type = IMAGETYPE_PNG;
198
                break;
199
200
            default:
201
                throw new ImageException("The image format '{$format}' is not valid");
202
        }
203
    }
204
205
    /**
206
     * {@inheritdoc}
207
     */
208
    public function resize($width, $height)
209
    {
210
        if (($image = imagescale($this->image, $width, $height, IMG_BICUBIC)) === false) {
211
            throw new ImageException('Error resizing the image');
212
        }
213
214
        $this->image = $image;
215
    }
216
217
    /**
218
     * {@inheritdoc}
219
     */
220
    public function getCropOffsets($width, $height, $method)
221
    {
222
        if (isset(static::$fallbackCropMethods[$method])) {
223
            return static::$fallbackCropMethods[$method];
224
        }
225
226
        throw new ImageException("The crop method '$method' is not available for Gd");
227
    }
228
229
    /**
230
     * {@inheritdoc}
231
     */
232
    public function crop($width, $height, $x, $y)
233
    {
234
        $crop = [
235
            'width' => $width,
236
            'height' => $height,
237
            'x' => $x,
238
            'y' => $y,
239
        ];
240
241
        if (($image = imagecrop($this->image, $crop)) === false) {
242
            throw new ImageException('Error cropping the image');
243
        }
244
245
        $this->image = $image;
246
    }
247
248
    /**
249
     * {@inheritdoc}
250
     */
251
    public function rotate($angle)
252
    {
253
        $background = imagecolorallocatealpha($this->image, 0, 0, 0, 127);
254
255
        if ($background === false || ($image = imagerotate($this->image, $angle, $background)) === false) {
256
            throw new ImageException('Error rotating the image');
257
        }
258
259
        $this->image = $image;
260
    }
261
}
262