用PHP的imagettftext繪制文字的換行問(wèn)題

小追兵專欄

項(xiàng)目的一些說(shuō)明:
  • 我們?cè)谧鲆粋€(gè)漢字的項(xiàng)目废离,在這個(gè)項(xiàng)目中我們需要使用ps不停的制作一種圖片琳拭;
  • 而圖片樣式基本固定枣接。每次制作都需要設(shè)計(jì)人員重復(fù)排版盒至,不停調(diào)整圖片和文字間隔和大小争舞;
  • 這樣的事如果做一兩次還是可以忍受的凛忿,可是每天都為這個(gè)花費(fèi)大量的時(shí)間,就太折磨人了兑障;
  • 精通php的老板一看侄非,覺(jué)得這個(gè)用php就可以解決蕉汪,于是他就把這活交給了我,通過(guò)php自動(dòng)生成一張樣式統(tǒng)一的卡片逞怨,用來(lái)減輕設(shè)計(jì)小女孩的工作量者疤,把她從不停的排版中解除出來(lái)(可是我一點(diǎn)不懂php啊,我是做Android的叠赦,沒(méi)關(guān)系驹马,不會(huì)我們可以學(xué)習(xí)嘛。哈哈~~)除秀;
  • 就這樣這個(gè)任務(wù)落到了公司除老板意外唯一懂技術(shù)的我的肩膀上了糯累;
  • 來(lái)讓我們看看是什么樣樣子的一個(gè)卡片呢?
項(xiàng)目制作的卡片如下圖:

[圖片上傳失敗...(image-a2974c-1511782668998)]

由圖可以看出册踩,整個(gè)大圖由小的圖片和文字組成泳姐。由于文字的多少是不確定的,每次的解釋長(zhǎng)短不一樣暂吉,所以我們用程序畫圖的時(shí)候胖秒,要?jiǎng)討B(tài)的根據(jù)文字的長(zhǎng)短,個(gè)數(shù)慕的,計(jì)算出文字占用的高度阎肝。

我們使用imagettftext這個(gè)函數(shù)把文字繪制在圖片上,可是問(wèn)來(lái)了肮街,我們要解決換行問(wèn)題风题,還要解決行間距的問(wèn)題。如果我們單純的插入\n作為換行符嫉父,會(huì)發(fā)現(xiàn)沛硅,行間距幾乎為零,很難看熔号。

下面是自己寫了一個(gè)換行算法稽鞭,并且可以設(shè)置行高同時(shí)鸟整,可以返回文字占用的高度引镊。也想辦法拍出來(lái),標(biāo)點(diǎn)符號(hào)出現(xiàn)在句首的問(wèn)題篮条。

下面附上“自動(dòng)換行”和“計(jì)算段落高”的算法弟头,執(zhí)行后悔直接繪制。:
//下面函數(shù)方法我是這樣調(diào)用的涉茧,這里是用來(lái)測(cè)量高度的赴恨。

    
     $temp = array("color" => array(99, 99, 99), "fontsize" =>27, "width" => 496, "left" => 100, "top" => 0, "hang_size" => 40);
    //這里我只用它做測(cè)量高度,把參數(shù)false改為true就是繪制了伴栓。
    $str_h=draw_txt_to($im, $temp, $str, false);
    

//----------分割線------------

/**
 * 文字自動(dòng)換行算法
 * @param $card 畫板
 * @param $pos 數(shù)組伦连,top距離畫板頂端的距離雨饺,fontsize文字的大小,width寬度惑淳,left距離左邊的距離额港,hang_size行高
 * @param $str 要寫的字符串
 * @param $iswrite  是否輸出,ture歧焦,  花出文字移斩,false只計(jì)算占用的高度
 * @return int 返回整個(gè)字符所占用的高度
 */

function draw_txt_to($card, $pos, $str, $iswrite)
{

    $_str_h = $pos["top"];
    $fontsize = $pos["fontsize"];
    $width = $pos["width"];
    $margin_lift = $pos["left"];
    $hang_size = $pos["hang_size"];
    $temp_string = "";
    $font_file = "./Fonts/華文細(xì)黑.ttf";
    $tp = 0;

    $font_color = imagecolorallocate($card, $pos["color"][0], $pos["color"][1], $pos["color"][2]);
    for ($i = 0; $i < mb_strlen($str); $i++) {

        $box = imagettfbbox($fontsize, 0, $font_file, $temp_string);
        $_string_length = $box[2] - $box[0];
        $temptext = mb_substr($str, $i, 1);

        $temp = imagettfbbox($fontsize, 0, $font_file, $temptext);

        if ($_string_length + $temp[2] - $temp[0] < $width) {//長(zhǎng)度不夠,字?jǐn)?shù)不夠绢馍,需要

            //繼續(xù)拼接字符串向瓷。

            $temp_string .= mb_substr($str, $i, 1);

            if ($i == mb_strlen($str) - 1) {//是不是最后半行。不滿一行的情況
                $_str_h += $hang_size;//計(jì)算整個(gè)文字換行后的高度舰涌。
                $tp++;//行數(shù)
                if ($iswrite) {//是否需要寫入猖任,核心繪制函數(shù)
                    imagettftext($card, $fontsize, 0, $margin_lift, $_str_h, $font_color, $font_file, $temp_string);
                }

            }
        } else {//一行的字?jǐn)?shù)夠了,長(zhǎng)度夠了瓷耙。

//            打印輸出超升,對(duì)字符串零時(shí)字符串置null
            $texts = mb_substr($str, $i, 1);//零時(shí)行的開頭第一個(gè)字。

//            判斷默認(rèn)第一個(gè)字符是不是符號(hào)哺徊;
            $isfuhao = preg_match("/[\\\\pP]/u", $texts) ? true : false;//一行的開頭這個(gè)字符室琢,是不是標(biāo)點(diǎn)符號(hào)
            if ($isfuhao) {//如果是標(biāo)點(diǎn)符號(hào),則添加在第一行的結(jié)尾
                $temp_string .= $texts;

//                判斷如果是連續(xù)兩個(gè)字符出現(xiàn)落追,并且兩個(gè)丟失必須放在句末尾的盈滴,單獨(dú)處理
                $f = mb_substr($str, $i + 1, 1);
                $fh = preg_match("/[\\\\pP]/u", $f) ? true : false;
                if ($fh) {
                    $temp_string .= $f;
                    $i++;
                }

            } else {
                $i--;
            }

            $tmp_str_len = mb_strlen($temp_string);
            $s = mb_substr($temp_string, $tmp_str_len-1, 1);//取零時(shí)字符串最后一位字符

                if (is_firstfuhao($s)) {//判斷零時(shí)字符串的最后一個(gè)字符是不是可以放在見面
                    //講最后一個(gè)字符用“_”代替。指針前移動(dòng)一位轿钠。重新取被替換的字符巢钓。
                    $temp_string=rtrim($temp_string,$s);
                    $i--;
                }
//            }

//            計(jì)算行高,和行數(shù)疗垛。
            $_str_h += $hang_size;
            $tp++;
            if ($iswrite) {

                imagettftext($card, $fontsize, 0, $margin_lift, $_str_h, $font_color, $font_file, $temp_string);
            }
//           寫完了改行症汹,置null該行的臨時(shí)字符串。
            $temp_string = "";
        }
    }

    return $tp * $hang_size;

}


