Passed
Branch master (d2dc0d)
by compolom
04:15 queued 01:44
created

GD::getImage()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
nc 1
cc 1
eloc 2
nop 0
1
<?php declare(strict_types=1);
2
3
namespace Compolomus\Compomage;
4
5
use Compolomus\Compomage\Interfaces\ImageInterface;
6
7
class GD extends AbstractImage implements ImageInterface
8
{
9
    /**
10
     * GD constructor.
11
     * @param string $image
12
     * @throws \Exception
13
     */
14
    public function __construct(string $image)
15
    {
16
        $this->init($image);
17
    }
18
19
    /**
20
     * @return resource
21
     */
22
    public function getImage()
23
    {
24
        return $this->image;
25
    }
26
27
    /**
28
     * @param string $source
29
     * @return ImageInterface
30
     * @throws \Exception
31
     */
32
    protected function tmp(string $source): ImageInterface
33
    {
34
        $image = imagecreatefromstring($source);
35
        if (!\is_resource($image)) {
36
            throw new \InvalidArgumentException('Image create failed');
37
        }
38
        $this->setImage($image);
39
        $this->setSizes();
40
        // save transparent
41
        imagesavealpha($this->getImage(), true);
42
        imagealphablending($this->getImage(), false);
43
44
        return $this;
45
    }
46
47
    public function flip(): ImageInterface
48
    {
49
        imageflip($this->getImage(), IMG_FLIP_VERTICAL);
50
51
        return $this;
52
    }
53
54
    public function flop(): ImageInterface
55
    {
56
        imageflip($this->getImage(), IMG_FLIP_HORIZONTAL);
57
58
        return $this;
59
    }
60
61
    public function grayscale(): ImageInterface
62
    {
63
        imagefilter($this->getImage(), IMG_FILTER_GRAYSCALE);
64
65
        return $this;
66
    }
67
68
    /**
69
     * @param string $text
70
     * @param string $font
71
     * @param string $position
72
     * @return $this
73
     * @throws \Exception
74
     */
75
    public function copyright(string $text, string $font, string $position = 'SouthWest'): ImageInterface
76
    {
77
        if (!array_key_exists(strtoupper($position), self::POSITIONS)) {
78
            throw new \InvalidArgumentException('Wrong position');
79
        }
80
81
        imagecopymerge(
82
            $this->getImage(),
83
            $image = $this->prepareImage($text, $font),
84
            (int) ((($this->getWidth() - imagesx($image)) / 2) * self::POSITIONS[strtoupper($position)]['x']) + self::POSITIONS[strtoupper($position)]['padX'],
85
            (int) ((($this->getHeight() - imagesy($image)) / 2) * self::POSITIONS[strtoupper($position)]['y']) + self::POSITIONS[strtoupper($position)]['padY'],
86
            0,
87
            0,
88
            $this->getWidth(),
89
            $this->getHeight(),
90
            80
91
        );
92
93
        return $this;
94
    }
95
96
    /**
97
     * @param string $text
98
     * @param string $font
99
     * @return resource
100
     * @throws \Exception
101
     */
102
    private function prepareImage(string $text, string $font)
103
    {
104
        if (!$coordinates = imagettfbbox($fontSize = 15, 0, $font, $text)) {
105
            throw new \InvalidArgumentException('Does not support font');
106
        }
107
108
        $minX = min([$coordinates[0], $coordinates[2], $coordinates[4], $coordinates[6]]);
109
        $maxX = max([$coordinates[0], $coordinates[2], $coordinates[4], $coordinates[6]]);
110
        $minY = min([$coordinates[1], $coordinates[3], $coordinates[5], $coordinates[7]]);
111
        $maxY = max([$coordinates[1], $coordinates[3], $coordinates[5], $coordinates[7]]);
112
        $textX = (int) abs($minX) + 1;
113
        $textY = (int) abs($minY) + 1;
114
        $image = $this->newImage($maxX - $minX + 2, $maxY - $minY + 2);
115
        imagecolortransparent($image, $white = imagecolorallocate($image, 0, 0, 0));
116
        imagefilledrectangle($image, 0, 0, $this->getWidth(), 20, $white);
117
        imagettftext($image, $fontSize, 0, $textX, $textY, $white, $font, $text);
118
        imagettftext($image, $fontSize, 0, $textX + 1, $textY + 1, $blue = imagecolorallocate($image, 0, 128, 128), $font, $text);
119
        imagettftext($image, $fontSize, 0, $textX + 1, $textY + 1, $red = imagecolorallocate($image, 255, 0, 0), $font, $text);
120
        imagettftext($image, $fontSize, 0, $textX + 2, $textY + 2, $black = imagecolorallocate($image, 255, 255, 255), $font, $text);
121
        imagettftext($image, $fontSize, 0, $textX + 2, $textY + 2, $gray = imagecolorallocate($image, 128, 128, 128), $font, $text);
122
123
        return $image;
124
    }
125
126
    protected function setSizes(): void
127
    {
128
        $this->setWidth(imagesx($this->getImage()));
129
        $this->setHeight(imagesy($this->getImage()));
130
    }
131
132
    private function newImage(int $width, int $height)
133
    {
134
        $newimg = imagecreatetruecolor($width, $height);
135
        $transparent = imagecolorallocatealpha($newimg, 255, 255, 255, 127);
136
        imagefill($newimg, 0, 0, $transparent);
137
        imagealphablending($newimg, true);
138
        imagesavealpha($newimg, true);
139
140
        return $newimg;
141
    }
142
143
    public function resize(int $width, int $height): ImageInterface
144
    {
145
        $newimage = $this->newImage($width, $height);
146
        imagecopyresampled($newimage, $this->getImage(), 0, 0, 0, 0, $width, $height, $this->getWidth() , $this->getHeight());
147
        $this->setImage($newimage);
148
        $this->setSizes();
149
150
        return $this;
151
    }
152
153
    public function crop(int $width, int $height, int $x, int $y): ImageInterface
154
    {
155
        $width -= $x;
156
        $height -= $y;
157
        $newimage = $this->newImage($width, $height);
158
        imagecopyresampled($newimage, $this->getImage(), 0, 0, $x, $y, $width, $height, $width, $height);
159
        $this->setImage($newimage);
160
        $this->setSizes();
161
162
        return $this;
163
    }
164
165
    /**
166
     * @param Image $watermark
167
     * @param int $x
168
     * @param int $y
169
     * @return ImageInterface
170
     */
171
    protected function prepareWatermark(Image $watermark, int $x, int $y): ImageInterface
172
    {
173
        imagealphablending($this->getImage(), true);
174
        imagesavealpha($this->getImage(), true);
175
        imagecopyresampled(
176
            $this->getImage(),
177
            $watermark->getImage(),
178
            $x,
179
            $y,
180
            0,
181
            0,
182
            $width = $watermark->getWidth(),
183
            $height = $watermark->getHeight(),
184
            $width,
185
            $height
186
        );
187
188
        return $this;
189
    }
190
191
    public function rotate(int $angle = 90): ImageInterface
192
    {
193
        $transparent = imagecolorallocatealpha($this->image, 0, 0, 0, 127);
194
        $rotate = imagerotate($this->getImage(), $angle, $transparent);
195
        imagealphablending($rotate, true);
196
        imagesavealpha($rotate, true);
197
        $this->setImage($rotate);
198
        $this->setSizes();
199
200
        return $this;
201
    }
202
203
    public function __toString(): string
204
    {
205
        ob_start();
206
        imagepng($this->getImage(), null, 9, PNG_ALL_FILTERS);
207
        $temp = ob_get_contents();
208
        ob_clean();
209
210
        return trim($temp);
211
    }
212
213
    public function save(string $filename): bool
214
    {
215
        return true;
216
    }
217
}
218