# 筆記_工作_圖形驗證碼 --- ###### tags: `Captcha` `PHP` `驗證碼` 筆記內成就皆不來自我 --- [Mac缺少freetype解决方案](https://blog.si-yee.com/2019/03/19/Mac%E7%BC%BA%E5%B0%91freetype%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/) [php 安装 freetype 支持](https://blog.csdn.net/coolpan123/article/details/79893668) MacOS上無法直接使用freetype擴展庫 [Tutorial on creating image captcha in PHP using GD library](https://perials.com/tutorial-creating-image-captcha-php-using-gd-library/) 帶你一步步看GD怎麼產生驗證碼的 --- 圖形驗證,就是使用PHP語言將文本(腳本)轉成圖片輸出 而基本上很多語言都有相對應的方法 PHP種可以分成大致兩種來做出文本輸出圖像方法 原理是一樣的 只是一個有使用外部文字的字體引擎 一個沒有但都是使用GD庫 目錄 - GD庫 - 什麼是GD庫 - GD庫使用 - Freetype - 不需Freetype驗證碼 - GD教學 ## GD庫 --- ## 什麼是GD庫 引用: PHP 在 Web 开发领域被广泛应用的原因在于,PHP 不仅可以生成 HTML 页面,还可以创建和操作二进制形式的数据,例如图像、文件等等。其中,使用 **PHP 处理图像就需要 GD 库的支持** 本节我们就来介绍一下 GD 库,以及如何启用 GD 库。 1. ***GD库是什么*** GD 库(也可以称为 GD2 函数库)是一个开源的用于创建图形图像的函数库,该函数库由C语言编写,可以在 Perl,PHP 等多种语言中使用。GD 库中提供了一系列用来处理图片的 API(接口),使用 GD 库可以处理图片、生成图片,也可以给图片加水印等。 另外,很多开源项目都对 GD 库提供了很好的技术支持,如 Jpgraph 类库就是基于 GD 库开发的用于制作复杂统计图的类库。 2. ***使用GD库可以做什么*** 在 PHP 中使用 GD 库可以在页面中绘制各种图形图像,以及统计图,如果与 Ajax 技术相结合还可以制作出各种强大的动态图表。还有就是在网站登陆页面中使用的验证码,也可以使用 GD 库来实现。 需要注意的是,GD 库开始时是支持 GIF 格式的,但由于 GIF 使用了有版权争议的 LZW 算法,会引起法律问题,于是从 GD 库 1.6 版起所有的 GIF 支持都移除了,但是又在 GD 库 2.0.28 版起又加了回来。如果使用了二者之间版本的 GD 库时,有关 GIF 相关函数是不可用。 ![](https://i.imgur.com/dbr0Rvs.png) ![](https://i.imgur.com/8ceYp3a.png) ![](https://i.imgur.com/Tj1sEjf.png) [C语言中文网](http://c.biancheng.net/view/7938.html) --- ## GD庫使用 [GD 和图像处理 函数](https://www.php.net/manual/zh/ref.image.php) --- ## Freetype Freetype在百度上解釋的比較好懂 ![](https://i.imgur.com/XG2iveK.png) ![](https://i.imgur.com/AEnCVN6.png) --- ## 不需Freetype驗證碼 [【PHP原生】數字和字母驗證碼](https://www.cnblogs.com/php99/p/9796211.html) [好讀版](https://www.itdaan.com/tw/bafb988f2174f4688e9e24fa24624429) 使用以下方式,可以在不使用freetype字體引擎下做出驗證碼 但這樣有個缺點 就是字體很小 *設置字體大小中默認值只有1-5* 所以出來圖片即使圖片實體很大 但字大小依然會給使用者帶來不便 要完全控制字體大小 [imagettftext()](https://www.php.net/manual/zh/function.imagettftext.php) 講解使用imagettftext()與imagestring() [Can't change font size for GD imagestring()](https://stackoverflow.com/questions/10954652/cant-change-font-size-for-gd-imagestring) 大小字體很小 ![](https://i.imgur.com/ksGB8Kt.png) ```php= //設置session,必須處於腳本最頂部 session_start(); $image = imagecreatetruecolor(100, 30); //1>設置驗證碼圖片大小的函數 //設置驗證碼顏色 imagecolorallocate(int im, int red, int green, int blue); $bgcolor = imagecolorallocate($image, 255, 255, 255); //#ffffff //區域填充 int imagefill(int im, int x, int y, int col) (x,y) 所在的區域着色,col 表示欲塗上的顏色 imagefill($image, 0, 0, $bgcolor); //設置變量 $captcha_code = ""; //生成隨機的字母和數字 for ($i = 0; $i < 4; $i++) { //設置字體大小 $fontsize = 8; //設置字體顏色,隨機顏色 $fontcolor = imagecolorallocate($image, rand(0, 120), rand(0, 120), rand(0, 120)); //0-120深顏色 //設置需要隨機取的值,去掉容易出錯的值如0和o $data = 'abcdefghigkmnpqrstuvwxy3456789'; //取出值,字符串截取方法 strlen獲取字符串長度 $fontcontent = substr($data, rand(0, strlen($data)), 1); // .=連續定義變量 $captcha_code .= $fontcontent; //設置坐標 $x = $i * 100 / 4 + rand(5, 10); $y = rand(5, 10); imagestring($image, $fontsize, $x, $y, $fontcontent, $fontcolor); } //存到session $_SESSION['authcode'] = $captcha_code; //增加干擾元素,設置雪花點 for ($i = 0; $i < 200; $i++) { //設置點的顏色,50-200顏色比數字淺,不干擾閱讀 $pointcolor = imagecolorallocate($image, rand(50, 200), rand(50, 200), rand(50, 200)); //imagesetpixel — 畫一個單一像素 imagesetpixel($image, rand(1, 99), rand(1, 29), $pointcolor); } //增加干擾元素,設置橫線 for ($i = 0; $i < 4; $i++) { //設置線的顏色 $linecolor = imagecolorallocate($image, rand(80, 220), rand(80, 220), rand(80, 220)); //設置線,兩點一線 imageline($image, rand(1, 99), rand(1, 29), rand(1, 99), rand(1, 29), $linecolor); } //設置頭部,image/png header('Content-Type: image/png'); //imagepng() 建立png圖形函數 imagepng($image); //imagedestroy() 結束圖形函數 銷毀$image imagedestroy($image); ``` 方法二 大小字體很大~ ![](https://i.imgur.com/6lXYTuw.png) ```php= $ImageText1Small = imagecreate( 148, 16 ); $ImageText1Large = imagecreate( 148, 16 ); $ImageText2Small = imagecreate( 308, 40 ); $ImageText2Large = imagecreate( 308, 40 ); $ImageFinal = imagecreate( 500, 100 ); $backgroundColor1 = imagecolorallocate($ImageText1Small, 255,255,255); $textColor1 = imagecolorallocate($ImageText1Small, 0,0,0); $backgroundColor2 = imagecolorallocate($ImageText2Small, 255,255,255); $textColor2 = imagecolorallocate($ImageText2Small, 0,0,0); imagestring( $ImageText1Small, 1, 1, 0, 'Stack Overflow', $textColor1 ); imagestring( $ImageText2Small, 5, 1, 0, 'Harry Harry Harry', $textColor2 ); imagecopyresampled($ImageText1Large, $ImageText1Small, 0, 0, 0, 0, 148, 16, 74, 8); imagecopyresampled($ImageText2Large, $ImageText2Small, 0, 0, 0, 0, 308, 40, 154, 20); $ImageText1Large = imagerotate ( $ImageText1Large, 20, $backgroundColor1 ); $ImageText2Large = imagerotate ( $ImageText2Large, -5, $backgroundColor2 ); $ImageText1W = imagesx($ImageText1Large); $ImageText1H = imagesy($ImageText1Large); $ImageText2W = imagesx($ImageText2Large); $ImageText2H = imagesy($ImageText2Large); imagecopymerge($ImageFinal, $ImageText1Large, 350, 20, 0, 0, $ImageText1W, $ImageText1H, 100); imagecopymerge($ImageFinal, $ImageText2Large, 20, 20, 0, 0, $ImageText2W, $ImageText2H, 100); // header( "Content-type: image/png" ); header('Content-Type: image/png'); imagepng($ImageFinal); imagecolordeallocate( $ImageText1, $textColor1 ); imagecolordeallocate( $ImageText2, $textColor2 ); imagedestroy($ImageText1); imagedestroy($ImageText2); ``` --- --- ## GD教學 原文 [Render Text and Shapes on Images in PHP](https://code.tutsplus.com/tutorials/rendering-text-and-basic-shapes-using-gd--cms-31767) 翻譯 [在PHP中渲染图像上的文本和形状](https://blog.csdn.net/cunjie3951/article/details/106905597)