2015-12-04 46 views
6

我有以下代碼以在圖像上打印文本。我還在文本週圍添加了一個調試框。不過,我注意到左邊的文字位於PHP給我的框外imagettfbbox如何使用PHP和GD帳戶進行字體刷新

enter image description here

這看起來與字體斜的問題。無論如何說明這一點?我可以計算出從斜槓開始到實際位置imagettfbbox給我的距離嗎?

我不認爲這是字體的問題,因爲我嘗試了幾個腳本樣式字體,結果是相似的。

<?php 

$font  = 'scriptin.ttf'; 
$text  = 'Ipsum'; 
$size  = 30; 
$image  = imagecreatetruecolor(200, 200); 
$fontColour = imagecolorallocate($image, hexdec('11'), hexdec('11'), hexdec('11')); 
$bgColour = imagecolorallocate($image, hexdec('CC'), hexdec('CC'), hexdec('CC')); 

imagefilledrectangle($image, 0, 0, 200, 200, $bgColour); 

$dimensions = imagettfbbox($size, 0, $font, $text); 
imagefilledrectangle(
    $image, 
    $dimensions[0] + 40, 
    $dimensions[7] + 50, 
    $dimensions[2] + 40, 
    $dimensions[3] + 50, 
    imagecolorallocate($image, mt_rand(1, 180), mt_rand(1, 180), mt_rand(1, 180)) 
); 

imagettftext(
    $image, 
    $size, 
    0, 
    40, 
    50, 
    $fontColour, 
    $font, 
    $text 
); 

header('Content-Type: image/png'); 
imagepng($image); 

的代碼和字體可以在這裏找到:https://github.com/AydinHassan/image-swash-example

如果您在存儲庫點了VHOST,你可以打swash.php

+0

看起來您沒有正確放置方框着色:左側的「缺失」空間量看起來與右側的「太多」空間量相同。 –

+0

這就是我的想法,但如果我是這樣,我不明白我在哪裏做錯了。我正在使用信息'imagettfbbox'給我。 –

+1

http://php.net/manual/en/function.imagettfbbox.php#97211表明這是一個已知的,如果不方便的話。 –

回答

2

編輯:這似乎是固定的PHP 7.0.12(bug #53504),所以下面的代碼不需要。


基於一個comment in the PHP manual我已經寫了下面的函數計算並傳回哪裏GD認爲邊框的左側是與在最左側的像素被發現之間的區別:

function xadjust($size, $angle, $fontfile, $text) 
{ 
    $bbox = imagettfbbox($size, $angle, $fontfile, $text); 

    $width = $bbox[4] - $bbox[6]; // upper right x - upper left x; 
    $height = $bbox[1] - $bbox[7]; // lower left y - upper left y; 

    // create an image with height and width doubled to fit any 'swash'. 
    $im = imagecreatetruecolor($width * 2, $height * 2); 

    // set background color to opaque black. 
    imagefill($im, 0, 0, 0x00000000); 

    // draw the text in opaque white. 
    imagettftext(
     $im, 
     $size, 
     0, 
     $width/2, 
     $height, 
     0x00ffffff, 
     $fontfile, 
     $text 
    ); 

    // set the min-width to its possible maximum. 
    $min_x = $width * 2; 

    for ($x = 0; $x < $width * 2; $x++) { 
     // each x-pixel (horizontal) 
     for ($y = 0; $y < $height * 2; $y++) { 
      // each y-pixel (vertical) 
      if (imagecolorat($im, $x, $y) > 0) { 
       // non-black pixel found! 
       $min_x = min($x, $min_x); 
      } 
     } 
    } 

    imagedestroy($im); 

    // return the difference between where GD thinks the bounding box is and 
    // where we found the leftmost non-black pixel. 
    return (($width/2) - $min_x) - abs($bbox[0]); 
} 

這可以集成到你的腳本很容易:

$font  = 'scriptin.ttf'; 
$text  = 'Ipsum'; 
$size  = 30; 
$image  = imagecreatetruecolor(200, 200); 
$fontColour = imagecolorallocate($image, hexdec('11'), hexdec('11'), hexdec('11')); 
$bgColour = imagecolorallocate($image, hexdec('CC'), hexdec('CC'), hexdec('CC')); 

imagefilledrectangle($image, 0, 0, 200, 200, $bgColour); 

$xadjust = xadjust($size, 0, $font, $text); // 1. get the adjust value. 

$dimensions = imagettfbbox($size, 0, $font, $text); 
imagefilledrectangle(
    $image, 
    $dimensions[0] + 40 - $xadjust, // 2. move the left-side of the box to the left. 
    $dimensions[7] + 50, 
    $dimensions[2] + 40 - $xadjust, // 3. move the right-side of the box to the left. 
    $dimensions[3] + 50, 
    imagecolorallocate($image, mt_rand(1, 180), mt_rand(1, 180), mt_rand(1, 180)) 
); 

imagettftext(
    $image, 
    $size, 
    0, 
    40, 
    50, 
    $fontColour, 
    $font, 
    $text 
); 

header('Content-Type: image/png'); 
imagepng($image); 

這給了我下面的輸出:

script result

我用一些其他字體和大小運行它,它似乎是準確的在1個像素內。

+1

我結束了類似的東西。除了我倒數以外,這爲大型圖像節省了大量時間。我還進行了初步檢查,將文本渲染爲臨時圖像,並檢查第一列中是否有像素。我需要這些優化,因爲我們將批量渲染這些圖像。謝謝! –