zoukankan      html  css  js  c++  java
  • php使用gd库输出中文内容的图片

      正如标题所说那样,本文只讨论输出内容全部为中文或者包含中文的情况。如果内容全是字母或者其他字符的话,可以参考这篇博客:生成验证码

    问题

      此处要注意,标题中为什么要区别windows和linux分别实现?因为我在网上搜了很多的博客,几乎所有的博客都是一样的,全是使用的windows系统,源代码在linux上跑不通,会提示一个函数imagettftext()不存在,这个函数在windows下是可以使用的,但是在linux上面确实不行的。这是为什么呢?

      有人说是linux的gd库版本太低了,应该升级为高版本的gd库????

      且不说是不是真么gd库太老了,另外一个问题就是,使用imagettftext()函数的时候,需要传递一个参数,参数就是字体的文件的路径及名称。这个该怎么整?

      所以下面就按照上面的问题来叙述。

      

    imagettftext()

      先看下面这个phpinfo()中对gd库的描述:

      再看下面一个系统中phpinfo()的输出:

      仔细注意上面两个gd库的区别,就会发现,第二个gd库相对于第一个gd库要多一些“功能”,这个功能就是关系到能不能使用imagettftext()函数。

      在一些linux上使用imagettftext()函数时,会提示函数不存在,但是,在windows上就行,其实就是这个原因。

      如果你的php上面没有这个FreeType,可以在网上找一下相关的博客。

    多字节字符串操作

      多字节字符串的截断、求长度的问题,可以使用mb_扩展,否则会出现乱码。

      

    字体

      中文验证码的内容是中文,所以,要使用中文的字体,可以上网下载即可。在imagettftext()指定字体文件的路径以及文件名和扩展名即可。

    下面就是一个简单的中文验证码例子:

      产生的验证码内容存储在session中(在captcha.php完成),提交验证码(在index.php中完成)之后,在validate.php中将提交的验证码和session中的验证码作对比即可。

      如果要安全一点的话,可以将验证码加密后再存session。

     

    captcha.php  专门创建中文验证码

    <?php
        class Captcha{
            private $width;//验证码的宽
            private $height;//验证码的高
            private $num;//验证码字符的个数
            private $code;//验证码的字符串
            private $img;//验证码source
    
            //初始化
            function __construct($width=80,$height=20,$num=4){
                mb_internal_encoding("UTF-8");
                $this->width=$width;
                $this->height=$height;
                $this->num=$num;
                $this->code=$this->create_code();
            }
    
            //创建画布
            private function create_canvas(){
                $this->img=imagecreatetruecolor($this->width,$this->height);
                $background_color=imagecolorallocate($this->img,0xFF,0xFF,0xFF);
                imagefill($this->img,0,0,$background_color);
                $border_color=imagecolorallocate($this->img,0xAA,0xAA,0xAA);
                imagerectangle($this->img,0,0,$this->width-1,$this->height-1,$border_color);
            }
    
            //生成验证码的字符串
            private function create_code(){
                $src="这是字典XXXXX";
                $code="";
                for($i=0;$i<$this->num;$i++){
                    $index=mt_rand(0,mb_strlen($src)-1);
                    $code.= mb_substr($src,$index,1); //注意求多字节内容的长度时使用mb_扩展
                }
                return $code;
            }
    
            //将生成的字符串画在画布上
            private function paint_char(){
                for($i=0;$i<$this->num;$i++){
                    $char_color=imagecolorallocate($this->img,0xFF,0,0xFF);
                    $font_size=24;
                    $x=5+($this->width/$this->num)*$i;
                    $y=($this->height-imagefontheight($font_size));
                    imagettftext($this->img,$font_size,mt_rand(2, 20),$x,$y,$char_color,"STXINGKA.TTF",mb_substr($this->code,$i,1,"UTF-8"));
                    //注意截取多字节的内容使用mb_扩展
                }
            }
            
            //添加干扰标记 
            private function add_disturbance(){
                for($i=0;$i<20;$i++){
                    $color=imagecolorallocate($this->img,rand(0,255),rand(0,255),rand(0,255));
                    imagesetpixel($this->img,rand(1,$this->width-2),rand(1,$this->height-2),$color);
                }
            }
    
            //输出图片
            private function print_code() {
                if (imagetypes() & IMG_PNG) {
                    header("Content-type: image/png");
                    imagepng($this->img);
                } elseif (imagetypes() & IMG_JPG) {
                    header("Content-type: image/jpeg");
                    imagejpeg($this->img);
                }  else {
                      die("No image support in this PHP server");
                }
            }
    
            //获取验证码字符串的值
            public function get_code(){
                return $this->code;
            }
    
            //释放资源
            private function destroy_code(){
                imagedestroy($this->img);
            }
    
            //搞定所有验证码的工作
            public function show_image_code(){
                $this->create_canvas();
                $this->paint_char();
                $this->add_disturbance();
                $this->print_code();
                $this->destroy_code();
                
            }
        }
    
        session_start();
        $captcha = new Captcha(200, 60, 4);
        $captcha->show_image_code();
        $_SESSION['cap_v'] = $captcha->get_code();
     ?>

      

    index.html   首页显示

    <!DOCTYPE html>
    <html>
        <head>
            <title>中文验证码</title>
            <meta charset='utf-8'>
        </head>
    
        <body>
            <img id="captcha_img" border='1' src='./captcha.php' style=" 100px; height: 30px"><br>
            <a href='' id="change_img">换一个?</a><br><br>
            <input type='text' id='cap_v'>
            <button id="btn">submit</button>
        </body>
    
        <script>
            var captcha_img = document.getElementById("captcha_img"); 
            var change_img  = document.getElementById("change_img");
            var btn         = document.getElementById("btn");
            change_img = captcha_img.onclick = function(){
                captcha_img.src='./captcha.php?r='+Math.random();
                return false;
            }
        
            btn.onclick = function(){ 
                var xhr = new XMLHttpRequest();
                var cap_v = document.getElementById("cap_v").value; 
                if( cap_v.trim().length == 0){
                    alert("验证码不能为空");
                    return;
                }
                xhr.open("post","validate.php",true);
                xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
                xhr.send("cap_v=" + cap_v);
                xhr.onreadystatechange = function(){
                    if(xhr.readyState==4){
                        if((xhr.status==200 && xhr.status<300) || xhr.status==304){
                            if(xhr.responseText == 'right'){
                                alert("欢迎");
                            } else {
                                alert("验证码输入错误");
                            }
                        } 
                    }
                }
            }
        </script>
    </html>
    

      

    validate.php 用于检测验证码是否正确

    <?php
        session_start();
        if(isset($_POST['cap_v'])){
            if($_SESSION['cap_v'] == trim($_POST['cap_v'])){
                echo 'right';
            } else {
                echo 'wrong';
            } 
        }
    ?>
    

      

    运行截图:

  • 相关阅读:
    SecureCRT上传文件到服务器 CentOS举例
    MongoDB关于replSet的配置概述(一主二从)
    MongoDB的安装与卸载与再安装……
    zip在python中的使用方法
    try,raise等的python的使用方法介绍
    【转】jQuery给动态添加的元素绑定事件的方法
    sublime的纵向操作(列操作)原来这么用
    Python 利用*args和**kwargs解决函数遇到不确定数量参数问题
    Python 函数式编程介绍
    Python list可以做什么
  • 原文地址:https://www.cnblogs.com/-beyond/p/9193304.html
Copyright © 2011-2022 走看看