Passed
Push — master ( afe694...4c5a84 )
by Petr
02:23
created

Processor::__construct()   B

Complexity

Conditions 10
Paths 2

Size

Total Lines 20
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 10.0454

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 10
eloc 12
c 1
b 0
f 0
nc 2
nop 2
dl 0
loc 20
ccs 12
cts 13
cp 0.9231
crap 10.0454
rs 7.6666

How to fix   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
namespace kalanis\kw_images\Graphics;
4
5
6
use kalanis\kw_images\ImagesException;
7
use kalanis\kw_images\Interfaces\IIMTranslations;
8
use kalanis\kw_images\Interfaces\IExifConstants;
9
use kalanis\kw_images\Traits\TLang;
10
11
12
/**
13
 * Class Processor
14
 * @package kalanis\kw_images
15
 * Pass images in temporary local storage  - cannot work with images directly in main storage
16
 */
17
class Processor
18
{
19
    use TLang;
20
21
    protected Format\Factory $factory;
22
    /** @var resource|\GdImage|null */
23
    protected $resource = null;
24
25
    /**
26
     * @param Format\Factory $factory
27
     * @param IIMTranslations|null $lang
28
     * @throws ImagesException
29
     */
30 35
    public function __construct(Format\Factory $factory, ?IIMTranslations $lang = null)
31
    {
32 35
        $this->setImLang($lang);
33
34 35
        if (!(function_exists('imagecreatetruecolor')
35 35
            && function_exists('imagecolorallocate')
36 35
            && function_exists('imagesetpixel')
37 35
            && function_exists('imagecopyresized')
38 35
            && function_exists('imagecopyresampled')
39 35
            && function_exists('imagesx')
40 35
            && function_exists('imagesy')
41 35
            && function_exists('imagerotate')
42 35
            && function_exists('imageflip')
43
        )) {
44
            // @codeCoverageIgnoreStart
45
            throw new ImagesException($this->getImLang()->imGdLibNotPresent());
46
        }
47
        // @codeCoverageIgnoreEnd
48
49 35
        $this->factory = $factory;
50 35
    }
51
52
    /**
53
     * @param string $type
54
     * @param string $tempPath
55
     * @throws ImagesException
56
     * @return $this
57
     */
58 13
    public function load(string $type, string $tempPath): self
59
    {
60 13
        $processor = $this->factory->getByType($type, $this->getImLang());
61 12
        $this->resource = $processor->load($tempPath);
62 12
        return $this;
63
    }
64
65
    /**
66
     * @param string $type
67
     * @param string $tempPath
68
     * @throws ImagesException
69
     * @return $this
70
     */
71 9
    public function save(string $type, string $tempPath): self
72
    {
73 9
        $processor = $this->factory->getByType($type, $this->getImLang());
74 9
        $processor->save($tempPath, $this->getResource());
75 9
        return $this;
76
    }
77
78
    /**
79
     * Change image size - cut it to desired size
80
     * @param int|null $width
81
     * @param int|null $height
82
     * @throws ImagesException
83
     * @return $this
84
     */
85 1
    public function resize(?int $width = null, ?int $height = null): self
86
    {
87 1
        $fromWidth = $this->width();
88 1
        $fromHeight = $this->height();
89 1
        $width = (!is_null($width) && (0 < $width)) ? intval($width) : $fromWidth;
90 1
        $height = (!is_null($height) && (0 < $height)) ? intval($height) : $fromHeight;
91 1
        $resource = $this->create($width, $height);
92 1
        if (false === imagecopyresized($resource, $this->getResource(), 0, 0, 0, 0, $width, $height, $fromWidth, $fromHeight)) {
93
            // @codeCoverageIgnoreStart
94
            imagedestroy($resource);
95
            throw new ImagesException($this->getImLang()->imImageCannotResize());
96
        }
97
        // @codeCoverageIgnoreEnd
98 1
        imagedestroy($this->getResource());
99 1
        $this->resource = $resource;
100 1
        return $this;
101
    }
102
103
    /**
104
     * Change image size - content will change its proportions according the passed sizes
105
     * @param int|null $width
106
     * @param int|null $height
107
     * @throws ImagesException
108
     * @return $this
109
     */
110 7
    public function resample(?int $width = null, ?int $height = null): self
111
    {
112 7
        $fromWidth = $this->width();
113 7
        $fromHeight = $this->height();
114 7
        $width = (!is_null($width) && (0 < $width)) ? intval($width) : $fromWidth;
115 7
        $height = (!is_null($height) && (0 < $height)) ? intval($height) : $fromHeight;
116 7
        $resource = $this->create($width, $height);
117 7
        if (false === imagecopyresampled($resource, $this->getResource(), 0, 0, 0, 0, $width, $height, $fromWidth, $fromHeight)) {
118
            // @codeCoverageIgnoreStart
119
            imagedestroy($resource);
120
            throw new ImagesException($this->getImLang()->imImageCannotResample());
121
        }
122
        // @codeCoverageIgnoreEnd
123 7
        imagedestroy($this->getResource());
124 7
        $this->resource = $resource;
125 7
        return $this;
126
    }
127
128
    /**
129
     * Orientate image by passed info
130
     * @param int $currentOrientation
131
     * @throws ImagesException
132
     * @return $this
133
     * @link https://jdhao.github.io/2019/07/31/image_rotation_exif_info/#exif-orientation-flag
134
     * @link https://stackoverflow.com/questions/7489742/php-read-exif-data-and-adjust-orientation
135
     */
136
    public function orientate(int $currentOrientation): self
137
    {
138
        $image = $this->resource; // normal
139
        if (in_array($currentOrientation, [
140
            IExifConstants::EXIF_ORIENTATION_UPSIDE_DOWN,
141
            IExifConstants::EXIF_ORIENTATION_MIRROR_UPSIDE_DOWN,
142
        ])) {
143
            $image = imagerotate($this->resource, 180, 0);
144
        }
145
        if (in_array($currentOrientation, [
146
            IExifConstants::EXIF_ORIENTATION_ON_LEFT,
147
            IExifConstants::EXIF_ORIENTATION_MIRROR_ON_LEFT,
148
        ])) {
149
            $image = imagerotate($this->resource, 270, 0);
150
        }
151
        if (in_array($currentOrientation, [
152
            IExifConstants::EXIF_ORIENTATION_ON_RIGHT,
153
            IExifConstants::EXIF_ORIENTATION_MIRROR_ON_RIGHT,
154
        ])) {
155
            $image = imagerotate($this->resource, 90, 0);
156
        }
157
        if (empty($image)) {
158
            // @codeCoverageIgnoreStart
159
            throw new ImagesException($this->getImLang()->imImageCannotOrientate());
160
        }
161
        // @codeCoverageIgnoreEnd
162
        if (in_array($currentOrientation, [
163
            IExifConstants::EXIF_ORIENTATION_MIRROR_SIMPLE,
164
            IExifConstants::EXIF_ORIENTATION_MIRROR_ON_LEFT,
165
            IExifConstants::EXIF_ORIENTATION_MIRROR_ON_RIGHT,
166
            IExifConstants::EXIF_ORIENTATION_MIRROR_UPSIDE_DOWN,
167
        ])) {
168
            imageflip($image, IMG_FLIP_HORIZONTAL);
169
        }
170
        $this->resource = $image;
171
172
        return $this;
173
    }
174
175
    /**
176
     * Create empty image resource
177
     * @param int $width
178
     * @param int $height
179
     * @throws ImagesException
180
     * @return \GdImage|resource
181
     */
182 8
    protected function create(int $width, int $height)
183
    {
184 8
        $resource = imagecreatetruecolor($width, $height);
185 8
        if (false === $resource) {
186
            // @codeCoverageIgnoreStart
187
            throw new ImagesException($this->getImLang()->imImageCannotCreateEmpty());
188
        }
189
        // @codeCoverageIgnoreEnd
190 8
        return $resource;
191
    }
192
193
    /**
194
     * @throws ImagesException
195
     * @return int
196
     */
197 11
    public function width(): int
198
    {
199 11
        $size = imagesx($this->getResource());
200 11
        if (false === $size) {
201
            // @codeCoverageIgnoreStart
202
            throw new ImagesException($this->getImLang()->imImageCannotGetSize());
203
        }
204
        // @codeCoverageIgnoreEnd
205 11
        return intval($size);
206
    }
207
208
    /**
209
     * @throws ImagesException
210
     * @return int
211
     */
212 13
    public function height(): int
213
    {
214 13
        $size = imagesy($this->getResource());
215 12
        if (false === $size) {
216
            // @codeCoverageIgnoreStart
217
            throw new ImagesException($this->getImLang()->imImageCannotGetSize());
218
        }
219
        // @codeCoverageIgnoreEnd
220 12
        return intval($size);
221
    }
222
223
    /**
224
     * @throws ImagesException
225
     * @return \GdImage|resource
226
     */
227 13
    public function getResource()
228
    {
229 13
        if (empty($this->resource)) {
230 1
            throw new ImagesException($this->getImLang()->imImageLoadFirst());
231
        }
232 12
        return $this->resource;
233
    }
234
}
235