1 <?php
2
3 4 5 6 7 8 9 10 11 12
13
14 namespace Slimore\Captcha;
15
16 17 18 19 20 21 22 23
24
25 class Builder
26 {
27 28 29
30 private $imageTypes = ['png', 'jpeg', 'gif'];
31
32 33 34
35 public $imageType = 'png';
36
37 38 39
40 public $width = 120;
41
42 43 44
45 public $height = 40;
46
47 48 49
50 public $lines = 6;
51
52 53 54
55 public $backgroundColor = [255, 255, 255];
56
57 58 59
60 public $borderWidth = 1;
61
62 63 64
65 public $length = 5;
66
67 68 69
70 public $numbers = '0123456789';
71
72 73 74
75 public $letters = [
76 '123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ',
77 'ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789',
78 '123456789abcdefghijkmnopqrstuvwxyz'
79 ];
80
81 82 83
84 public $pureLetters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';
85
86 87 88 89 90 91 92 93 94
95 public $randomType = 1;
96
97 98 99
100 public $chineseCharacters = '民谣歌手周云蓬今年四月发行新专辑四月旧州其中专辑主打曲目镜中提前首发这首改编自张枣著名诗歌的单曲一经发布就引发了热烈的反响得到了圈内圈外的一致好评更引发了新一轮文艺界的诗歌复兴镜中周云蓬词周云蓬改编自张枣同名诗歌曲周云蓬我在镜中等你归来坐在镜中望窗外想起一生后悔的事情梅花就会落下来我在镜中等你归来坐在镜中看云天想起一生后悔的事情梅花就会落满南山镜子照镜子很多的镜子所有镜中都要有你一个小影子一个老影子抱着睡进黑暗里九月周云蓬目击众神死亡的草原上野花一片远在远方的风比远方更远我的琴声呜咽我的泪水全无我把远方的远归还草原一个叫木头一个叫马尾一个叫木头一个叫马尾目击众神死亡的草原上野花一片远在远方的风比远方更远我的琴声呜咽我的泪水全无我把远方的远归还草原一个叫木头一个叫马尾一个叫木头一个叫马尾一个叫木头一个叫马尾一个叫木头一个叫马尾亡我祁连山使我牛羊不蕃息失我胭脂山令我妇女无颜色远方只有在死亡中凝聚野花一片明月如镜高悬在草原映照千年的岁月我的琴声呜咽我的泪水全无只身打马过草原一个叫木头一个叫马尾一个叫木头一个叫马尾一个叫木头一个叫马尾一个叫木头一个叫马尾一个叫木头一个叫马尾一个叫木头一个叫马尾一个叫木头一个叫马尾今生今世遥不可及李健多想拥你在我的怀里却无法超越那距离美好回忆渐渐地远去盼望今生出现奇迹无尽的想念荒了容颜无助的爱恋从未改变喔喔喔啦愿有情人终成眷属李健八月照相馆风吹过照相馆的橱窗窗外溜走的时光当我路过这个地方仿佛就像回到昨天一样你幸福地靠我的肩说就这样过生命里的每一天嗯那一个夏天在心底深藏偶尔荡漾嗯渐渐泛黄的相片带我回到那某一年的某一天光闪过你笑着的脸庞永远装进了相框这首歌让我回望那年八月我们傻傻的模样当捧着那些旧照片燃起戒掉的烟悄悄的湿了眼嗯那么一瞬间留下来的笑已成永远当爱消失在时间里面相片永远把你留在我的身边啊似水流年偶尔在镜子里面旧时光和我相遇那片远远的天空炉火映红的暖冬大雁飞过秋天的海面看着奔跑的童年赤着脚的快乐只不过是仓惶的一转眼她手中的口琴唱的歌唤醒贪玩的耳朵爱是手中捧的红苹果那年夏天她微笑着不说让我这一夜长醉流年似水的滋味笑中青涩的眼泪那时光渐渐沉睡记忆中曾飘动的烛光今夜又照亮远方这不经意之间的回望让目光走过那扇窗生命的河从身旁流过将回忆慢慢淹没那年春天燃起的篝火多年以后泛着泪光闪烁我愿这一夜长醉流年似水的滋味旅行词曲许巍阵阵晚风吹动着松涛吹响这风铃声如天籁站在这城市的寂静处让一切喧嚣走远只有青山藏在白云间蝴蝶穿行自由在清涧看那晚霞盛开在天边有一群向西归鸟谁画出这天地又画下我和你让我们的世界绚丽多彩谁让我们哭泣又给我们惊喜让我们就这样相爱相遇总是要说再见相聚又分离总是走在漫长的路上啦谁画出这天地又画下我和你让我们的世界绚丽多彩谁让我们哭泣又给我们惊喜让我们就这样相爱相遇总是要说再见相聚又分离总是走在漫长的路上总是走在漫长的路上陀螺李健词曲万晓利在田野上转在清风里转在飘着香的鲜花上转在沉默里转在孤独里转在结着冰的湖面上转在欢笑里转在泪水里转在燃烧着的生命里转在洁白里转在血红里转在你已衰老的容颜里转如果我可以停下来我想把眼睛睁开看着你怎么离开可是我不能停下来也无法为你喝彩请你把双手松开在酒杯里转在噩梦里转在深不见底的黑暗里转在欲望里转在挣扎里转在任由天命的麻木里转在阳光灿烂的一天你用手捂着你的脸对我说你很疲倦你扔下手中的道具开始咒骂这场游戏说你一直想放弃但不能停止转转转转转高高地举起你的鞭转转转转转转转转轻轻地闭上我的眼啦啦啦春水初生春林初盛春风十里不如你生命如河流李健生命像条河我顺流而下湍急或平缓随着它我一路奔忙穿越了冬夏难过或欢乐却从容不下虚假忽明忽暗的风景起起落落的心情这一切像浪花蜕成涟漪无论现实多坚硬柔软如初的心灵忘不了为爱感伤的夜里但终究未曾对真爱怀疑我也会想起那动听的话如今不计较是真假我几经辗转才遇见了他他让我看到生命绚烂的云霞生命像条河我顺流而下湍急或平缓随着它学问越渊博的人越谦卑才疏学浅的人往往声色俱厉歌手李健意林假如爱有天意李健坦言有时候爱情和理想一样都很美好但都难以实现尘缘人间有我残梦未醒漫漫长路起伏不能由我任多少深情独向寂寞人随风过自在花开花又落我始终爱你李健因为你我尝过甜蜜忘记你却谈何容易这么多年沧海桑田我情深却无怨再见你你依然美丽望着你我默默无语又想问候又怕心痛让岁月为我说你知不知道我始终爱你我只是没有告诉你让相思烈火熊熊烧着我也不愿让你受委屈你知不知道我始终爱你却只能远远看着你春去秋来谁会明了我认真的感情在梦里我也曾哭泣在风里我不断寻觅情愿寂寞不愿割舍这一生为你过你知不知道我始终爱你我只是没有告诉你让相思烈火熊熊烧着我也不愿让你受委屈你知不知道我始终爱你却只能远远看着你春去秋来盼你明了我认真的感情你知不知道我始终爱你我只是没有告诉你春去秋来你会明了我认真的感情春去秋来你会明了我始终爱你为你而来李健词曲李健编曲刘卓不停地追赶理想忽隐又忽现为生活来不及疲倦阳光下世界多鲜艳怎么能视而不见我是为你而来不在乎穿越绵绵山脉你给我的最爱永远在盛开是我一生的精彩啦不停地驱赶来去无常的孤单也茫然还好有勇敢看星空梦幻般流转怎么能袖手旁观我是为你而来不在乎穿越绵绵山脉你给我的最爱永远在盛开是我一生的精彩中学时代水木年华词卢庚戌曲李健穿过运动场让雨淋湿我羞涩的你何时变孤寂躲在墙角里偷偷的哭泣我忧郁的你有谁会懂你爱是什么我不知道我不懂永远我不懂自己爱是什么我还不知道谁能懂永远谁能懂自己穿过运动场让雨淋湿我羞涩的你何时变孤寂躲在墙角里偷偷的哭泣我忧郁的你不许谁懂你爱是什么我不知道我不懂永远我不懂自己爱是什么我还不知道谁能懂永远谁能懂自己把百合日记藏在书包我纯真的你我生命中的唯一绽放李健词左右曲李健紫色的火穿越夜的云朵流星一样飞过雨的线索繁花碎落打开平静湖泊鱼鹰一样急迫远去的我另一边世界的光亮在这片水面下摇晃每一颗水珠已绽放在生命最美的地方在生命最美的地方每一颗水珠已绽放在这片水面下摇晃另一边世界的光亮远去的我鱼鹰一样急迫打开平静湖泊繁花碎落雨的线索流星一样飞过穿越夜的云朵紫色的火花碎落平静湖泊夜的云朵远去的我向往李健词曲李健我知道并不是所有鸟儿都飞翔当夏天过去后还有鲜花未曾开放我害怕看到你独自一人绝望更害怕看不到你不能和你一起迷惘多想你在我身旁看命运变幻无常体会这默默忍耐的力量当春风掠过山岗依然能感觉寒冷却无法阻挡对温暖的向往啊我知道并不是耕耘就有收获当泪水流干后生命还是那么脆弱多残忍你和我就像流星划落多绚烂飞驰而过点亮黑夜最美烟火多想你在我身旁看命运变幻无常体会这默默忍耐的力量当春风掠过山岗依然能感觉寒冷却无法阻挡对温暖的向往向往向往多想你在我身旁看命运变幻无常体会这默默忍耐的力量当春风掠过山岗依然能感觉寒冷却无法阻挡对温暖的向往多想你在我身旁看命运变幻无常体会这默默忍耐的力量当春风掠过山岗依然能感觉寒冷又怎能停止对温暖的向往向往';
101
102 103 104
105 public $drawBorder = false;
106
107 108 109
110 public $drawLine = true;
111
112 113 114
115 public $drawPixel = true;
116
117 118 119
120 public $fontSize = 16;
121
122 123 124
125 public $fontFile = null;
126
127 128 129
130 private $image;
131
132 133 134
135 private $code;
136
137 138 139
140 public function __construct()
141 {
142 }
143
144 145 146 147 148
149
150 public function getImageType()
151 {
152 $this->imageType = ($this->imageType === 'jpg') ? 'jpeg' : $this->imageType;
153 $this->imageType = ( in_array($this->imageType, $this->imageTypes) ) ? $this->imageType : 'png';
154
155 return $this->imageType;
156 }
157
158 159 160 161 162 163
164
165 public function getCode($uppercase = true)
166 {
167 return ($uppercase) ? strtoupper($this->code) : $this->code;
168 }
169
170 171 172 173 174 175 176
177
178 public function create($width = null, $height = null)
179 {
180 $this->width = ($width) ? $width : $this->width;
181 $this->height = ($height) ? $height : $this->height;
182
183 $imageType = $this->getImageType();
184 $createFunc = ($imageType === 'gif') ? 'imagecreate' : 'imagecreatetruecolor';
185 $this->image = $createFunc($this->width, $this->height);
186
187 $bgColor = $this->backgroundColor;
188
189 $backgroundColor = imagecolorallocate($this->image, $bgColor[0], $bgColor[1], $bgColor[2]);
190
191 imagefilledrectangle($this->image, 0, 0, $this->width, $this->height, $backgroundColor);
192
193 $this->drawText();
194
195 if ($this->drawBorder)
196 {
197 $this->drawBorder();
198 }
199
200 if ($this->drawLine)
201 {
202 $this->drawLine();
203 }
204
205 if ($this->drawPixel)
206 {
207 $this->drawPixel();
208 }
209
210 return $this;
211 }
212
213 214 215 216 217
218
219 protected function randomNumbers()
220 {
221 $this->code = substr(str_shuffle($this->numbers), 0, $this->length);
222 }
223
224 225 226 227 228
229
230 protected function randomPureLetters()
231 {
232 $this->code = substr(str_shuffle($this->pureLetters), 0, $this->length);
233 }
234
235 236 237 238 239
240
241 protected function randomLetters()
242 {
243 for ($i = 0; $i < $this->length; $i++)
244 {
245 $letters = $this->letters[mt_rand(0, count($this->letters) - 1)];
246 $this->code .= $letters[mt_rand(0, strlen($letters) - 1)];
247 }
248 }
249
250 251 252 253 254
255
256 protected function randomChinese()
257 {
258 if ( function_exists('mb_substr') )
259 {
260 $len = mb_strlen($this->chineseCharacters, 'utf-8');
261
262 for ($i = 0; $i < $this->length; $i++)
263 {
264 $this->code .= mb_substr($this->chineseCharacters, mt_rand(0, $len - 1), 1, 'utf-8');
265 }
266 }
267 }
268
269 270 271 272 273
274
275 protected function randomMixed()
276 {
277 $characters = implode('', $this->letters) . $this->chineseCharacters;
278
279 if (function_exists('mb_substr'))
280 {
281 $len = mb_strlen($characters, 'utf-8');
282
283 for ($i = 0; $i < $this->length; $i++)
284 {
285 $this->code .= mb_substr($characters, mt_rand(0, $len - 1), 1, 'utf-8');
286 }
287 }
288 }
289
290 291 292 293 294
295
296 protected function drawText()
297 {
298 299 300 301 302 303 304
305
306 switch($this->randomType)
307 {
308 case 0:
309 $this->randomNumbers();
310 break;
311
312 case 1:
313 $this->randomPureLetters();
314 break;
315
316 case 3:
317 $this->randomChinese();
318 break;
319
320 case 4:
321 $this->randomMixed();
322 break;
323
324 case 2:
325 default:
326 $this->randomLetters();
327 break;
328 }
329
330 if (!$this->fontFile)
331 {
332 $this->fontFile = __DIR__ . '../../Fonts/verdana.ttf';
333 }
334
335 if (!file_exists($this->fontFile))
336 {
337 throw new \InvalidArgumentException('Font file ' . $this->fontFile . ' not found.');
338 }
339
340 $textColor = imagecolorallocate($this->image, mt_rand(0, 255), mt_rand(0, 255), mt_rand(0, 255));
341
342 $x = ($this->width - ($this->fontSize * $this->length)) / 2;
343 $y = $this->fontSize + ($this->height - $this->fontSize) / 2;
344 $fontFile = (is_array($this->fontFile)) ? $this->fontFile[array_rand($this->fontFile)] : $this->fontFile;
345
346 imagettftext($this->image, $this->fontSize , mt_rand(-8, 8), $x, $y, $textColor, $fontFile, $this->code);
347 }
348
349 350 351 352 353
354
355 protected function drawBorder()
356 {
357 $borderColor = imagecolorallocate($this->image, 0, 0, mt_rand(50, 255));
358
359 imagerectangle($this->image, 0, 0, $this->width - $this->borderWidth, $this->height - $this->borderWidth, $borderColor);
360 }
361
362 363 364 365 366
367
368 protected function drawLine()
369 {
370 $lineColor = imagecolorallocate($this->image, mt_rand(50, 255), mt_rand(100, 255), mt_rand(0, 255));
371
372 for($i = 0; $i < $this->lines; $i++)
373 {
374 imageline($this->image, 0, mt_rand() % $this->height, $this->width, mt_rand() % $this->height, $lineColor);
375 }
376 }
377
378 379 380 381 382
383
384 protected function drawPixel()
385 {
386 $pixelColor = imagecolorallocate($this->image, mt_rand(0, 255), mt_rand(100, 255), mt_rand(50, 255));
387
388 for($i = 0; $i< mt_rand(1000, 1800); $i++)
389 {
390 imagesetpixel($this->image, mt_rand() % $this->width, mt_rand() % $this->height, $pixelColor);
391 }
392 }
393
394 395 396 397 398
399
400 public function display()
401 {
402 $imageType = $this->getImageType();
403
404 header('Content-type: image/' . $imageType);
405
406 $imageFunc = 'image' . $imageType;
407 $imageFunc($this->image);
408
409 $this->destroy($this->image);
410
411 return $this;
412 }
413
414 415 416 417 418 419
420
421 public function save($filename)
422 {
423 $type = pathinfo($filename, PATHINFO_EXTENSION);
424 $type = ($type === 'jpg') ? 'jpeg' : $type;
425 $type = (in_array($type, $this->imageTypes)) ? $type : 'png';
426
427 header('Content-type: image/' . $type);
428
429 $imageFunc = 'image' . $type;
430 $imageFunc($this->image, $filename);
431
432 $this->destroy($this->image);
433
434 return $this;
435 }
436
437 438 439 440 441
442 protected function destroy($image)
443 {
444 if (is_resource($image))
445 {
446 imagedestroy($image);
447 }
448 }
449 }