PHP 文字生成點陣圖

jcc123發表於2019-07-31

七夕到了是不是該做點什麼了~
體驗地址
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;
}

NOT IS BECAUSE I WANT TO WRITE,
BUT I WANT TO INCREASE,
SO I GO TO WRITE~~

相關文章