1 | <?php |
||||
2 | /** |
||||
3 | * Class Image |
||||
4 | * |
||||
5 | * @link https://www.icy2003.com/ |
||||
6 | * @author icy2003 <[email protected]> |
||||
7 | * @copyright Copyright (c) 2017, icy2003 |
||||
8 | */ |
||||
9 | namespace icy2003\php\ihelpers; |
||||
10 | |||||
11 | use Exception; |
||||
12 | use icy2003\php\C; |
||||
13 | use icy2003\php\I; |
||||
14 | use icy2003\php\icomponents\file\LocalFile; |
||||
15 | |||||
16 | /** |
||||
17 | * 图片处理类 |
||||
18 | */ |
||||
19 | class Image |
||||
20 | { |
||||
21 | |||||
22 | /** |
||||
23 | * 加载图片 |
||||
24 | * |
||||
25 | * @param string $image 图片路径 |
||||
26 | * |
||||
27 | * @return void |
||||
28 | */ |
||||
29 | public function __construct($image) |
||||
30 | { |
||||
31 | $this->_attributes = $this->__parseImage($image); |
||||
32 | $this->_imageIn = $this->_attributes['object']; |
||||
0 ignored issues
–
show
|
|||||
33 | } |
||||
34 | |||||
35 | /** |
||||
36 | * 输入图片对象 |
||||
37 | * |
||||
38 | * @var resource |
||||
39 | */ |
||||
40 | protected $_imageIn; |
||||
41 | |||||
42 | /** |
||||
43 | * 输出图片对象 |
||||
44 | * |
||||
45 | * @var resource |
||||
46 | */ |
||||
47 | protected $_imageOut; |
||||
48 | |||||
49 | /** |
||||
50 | * 图片属性 |
||||
51 | * |
||||
52 | * @var array |
||||
53 | */ |
||||
54 | protected $_attributes = []; |
||||
55 | |||||
56 | /** |
||||
57 | * 解析图片属性 |
||||
58 | * |
||||
59 | * @param string $image 图片地址 |
||||
60 | * |
||||
61 | * @return array |
||||
62 | */ |
||||
63 | private function __parseImage($image) |
||||
64 | { |
||||
65 | $image = I::getAlias($image); |
||||
66 | C::assertTrue(is_array($size = @getimagesize($image)), '不是有效的图片:' . $image); |
||||
0 ignored issues
–
show
It seems like
$image can also be of type boolean ; however, parameter $filename of getimagesize() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
67 | // static::$_instance->_attributes['size'] = $size; |
||||
68 | $width = $size[0]; |
||||
69 | $height = $size[1]; |
||||
70 | $mime = $size['mime']; |
||||
71 | switch ($size[2]) { |
||||
72 | case 1: |
||||
73 | $ext = 'gif'; |
||||
74 | $object = imagecreatefromgif($image); |
||||
75 | $method = 'imagegif'; |
||||
76 | break; |
||||
77 | case 2: |
||||
78 | $ext = 'jpg'; |
||||
79 | $object = imagecreatefromjpeg($image); |
||||
80 | $method = 'imagejpeg'; |
||||
81 | break; |
||||
82 | case 3: |
||||
83 | $ext = 'png'; |
||||
84 | $object = imagecreatefrompng($image); |
||||
85 | $method = 'imagepng'; |
||||
86 | break; |
||||
87 | default: |
||||
88 | throw new Exception("不支持的图片类型"); |
||||
89 | } |
||||
90 | return [ |
||||
91 | 'file' => $image, |
||||
92 | 'width' => $width, |
||||
93 | 'height' => $height, |
||||
94 | 'mime' => $mime, |
||||
95 | 'ext' => $ext, |
||||
96 | 'object' => $object, |
||||
97 | 'method' => $method, |
||||
98 | ]; |
||||
99 | } |
||||
100 | |||||
101 | /** |
||||
102 | * 获取图片属性数组 |
||||
103 | * |
||||
104 | * @return array |
||||
105 | */ |
||||
106 | public function getAttributes() |
||||
107 | { |
||||
108 | return $this->_attributes; |
||||
109 | } |
||||
110 | |||||
111 | /** |
||||
112 | * 获取图片属性 |
||||
113 | * |
||||
114 | * @param string $name |
||||
115 | * |
||||
116 | * @return mixed |
||||
117 | */ |
||||
118 | public function getAttribute($name) |
||||
119 | { |
||||
120 | return I::get($this->_attributes, $name); |
||||
121 | } |
||||
122 | |||||
123 | /** |
||||
124 | * 设置透明度 |
||||
125 | * |
||||
126 | * @return void |
||||
127 | */ |
||||
128 | private function __setTransparency() |
||||
129 | { |
||||
130 | $index = imagecolortransparent($this->_imageIn); |
||||
131 | $color = ['red' => 255, 'green' => 255, 'blue' => 255]; |
||||
132 | if ($index >= 0) { |
||||
133 | $color = imagecolorsforindex($this->_imageIn, $index); |
||||
134 | } |
||||
135 | null === $this->_imageOut && $this->_imageOut = imagecreatetruecolor($this->_attributes['width'], $this->_attributes['height']); |
||||
0 ignored issues
–
show
It seems like
imagecreatetruecolor($th...>_attributes['height']) can also be of type GdImage . However, the property $_imageOut is declared as type resource . Maybe add an additional type check?
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly. For example, imagine you have a variable Either this assignment is in error or a type check should be added for that assignment. class Id
{
public $id;
public function __construct($id)
{
$this->id = $id;
}
}
class Account
{
/** @var Id $id */
public $id;
}
$account_id = false;
if (starsAreRight()) {
$account_id = new Id(42);
}
$account = new Account();
if ($account instanceof Id)
{
$account->id = $account_id;
}
![]() |
|||||
136 | $index = imagecolorallocate($this->_imageOut, $color['red'], $color['green'], $color['blue']); |
||||
137 | imagefill($this->_imageOut, 0, 0, $index); |
||||
138 | imagecolortransparent($this->_imageOut, $index); |
||||
139 | } |
||||
140 | |||||
141 | /** |
||||
142 | * 缩放图片 |
||||
143 | * |
||||
144 | * @param array|integer $zoom 数组或数字,如:数组[1, 0.5]表示宽不变,高变成一半,如果是整数,表示等比例缩放 |
||||
145 | * |
||||
146 | * @return static |
||||
147 | */ |
||||
148 | public function zoom($zoom = 1) |
||||
149 | { |
||||
150 | if (2 === Arrays::count($zoom)) { |
||||
151 | list($zoomWidth, $zoomHeight) = $zoom; |
||||
152 | $zoomWidth *= $this->_attributes['width']; |
||||
153 | $zoomHeight *= $this->_attributes['height']; |
||||
154 | } else { |
||||
155 | $zoom = (int) $zoom; |
||||
156 | $zoomWidth = $zoom * $this->_attributes['width']; |
||||
157 | $zoomHeight = $zoom * $this->_attributes['height']; |
||||
158 | } |
||||
159 | if ($this->_imageOut = imagecreatetruecolor($zoomWidth, $zoomHeight)) { |
||||
0 ignored issues
–
show
It seems like
imagecreatetruecolor($zoomWidth, $zoomHeight) can also be of type GdImage . However, the property $_imageOut is declared as type resource . Maybe add an additional type check?
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly. For example, imagine you have a variable Either this assignment is in error or a type check should be added for that assignment. class Id
{
public $id;
public function __construct($id)
{
$this->id = $id;
}
}
class Account
{
/** @var Id $id */
public $id;
}
$account_id = false;
if (starsAreRight()) {
$account_id = new Id(42);
}
$account = new Account();
if ($account instanceof Id)
{
$account->id = $account_id;
}
![]() |
|||||
160 | $this->__setTransparency(); |
||||
161 | imagecopyresampled($this->_imageOut, $this->_imageIn, 0, 0, 0, 0, $zoomWidth, $zoomHeight, $this->_attributes['width'], $this->_attributes['height']); |
||||
162 | } |
||||
163 | |||||
164 | return $this; |
||||
165 | } |
||||
166 | |||||
167 | /** |
||||
168 | * 裁剪 |
||||
169 | * |
||||
170 | * @param array $cut 裁剪的宽高,如:[100, 200] |
||||
171 | * @param array $pos 裁剪起始 x 和 y 坐标,坐标原点在左上角,如:[0, 0] |
||||
172 | * |
||||
173 | * @return static |
||||
174 | */ |
||||
175 | public function cut($cut = null, $pos = [0, 0]) |
||||
176 | { |
||||
177 | null === $cut && $cut = [$this->_attributes['width'], $this->_attributes['height']]; |
||||
178 | $width = min($this->_attributes['width'], $cut[0]); |
||||
179 | $height = min($this->_attributes['height'], $cut[1]); |
||||
180 | $x = min($this->_attributes['width'], $pos[0]); |
||||
181 | $y = min($this->_attributes['height'], $pos[1]); |
||||
182 | if ($this->_imageOut = imagecreatetruecolor($width, $height)) { |
||||
0 ignored issues
–
show
It seems like
imagecreatetruecolor($width, $height) can also be of type GdImage . However, the property $_imageOut is declared as type resource . Maybe add an additional type check?
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly. For example, imagine you have a variable Either this assignment is in error or a type check should be added for that assignment. class Id
{
public $id;
public function __construct($id)
{
$this->id = $id;
}
}
class Account
{
/** @var Id $id */
public $id;
}
$account_id = false;
if (starsAreRight()) {
$account_id = new Id(42);
}
$account = new Account();
if ($account instanceof Id)
{
$account->id = $account_id;
}
![]() |
|||||
183 | $this->__setTransparency(); |
||||
184 | imagecopy($this->_imageOut, $this->_imageIn, 0, 0, $x, $y, $this->_attributes['width'], $this->_attributes['height']); |
||||
185 | } |
||||
186 | |||||
187 | return $this; |
||||
188 | } |
||||
189 | |||||
190 | /** |
||||
191 | * 创建文字水印 |
||||
192 | * |
||||
193 | * @param string $text 文字水印内容 |
||||
194 | * @param array $pos 水印位置,默认在左上角的坐标原点 |
||||
195 | * @param mixed $fontColor 颜色值,支持类型参见 Color |
||||
196 | * @param int $fontSize 字体大小,默认 12 |
||||
197 | * @param string $fontPath 字体路径,默认宋体 |
||||
198 | * |
||||
199 | * @return static |
||||
200 | */ |
||||
201 | public function markText($text, $pos = [0, 0], $fontColor = 'black', $fontSize = 12, $fontPath = 'simkai') |
||||
202 | { |
||||
203 | if ($this->_imageOut = imagecreatetruecolor($this->_attributes['width'], $this->_attributes['height'])) { |
||||
0 ignored issues
–
show
It seems like
imagecreatetruecolor($th...>_attributes['height']) can also be of type GdImage . However, the property $_imageOut is declared as type resource . Maybe add an additional type check?
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly. For example, imagine you have a variable Either this assignment is in error or a type check should be added for that assignment. class Id
{
public $id;
public function __construct($id)
{
$this->id = $id;
}
}
class Account
{
/** @var Id $id */
public $id;
}
$account_id = false;
if (starsAreRight()) {
$account_id = new Id(42);
}
$account = new Account();
if ($account instanceof Id)
{
$account->id = $account_id;
}
![]() |
|||||
204 | $this->__setTransparency(); |
||||
205 | $text = Charset::toUtf($text); |
||||
206 | $temp = imagettfbbox($fontSize, 0, $fontPath, $text); |
||||
207 | $textWidth = $temp[2] - $temp[6]; |
||||
208 | // $textHeight = $temp[3] - $temp[7]; |
||||
209 | imagesettile($this->_imageOut, $this->_imageIn); |
||||
210 | imagefilledrectangle($this->_imageOut, 0, 0, $this->_attributes['width'], $this->_attributes['height'], IMG_COLOR_TILED); |
||||
211 | list($red, $green, $blue) = (new Color($fontColor))->toRGB()->get(); |
||||
212 | $text2 = imagecolorallocate($this->_imageOut, $red, $green, $blue); |
||||
213 | $posX = min($pos[0], $this->_attributes['width'] - $textWidth); |
||||
214 | $posY = min($pos[1], $this->_attributes['height']); |
||||
215 | imagettftext($this->_imageOut, $fontSize, 0, $posX, $posY, $text2, $fontPath, $text); |
||||
216 | } |
||||
217 | |||||
218 | return $this; |
||||
219 | } |
||||
220 | |||||
221 | /** |
||||
222 | * 创建图片水印 |
||||
223 | * |
||||
224 | * @param string $image 图片水印的地址 |
||||
225 | * @param array $pos 水印位置,默认在左上角的坐标原点 |
||||
226 | * @param array $size 图片水印大小,如果不给则是默认大小 |
||||
227 | * |
||||
228 | * @return static |
||||
229 | */ |
||||
230 | public function markPicture($image, $pos = [0, 0], $size = null) |
||||
231 | { |
||||
232 | if ($this->_imageOut = imagecreatetruecolor($this->_attributes['width'], $this->_attributes['height'])) { |
||||
0 ignored issues
–
show
It seems like
imagecreatetruecolor($th...>_attributes['height']) can also be of type GdImage . However, the property $_imageOut is declared as type resource . Maybe add an additional type check?
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly. For example, imagine you have a variable Either this assignment is in error or a type check should be added for that assignment. class Id
{
public $id;
public function __construct($id)
{
$this->id = $id;
}
}
class Account
{
/** @var Id $id */
public $id;
}
$account_id = false;
if (starsAreRight()) {
$account_id = new Id(42);
}
$account = new Account();
if ($account instanceof Id)
{
$account->id = $account_id;
}
![]() |
|||||
233 | $this->__setTransparency(); |
||||
234 | $markAttrs = $this->__parseImage($image); |
||||
235 | null === $size && $size = [$markAttrs['width'], $markAttrs['height']]; |
||||
236 | imagecopy($this->_imageOut, $this->_imageIn, 0, 0, 0, 0, $this->_attributes['width'], $this->_attributes['height']); |
||||
237 | $posX = min($pos[0], $this->_attributes['width'] - $size[0]); |
||||
238 | $posY = min($pos[1], $this->_attributes['height'] - $size[1]); |
||||
239 | imagecopyresized($this->_imageOut, /** @scrutinizer ignore-type */$markAttrs['object'], $posX, $posY, 0, 0, $size[0], $size[1], $markAttrs['width'], $markAttrs['height']); |
||||
240 | imagedestroy(/** @scrutinizer ignore-type */$markAttrs['object']); |
||||
241 | } |
||||
242 | |||||
243 | return $this; |
||||
244 | } |
||||
245 | |||||
246 | /** |
||||
247 | * 沿着 Y 轴翻转 |
||||
248 | * |
||||
249 | * @return static |
||||
250 | */ |
||||
251 | public function turnY() |
||||
252 | { |
||||
253 | if ($this->_imageOut = imagecreatetruecolor($this->_attributes['width'], $this->_attributes['height'])) { |
||||
0 ignored issues
–
show
It seems like
imagecreatetruecolor($th...>_attributes['height']) can also be of type GdImage . However, the property $_imageOut is declared as type resource . Maybe add an additional type check?
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly. For example, imagine you have a variable Either this assignment is in error or a type check should be added for that assignment. class Id
{
public $id;
public function __construct($id)
{
$this->id = $id;
}
}
class Account
{
/** @var Id $id */
public $id;
}
$account_id = false;
if (starsAreRight()) {
$account_id = new Id(42);
}
$account = new Account();
if ($account instanceof Id)
{
$account->id = $account_id;
}
![]() |
|||||
254 | for ($x = 0; $x < $this->_attributes['width']; $x++) { |
||||
255 | imagecopy($this->_imageOut, $this->_imageIn, $this->_attributes['width'] - $x - 1, 0, $x, 0, 1, $this->_attributes['height']); |
||||
256 | } |
||||
257 | } |
||||
258 | |||||
259 | return $this; |
||||
260 | } |
||||
261 | |||||
262 | /** |
||||
263 | * 沿着 X 轴翻转 |
||||
264 | * |
||||
265 | * @return static |
||||
266 | */ |
||||
267 | public function turnX() |
||||
268 | { |
||||
269 | if ($this->_imageOut = imagecreatetruecolor($this->_attributes['width'], $this->_attributes['height'])) { |
||||
0 ignored issues
–
show
It seems like
imagecreatetruecolor($th...>_attributes['height']) can also be of type GdImage . However, the property $_imageOut is declared as type resource . Maybe add an additional type check?
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly. For example, imagine you have a variable Either this assignment is in error or a type check should be added for that assignment. class Id
{
public $id;
public function __construct($id)
{
$this->id = $id;
}
}
class Account
{
/** @var Id $id */
public $id;
}
$account_id = false;
if (starsAreRight()) {
$account_id = new Id(42);
}
$account = new Account();
if ($account instanceof Id)
{
$account->id = $account_id;
}
![]() |
|||||
270 | for ($y = 0; $y < $this->_attributes['height']; $y++) { |
||||
271 | imagecopy($this->_imageOut, $this->_imageIn, 0, $this->_attributes['height'] - $y - 1, 0, $y, $this->_attributes['width'], 1); |
||||
272 | } |
||||
273 | } |
||||
274 | |||||
275 | return $this; |
||||
276 | } |
||||
277 | |||||
278 | /** |
||||
279 | * 逆时针旋转图片 |
||||
280 | * |
||||
281 | * @param integer $degrees 角度 |
||||
282 | * |
||||
283 | * @return static |
||||
284 | */ |
||||
285 | public function rotate($degrees = -90) |
||||
286 | { |
||||
287 | $this->_imageOut = imagerotate($this->_attributes['object'], $degrees, 0); |
||||
0 ignored issues
–
show
It seems like
imagerotate($this->_attr...'object'], $degrees, 0) can also be of type GdImage . However, the property $_imageOut is declared as type resource . Maybe add an additional type check?
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly. For example, imagine you have a variable Either this assignment is in error or a type check should be added for that assignment. class Id
{
public $id;
public function __construct($id)
{
$this->id = $id;
}
}
class Account
{
/** @var Id $id */
public $id;
}
$account_id = false;
if (starsAreRight()) {
$account_id = new Id(42);
}
$account = new Account();
if ($account instanceof Id)
{
$account->id = $account_id;
}
![]() |
|||||
288 | $this->__setTransparency(); |
||||
289 | |||||
290 | return $this; |
||||
291 | } |
||||
292 | |||||
293 | /** |
||||
294 | * 获取 (x, y) 坐标处的颜色值 |
||||
295 | * |
||||
296 | * @param integer $x |
||||
297 | * @param integer $y |
||||
298 | * |
||||
299 | * @return \icy2003\php\ihelpers\Color Color 类对象 |
||||
300 | */ |
||||
301 | public function getColor($x, $y) |
||||
302 | { |
||||
303 | $rgb = imagecolorat($this->_attributes['object'], $x, $y); |
||||
304 | return new Color([($rgb >> 16) & 0xFF, ($rgb >> 8) & 0xFF, $rgb & 0xFF], Color::TYPE_RGB); |
||||
305 | } |
||||
306 | |||||
307 | /** |
||||
308 | * 保存图片到某个路径下,文件名自动生成 |
||||
309 | * |
||||
310 | * @param string $path 目标路径 |
||||
311 | * |
||||
312 | * @return void |
||||
313 | */ |
||||
314 | public function saveTo($path = './') |
||||
315 | { |
||||
316 | $this->save($path . date('YmdHis') . '.' . $this->_attributes['ext']); |
||||
317 | } |
||||
318 | |||||
319 | /** |
||||
320 | * 保存到文件,如果不给文件名,则保存回原文件 |
||||
321 | * |
||||
322 | * @return void |
||||
323 | */ |
||||
324 | public function save($file = null) |
||||
325 | { |
||||
326 | null === $file && $file = $this->_attributes['file']; |
||||
327 | $this->_attributes['out'] = $file; |
||||
328 | $method = $this->_attributes['method']; |
||||
329 | $method($this->_imageOut, $this->_attributes['out']); |
||||
330 | } |
||||
331 | |||||
332 | /** |
||||
333 | * 显示图片到浏览器 |
||||
334 | * |
||||
335 | * @return void |
||||
336 | */ |
||||
337 | public function show() |
||||
338 | { |
||||
339 | header('Content-type:' . $this->_attributes['mime']); |
||||
340 | $method = $this->_attributes['method']; |
||||
341 | null === $this->_imageOut && $this->_imageOut = $this->_imageIn; |
||||
342 | $method($this->_imageOut); |
||||
343 | } |
||||
344 | |||||
345 | /** |
||||
346 | * 释放图片资源 |
||||
347 | * |
||||
348 | * @return void |
||||
349 | */ |
||||
350 | public function destroy() |
||||
351 | { |
||||
352 | is_resource($this->_imageIn) && imagedestroy($this->_imageIn); |
||||
353 | is_resource($this->_imageOut) && imagedestroy($this->_imageOut); |
||||
354 | } |
||||
355 | |||||
356 | /** |
||||
357 | * 生成验证码 |
||||
358 | * |
||||
359 | * @todo 智能处理文字和图片间距大小等 |
||||
360 | * |
||||
361 | * @param string $code 验证码 |
||||
362 | * @param array $size 验证码图片宽高,默认 80*30 |
||||
363 | * @param int $fontSize 字体大小,默认 14 |
||||
364 | * @param string $fontPath 字体路径,默认宋体 |
||||
365 | * @param int $pixelNum 杂点数量,默认 2 |
||||
366 | * @param int $pixelColor 杂点颜色数量,默认 5 |
||||
367 | * @param int $padding 文字左右间距 |
||||
368 | * @param int $margin 文字左边距 |
||||
369 | * @param int $base 文字上边距 |
||||
370 | * @param int $baseOffset 文字抖动偏差 |
||||
371 | * |
||||
372 | * @return void |
||||
373 | */ |
||||
374 | public static function captcha($code, $size = [80, 30], $fontSize = 14, $fontPath = 'simkai', $pixelNum = 2, $pixelColor = 5, $padding = 8, $margin = 7, $base = 20, $baseOffset = 4) |
||||
375 | { |
||||
376 | header("Cache-Control: no-cache, must-revalidate"); |
||||
377 | header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); |
||||
378 | header("Pragma: no-cache"); |
||||
379 | header("Cache-control: private"); |
||||
380 | header('Content-Type: image/png'); |
||||
381 | $codeLength = Strings::length($code); |
||||
382 | if ($image = imagecreatetruecolor($size[0], $size[1])) { |
||||
383 | imagefilledrectangle($image, 0, 0, $size[0] - 1, $size[1] - 1, imagecolorallocate($image, mt_rand(235, 255), mt_rand(235, 255), mt_rand(235, 255))); |
||||
384 | for ($i = 0; $i < $pixelColor; $i++) { |
||||
385 | $noiseColor = imagecolorallocate($image, mt_rand(150, 225), mt_rand(150, 225), mt_rand(150, 225)); |
||||
386 | for ($j = 0; $j < $pixelNum; $j++) { |
||||
387 | imagestring($image, 1, mt_rand(-10, $size[0]), mt_rand(-10, $size[1]), Strings::random(1), $noiseColor); |
||||
388 | } |
||||
389 | } |
||||
390 | $codeArray = Strings::split($code); |
||||
391 | for ($i = 0; $i < $codeLength; ++$i) { |
||||
392 | $color = imagecolorallocate($image, mt_rand(0, 100), mt_rand(20, 120), mt_rand(50, 150)); |
||||
393 | imagettftext($image, $fontSize, mt_rand(-10, 10), $margin, mt_rand($base - $baseOffset, $base + $baseOffset), $color, $fontPath, $codeArray[$i]); |
||||
394 | $margin += (imagefontwidth($fontSize) + $padding); |
||||
395 | } |
||||
396 | imagepng($image); |
||||
397 | imagedestroy($image); |
||||
398 | } |
||||
399 | } |
||||
400 | |||||
401 | /** |
||||
402 | * 猫咪图片 |
||||
403 | */ |
||||
404 | const RESOURCE_CAT = 'http://placekitten.com'; |
||||
405 | |||||
406 | /** |
||||
407 | * 图片 |
||||
408 | */ |
||||
409 | const RESOURCE_DEFAULT = 'https://picsum.photos'; |
||||
410 | |||||
411 | /** |
||||
412 | * 文字图片 |
||||
413 | */ |
||||
414 | const RESOURCE_PLAINTEXT = 'https://fakeimg.pl'; |
||||
415 | |||||
416 | /** |
||||
417 | * 生成随机图片并返回图片路径 |
||||
418 | * |
||||
419 | * @param string $dir 目标目录 |
||||
420 | * @param array $options 选项 |
||||
421 | * - width:图片宽,默认 120 |
||||
422 | * - height:图片高,默认 120 |
||||
423 | * - resource:图片服务 |
||||
424 | * -- self::RESOURCE_DEFAULT 默认 |
||||
425 | * -- self::RESOURCE_PLAINTEXT 纯文字:text 文字内容 |
||||
426 | * -- self::RESOURCE_CAT 猫咪 |
||||
427 | * |
||||
428 | * @return string |
||||
429 | */ |
||||
430 | public static function randomTo($dir, $options = []) |
||||
431 | { |
||||
432 | $options['resource'] = I::get($options, 'resource', self::RESOURCE_DEFAULT); |
||||
433 | $options['width'] = I::get($options, 'width', 120); |
||||
434 | $options['height'] = I::get($options, 'height', 120); |
||||
435 | $url = $options['resource']; |
||||
436 | if (self::RESOURCE_PLAINTEXT === $options['resource']) { |
||||
437 | $url .= '/' . $options['width'] . 'x' . $options['height']; |
||||
438 | $url .= '/?text=' . I::get($options, 'text'); |
||||
439 | $url .= '&font=noto'; |
||||
440 | } else if (self::RESOURCE_DEFAULT === $options['resource']) { |
||||
441 | $url .= '/' . $options['width'] . '/' . $options['height']; |
||||
442 | $query = []; |
||||
443 | if (isset($options['grayscale'])) { |
||||
444 | $query['grayscale'] = 1; |
||||
445 | } |
||||
446 | if (isset($options['blur'])) { |
||||
447 | $query['blur'] = 1; |
||||
448 | } |
||||
449 | if (isset($options['random'])) { |
||||
450 | $query['random'] = 1; |
||||
451 | } |
||||
452 | } else { |
||||
453 | $url .= '/' . $options['width'] . '/' . $options['height']; |
||||
454 | } |
||||
455 | $fileName = $dir . '/' . md5(microtime(true)) . '.png'; |
||||
456 | (new LocalFile())->downloadFile([$url, $fileName]); |
||||
457 | return $fileName; |
||||
458 | } |
||||
459 | |||||
460 | /** |
||||
461 | * 释放输入输出图片 |
||||
462 | */ |
||||
463 | public function __destruct() |
||||
464 | { |
||||
465 | $this->destroy(); |
||||
466 | } |
||||
467 | } |
||||
468 |
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.
For example, imagine you have a variable
$accountId
that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to theid
property of an instance of theAccount
class. This class holds a proper account, so the id value must no longer be false.Either this assignment is in error or a type check should be added for that assignment.