function is_firstfuhao($str)
{
    $fuhaos = array("\\"", "“", "'", "<", "《",);

    return in_array($str, $fuhaos);

}

這樣我們的漢字換行繪制輸出贷腕,和測(cè)量高度的問(wèn)題就解決了背镇。雖然算法不完美,可是時(shí)間有限的情況下泽裳,基本能滿足了我們的需求瞒斩。

Github地址:https://github.com/SaudM/PhpCard

下篇,我們將實(shí)現(xiàn)該圖片的圖片和卡片的圓角處理涮总。

最后:有需要Shadowsock翻墻賬號(hào)可以私聊胸囱。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市瀑梗,隨后出現(xiàn)的幾起案子烹笔,更是在濱河造成了極大的恐慌裳扯,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,039評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件谤职,死亡現(xiàn)場(chǎng)離奇詭異嚎朽,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)柬帕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門哟忍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人陷寝,你說(shuō)我怎么就攤上這事锅很。” “怎么了凤跑?”我有些...
    開封第一講書人閱讀 165,417評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵爆安,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我仔引,道長(zhǎng)扔仓,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,868評(píng)論 1 295
  • 正文 為了忘掉前任咖耘,我火速辦了婚禮翘簇,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘儿倒。我一直安慰自己版保,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,892評(píng)論 6 392
  • 文/花漫 我一把揭開白布夫否。 她就那樣靜靜地躺著彻犁,像睡著了一般。 火紅的嫁衣襯著肌膚如雪凰慈。 梳的紋絲不亂的頭發(fā)上汞幢,一...
    開封第一講書人閱讀 51,692評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音微谓,去河邊找鬼森篷。 笑死,一個(gè)胖子當(dāng)著我的面吹牛堰酿,可吹牛的內(nèi)容都是我干的疾宏。 我是一名探鬼主播张足,決...
    沈念sama閱讀 40,416評(píng)論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼触创,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了为牍?” 一聲冷哼從身側(cè)響起哼绑,我...
    開封第一講書人閱讀 39,326評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤岩馍,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后抖韩,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蛀恩,經(jīng)...
    沈念sama閱讀 45,782評(píng)論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,957評(píng)論 3 337
  • 正文 我和宋清朗相戀三年茂浮,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了双谆。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,102評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡席揽,死狀恐怖顽馋,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情幌羞,我是刑警寧澤寸谜,帶...
    沈念sama閱讀 35,790評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站属桦,受9級(jí)特大地震影響熊痴,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜聂宾,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,442評(píng)論 3 331
  • 文/蒙蒙 一果善、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧系谐,春花似錦岭埠、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至止喷,卻和暖如春馆类,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背弹谁。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工乾巧, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人预愤。 一個(gè)月前我還...
    沈念sama閱讀 48,332評(píng)論 3 373
  • 正文 我出身青樓沟于,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親植康。 傳聞我的和親對(duì)象是個(gè)殘疾皇子旷太,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,044評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,167評(píng)論 25 707
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,105評(píng)論 4 62
  • 愿勤二十載供璧,還盡我恩責(zé)存崖。 從此出紅塵,一心向自然睡毒。
    參度Gfh閱讀 213評(píng)論 0 0
  • 今天下午考了六級(jí)演顾,兩點(diǎn)二十搖搖晃晃的起床了供搀,下床穿鞋梳頭檢查證件急急忙忙的背著書包出去了,跑到樓下看看表都已經(jīng)四十...
    莻木夏夏愛(ài)閱讀 246評(píng)論 0 1
  • 今年開春钠至,小區(qū)的小野貓們多了起來(lái)趁曼,其中一只小花喵格外讓人注意,因?yàn)樗欢↑c(diǎn)兒也不怕人棕洋。其他的大小喵們挡闰,見到了人總是...
    李淼淼閱讀 374評(píng)論 0 0