PHP 文字生成点阵图

七夕到了是不是该做点什么了~
体验地址
[2019-7-31 更新]
做了个包~~

 composer require jc91715/lattice -vvv
use Jc91715\Lattice\Lattice;

$str="helloworld";
$lattice = new Lattice($str,5);

echo $lattice->getResult();

php 文字生成点阵图

PHP 文字生成点阵图

<?php

$font_width = 16; // 单字宽度
$font_height = 16; // 单字高度
$byteCount = $font_width * $font_height / 8;//一个点阵占的字节数

$str=iconv("utf-8","gb2312//IGNORE", "我是大是的大萨法fasf大多数");
$n=5;//每一行四个字

//所有字的字模
$dot = getDot($str,$byteCount);
/**
 * $positions 平面坐标系
 * $sections 每一个字模在平面坐标系中的点。(可移动每一个字模的位置)
 * $spreadSections 所有字模在平面坐标系中的点,是$sections的展开
 *
 */
list($positions,$sections,$spreadSections) = getPositionsSections($dot,$byteCount,$n);

/**
 * 输出点阵html字符串
 */
echo getOutHtml($positions,$sections,$spreadSections,$n);

/**
 * 从字库中获得每一个字的字模
 * @param $str
 * @param $byteCount
 * @return string
 */
function getDot($str,$byteCount){
    $dot='';
    $fontFileName = './HZK16';//字库名字
    $fp = fopen($fontFileName, "rb");
    for ($i=0;$i<strlen($str);$i++){

        if(ord($str[$i])<160){//非汉字
            $location=(ord($str{$i}) + 156-1) * $byteCount;
        }else {//汉字
            $qh = ord($str[$i]) - 32 - 128;//区码
            $wh = ord($str[++$i]) - 32 - 128;//位码
            $location = (94 * ($qh - 1) + ($wh - 1)) * $byteCount; /* 计算汉字字模在文件中的位置 */
        }
        fseek($fp, $location, SEEK_SET);//定位到汉字或字母指针开始的地方
        $dot.= fread($fp, $byteCount);//读取32字节的长度,一个字节8位,一行依次放两个字节组成16*16的点阵
    }
    fclose($fp);
    return $dot;
}

/**
 * 建平面按坐标系。并把每一区块用平面坐标系表示
 * @param $dot
 * @param $byteCount
 * @param $n
 * @return array
 */
function getPositionsSections($dot,$byteCount,$n){

    $count= strlen($dot)/$byteCount;//多少个字
    $positions=[];
    $sections =[];
    $sectionCount=$count;

    for ($i=0;$i<$sectionCount;$i++){
        $sections[]=[];

    }

    $yHeight=(intval($count/$n)*16+16);
    $xWeight=16*$n;
    for ($i=0;$i<$yHeight;$i++){
        for ($j=0;$j<$xWeight;$j++){
            $positions []=[$j,$i];
            $x=ceil(($j+1)/16);
            $y=ceil(($i+1)/16);
            $y--;
            $x--;
            $sections[(($y)*$n+$x)][] = [$j,$i];

        }
    }

    for ($b=0;$b<$count;$b++){//每一个字占用的点阵
        $str = substr($dot,($b)*32,$byteCount);//第几个字
        $dot_string='';
        for ($c = 0; $c < $byteCount; $c++){
            $dot_string .= sprintf("%08b", ord($str[$c]));
            if ($c % 2 == 1) {

                for($a=0;$a<strlen($dot_string);$a++){
                    if($dot_string[$a]){//和平面坐标系关联起来
                        $sections[$b][intval(16*floor($c/2)+$a)][]=1;
                    }
                }
                $dot_string = '';
            }
        }
    }
    $spreadSections=[];//每一个字块的的点展开到数组中
    foreach ($sections as $section){
        $spreadSections  = array_merge($spreadSections,$section);
    }

    return [$positions,$sections,$spreadSections,$count,$sectionCount];

}

function getOutHtml($positions,$sections,$spreadSections,$n){
    $str="<html><body><table border='1' width='100%' style='text-align: center'>";
    foreach (array_chunk($positions,16*$n) as $row){

        $str.=getOutRow($row,$sections,$spreadSections);
    }
    $str .= "</table></body>
</html>";
    return $str;
}

function getOutRow($row,$sections,$spreadSections){

    $str="<tr>";
    foreach ($row as $td) {
        if (!in_array($td,$spreadSections)){//不在平面坐标系中说明这个位置是一个点
            $str .= "<td style='color: white;background-color: red;'>O</td>";
        }else {
            $str .= "<td>O</td>";
        }
    }
    $str.="<tr>";
    return $str;
}
本作品采用《CC 协议》,转载必须注明作者和本文链接
Make everything simple instead of making difficulties as simple as possible
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 1

不错不错,偷走了。。。

4年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!