Maison > Article > développement back-end > 文字输出至图片的排版有关问题
文字输出至图片的排版问题
图片上给定一个方框(知道4点坐标),需要把一串文本分成N行输出到图片上,每行文字不能超过方框的宽度,N行总高度也不能超过方框。如果总高度会超过方框高度,则缩小字体,直至文字能全部显示在方框中。
目前情况:
不考虑英文分词
用mb_strlen及mb_substr获取长度和截取字符串
imagettfbbox计算文字宽高,imagettftext输出文字至图片
问题:
现在用递归可以在固定字体大小下,按照合适的宽度输出至图片。
但是如果最后高度超过了,怎么让它减小字体,重新走一遍?想用一个方法就搞定它。
------解决思路----------------------
計算字體大小不好。
其實可以這樣。
先把所有字先生成一張圖A,然後B作為底圖,然後縮小A使A能夠適合B。
------解决思路----------------------
使用等宽字体
一切就都可以计算了
------解决思路----------------------
不知道你是怎么写的(为什么要用递归?)
$font = 'c:/windows/fonts/simsun.ttf';<br />$text = iconv('gbk', 'utf-8', '图片上给定一个方框(知道4点坐标),需要把一串文本分成N行输出到图片上,每行文字不能超过方框的宽度,N行总高度也不能超过方框。如果总高度会超过方框高度,则缩小字体,直至文字能全部显示在方框中。');<br /><br />$im = imagecreate(200, 200);<br />$bg = imagecolorallocate($im, 255, 255, 255);<br />$pen = imagecolorallocate($im, 0, 0, 0);<br />$style = array( $pen, $pen, $bg, $bg, $pen );<br />imagesetstyle($im, $style);<br />iconv_set_encoding("internal_encoding", "UTF-8"); //我偏好 iconv,用 mb 也是一样的<br /><br />$sx = 20;<br />$sy = 20;<br />$ex = 180;<br />$ey = 180;<br />$h = 30; //行高<br />$loop = true;<br />while($loop) {<br /> $size = $h / 3 * 2; //字体大小<br /> $s = '';<br /> $r = 1;<br /> imagefilledrectangle($im, $sx, $sy, $ex, $ey, $bg);<br /> imagerectangle($im, $sx, $sy, $ex, $ey, IMG_COLOR_STYLED);<br /><br /> for($i=0; $i<iconv_strlen($text); $i++) {<br /> $c = iconv_substr($text, $i, 1);<br /> $box = ImageTTFBBox($size, 0, $font, $s.$c);<br /> if($box[2] - $box[0] < $ex - $sx) $s .= $c;<br /> else {<br /> if($h*$r > $ey - $sy) break;<br /> imagettftext($im, $size, 0, $box[0]+$sx, $sy+$h*$r, $pen, $font, $s);<br /> $s = '';<br /> $r++;<br /> $i--;<br /> }<br /> }<br /> if($s) {<br /> if($h*$r > $ey - $sy) {<br /> $h--;<br /> continue;<br /> }<br /> $loop = false;<br /> imagettftext($im, $size, 0, $box[0]+$sx, $sy+$h*$r, $pen, $font, $s);<br /> }<br />}<br />imagettftext($im, $size, 0, $sx, $ey+$h, $pen, $font, "size:$size");<br /><br />imagegif($im);