用PHP实现图片转字符画

最近在网上常常看到有那种字符画,感觉特别好玩,于是寻思着用PHP实现一个图片转字符画的功能。

根据网上获取到的信息:

  1. 图片转字符画的原理就是根据获取到的图像的像素的灰度值,用相应的字符来替换。
  2. 总结出了这样一个转化过程:

    • 设置像素块大小,将图片都分成这样的像素块,然后选取每个像素块的代表像素
    • 获取每个代表像素的RGB值,作为这个像素块的RGB值,计算灰度值
    • 根据灰度值选择填充准备好的字符
    • 输出
      灰度值就是我们看到的黑白图像的一种度量。它可以由公式:Gray=R*0.3+G*0.59+B*0.11计算得来。

于是有转化函数如下:

function convert($imgName,$size="medium"){
    /*
    *    参数说明:
    *    imageName    图像名称
    *    size        可选参数:low、medium、big 功能:控制输出不同的字符画大小
    *    echoText    功能:设置是否保存为txt文件
    */

    $im = getImg($imgName);    //自定义函数,获取不同格式的图像资源
    $output="";
    $str='@80GCLft1i;:,. ';    //填充字符

    //选取每个像素块的代表点。步长越大,图片越小
    switch($size){
        case "small":
            $stepx=8;
            $stepy=16;
            break;
        case "medium":
            $stepx=4;
            $stempy=8;
            break;
        case "big":
            $stepx=2;
            $stepy=4;
            break;
        default:
            $stepx=4;
            $stempy=8;
            break;
    }

    $x=imagesx($im);
    $y=imagesy($im);
    for($j=0;$j<$y;$j+=$stepy){
        for($i=0;$i<$x;$i+=$stepx){
            $colors=imagecolorsforindex($im,imagecolorat($im,$i,$j));    //获取像素块的代表点RGB信息
            $greyness=(0.3*$colors["red"]+0.59*$colors["green"]+0.11*$colors["blue"])/255;    //灰度值计算公式:Gray=R*0.3+G*0.59+B*0.11
            $offset=(int)ceil($greyness*(strlen($str)-1));    //根据灰度值选择合适的字符
            if($offset==(strlen($str)-1))
                $output.=" ";    //替换空格为 ;方便网页输出
            else
                $output.=$str[$offset];
        }
        $output.="
";
    }

    imagedestroy($im);
    return $output;    
}

getImg()是个自定义函数,功能是用来获取不同格式图片的图像资源

function getImg($imgName){
    $arr=getimagesize($imgName);
    if($arr[2]==1){
        return imagecreatefromgif($imgName);
    }else if($arr[2]==2){
        return imagecreatefromjpeg($imgName);
    }else if($arr[2]==3){
        return imagecreatefrompng($imgName);
    }else if(...){
        ...
    }
    else{
        echo "对不起,暂不支持该格式!";
    }
}

使用时直接调用output函数即可

$res=convert("aa.jpg","small",false);
echo "
".$res."";若要将其保存我文本也很简单,只需做一些简单的替换
$res=str_replace("
",PHP_EOL,$res);
$res=str_replace(" "," ",$res);
@unlink("output.txt");
file_put_contents("output.txt",$res);

几点说明

  1. 因为是用不同的字符来代替图像中的像素,所以字符的选择对最终效果的呈现很重要
  2. 若是直接echo到浏览器中,版式会因为浏览器的字体、大小等差异而有很大的差别。如果效果很差,建议直接复制到文本中查看(经测试,中文字体比较合适,如宋体)
  3. 在线图片转字符画试一试
    效果演示

超凶兔