使用透明背景的 GD 绘制文本

Posted

技术标签:

【中文标题】使用透明背景的 GD 绘制文本【英文标题】:Draw text with GD with transparent background 【发布时间】:2012-03-31 00:53:00 【问题描述】:

我有这段代码可以在新创建的图像上写一些文字:

class ImageCreator

    public function Draw($string)
    
        $font = "lg.ttf";

        $txtsize = imagettfbbox(20, 0, $font, $string);
        $image = imagecreatetruecolor($txtsize[2], $txtsize[4]);
        imagealphablending($image, false);
        $c = imagecolorallocatealpha($image,0,0,0,127);
        imagefilledrectangle($image,0,0,$txtsize[2],$txtsize[4], $c);
        imagealphablending($image, true);

        $c = ImageCreator::hexcol2dec("#FFFFFF");
        $white = imagecolorallocate($image, $c[0], $c[1], $c[2]);
        $c = ImageCreator::hexcol2dec("#000000");
        $black = imagecolorallocate($image, $c[0], $c[1], $c[2]);

        $c = ImageCreator::hexcol2dec("#044D8F");
        $tcolor = imagecolorallocate($image, $c[0], $c[1], $c[2]);

        imagettftext($image, 20, 0, 0, 0, $black, $font, $string);
        imagettftext($image, 20, 0, 1, 0, $tcolor, $font, $string);
        imagettftext($image, 20, 0, 2, 0, $white, $font, $string);

        imagealphablending($image,false);
        imagesavealpha($image,true);
        ob_start();
        imagepng($image);
        $imgData = ob_get_contents();
        ob_end_clean();
        return $imgData;
    

    public function hexcol2dec($hexColor)
    
        $R=0;
        $G=0;
        $B=0;

        for($i = 0; $i < strlen($hexColor);$i++)
        
            if($hexColor[$i] == "#")
            

            
            else if($hexColor[$i] == 'A' || $hexColor[$i] == 'a')
            
                $dec[$i] = 10;
            
            else if($hexColor[$i] == 'B' || $hexColor[$i] == 'b')
            
                $dec[$i] = 11;
            
            else if($hexColor[$i] == 'C' || $hexColor[$i] == 'c')
            
                $dec[$i] = 12;
            
            else if($hexColor[$i] == 'D' || $hexColor[$i] == 'd')
            
                $dec[$i] = 13;
            
            else if($hexColor[$i] == 'E' || $hexColor[$i] == 'e')
            
                $dec[$i] = 14;
            
            else if($hexColor[$i] == 'F' || $hexColor[$i] == 'f')
            
                $dec[$i] = 15;
            
            else
            
                $dec[$i] = $hexColor[$i];
            
        
        if($hexColor[0] == "#")
        
            $R = 16*$dec[1]+$dec[2];
            $G = 16*$dec[3]+$dec[4];
            $B = 16*$dec[5]+$dec[6];
        
        else
        
            $R = 16*$dec[0]+$dec[1];
            $G = 16*$dec[2]+$dec[3];
            $B = 16*$dec[4]+$dec[5];
        
        return array ($R, $G, $B);
    



我得到的只是透明背景,没有显示任何文字。我是 php GD 的新手,我不知道为什么不写文本。请帮我弄清楚

谢谢。

【问题讨论】:

【参考方案1】:

imagettfbbox 返回的坐标是相对于基点的,因此可以是负数。

所以角度为0时,上Y和左X都是负数,需要从下Y和右X中减去它们才能得到盒子大小。

$width = $txtsize[2] - $txtsize[0];
$height = $txtsize[1] - $txtsize[5]; 
$image = imagecreatetruecolor($width, $height);

然后你必须使用负坐标的绝对值作为绘制文本的基点坐标:

imagettftext($image, 20, 0, -$txtsize[0], -$txtsize[5], $black, $font, $string);

【讨论】:

【参考方案2】:

您是否启用了警告? PHP 定位字体文件可能存在问题,因为我注意到它不是完整的路径。

您的服务器是否安装了 FreeType 库?使用phpinfo() 进行验证。 http://www.freetype.org/

您可以使用此沙盒测试您的坐标是否正确:http://ruquay.com/sandbox/imagettf/。

请记住,基点是您用来绘制带有imagettftext 的文本的x、y 坐标。一个有用的做法是取一个类似...的字符串

ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789

并使用“aboveBasepoint”值作为字体高度。现在您可以画线并使用“字体高度 * 前导”作为文本行之间的距离,其中前导是一个数字,例如 1.45(表示前导 45%)。

在 PHP 手册条目底部的 cmets 中查找该函数的许多有用功能:http://php.net/manual/en/function.imagettfbbox.php

【讨论】:

我收到此错误:Warning: imagettftext() expects parameter 1 to be resource, boolean given in C:\wamp\www\test\a\drawimage.php on line 22, 23, 24, 26, 27;我已经安装了 FreeType 库。 我不能再呆下去了......如果你知道答案,请回复,我希望我们可以稍后再谈。 这意味着imagecreatetruecolor()遇到错误并返回FALSE。我会验证 $txtsize[2] 和 $txtsize[4] 是有效的整数。 这是 $txtsize: 数组 0 => int -1 1 => int -1 2 => int 61 3 => int -1 4 => int 61 5 => int -21 6 = > int -1 7 => int -21,我使用 2 和 4 女巫都是 61 像素

以上是关于使用透明背景的 GD 绘制文本的主要内容,如果未能解决你的问题,请参考以下文章

使用 GD 的背景图像透明度

如何在 CBitmap 上使用具有透明背景的 CDC 绘制文本?

PHP中带有GD的透明背景

PHP GD 在另一个形状上绘制形状并使其透明

iOS UIView 子类将透明文本绘制到背景

如何在 PHP 中使用 GD 设置透明背景?