GD2,TTF和PHP的字母放置错误

时间:2010-04-22 23:40:31

标签: php gd2

前段时间我创建了一个脚本,它接受一些文本并将其作为图像返回,并且完美无缺地工作。但是我不确定从什么时候开始发生一个奇怪的错误。左边的字母(我对字体极客的道歉)左边的“字形”被推到右边,所以字母从它开始,但是只留下主要字母的空间,呵呵,我想一个例子应该这样做。

alt text http://www.esbasura.com/images/bad.png

预期结果是: alt text http://www.esbasura.com/images/good.png

显然,我的脚本位于此处生成了“糟糕的”:http://www.esbasura.com/images/text.php?txt=The%20quick%20brown%20fox%20jumps%20over%20the%20lazy%20dog.&fnt=1&size=23&bg=lightgrey 好的一个是由dafont在这里产生的:http://img.dafont.com/preview.php?text=The%20quick%20brown%20fox%20jumps%20over%20the%20lazy%20dog.&ttf=bleeding_cowboys0&ext=1&size=23&psize=m&y=46

我在脚本中没有做任何花哨的事情,这是相关的部分:

                imagefilledrectangle($im, 0, 0, $width, $height, $$bg);
                imagettftext($im, $size, 0, (-1*$textsize[6]), (-1*$textsize[7]), $$color, $font, $text);
//              imagefttext($im, $size, 0, (-1*$textsize[6]), (-1*$textsize[7]), $$color, $font, $text); same results using imagefttext
                imagecolortransparent($im, $$bg);
                header("Cache-Control: public"); // HTTP/1.1
                header("Content-type: image/png");
                imagepng($im);
                imagedestroy($im);
    }

我有点惊讶,因为正如我所说的那样,它曾经完美无缺地工作。也许我的主人改变了我的机器。

(这是我的phpinfo:http://www.work4bandwidth.com/info.php) 相关位:

gd
GD Support  enabled
GD Version  bundled (2.0.34 compatible)
FreeType Support    enabled
FreeType Linkage    with freetype
FreeType Version    2.2.1
GIF Read Support    enabled
GIF Create Support  enabled
JPG Support     enabled
PNG Support     enabled
WBMP Support    enabled
XBM Support     enabled

编辑: 另请注意,图像大小计算显然是在考虑到字体的正确渲染的情况下完成的,我正在使用以下方法进行计算:

                $textsize = imagettfbbox($size, 0, $font, $text);

                $width = ($textsize[2] - $textsize[0]);
                $height = ($textsize[3] - $textsize[5]);

3 个答案:

答案 0 :(得分:3)

不幸的是,在使用PHP和PHP时,我也不得不处理问题。用于生成标题图形的GDLib。我在大多数项目中使用TYPO3作为CMS。它可以创建图形标题并为其利用GDLib。我不得不在质量问题上挣扎:在我的本地开发机器(osx)上,字体在生产服务器(gentoo)上以极好的质量呈现,它模糊不清并且“瘦”。我不知道这些差异是因为不同的平台还是因为PHP / GDLib版本略微不同。我也遇到了像你这样的问题,特别是当web主机升级到更新的PHP版本时。昨天头条新闻看起来不错,更新后,字符错位,变音符号丢失等。

服务器端替代可能是imagemagick。这个小的PHP代码段创建了一个示例图像(假设Bleeding_Cowboys.ttf与脚本位于同一目录中):

<?php
$currentDir = dirname(__FILE__);
$fontPathname = $currentDir . '/Bleeding_Cowboys.ttf';

$cmd = '  convert -background white -fill black -font "' . $fontPathname . '" -pointsize 23 label:"The quick brown fox jumps over the lazy dog" ' . $currentDir . '/headline.png';
exec($cmd);

print '<img src="headline.png" alt="" border="0" />';

图片如下所示:

alt text http://i45.tinypic.com/nckym0.png

你可能需要使用-pointsize 23参数的另一个值来调整字体大小。

我在Windows上使用了这个IM版本:

ImageMagick 6.5.4-6 2009-07-25 Q16 OpenMP 

在此处详细了解imagemagicks文本处理功能:http://www.imagemagick.org/Usage/text/

虽然Imagemagick现在是一个非常常见的软件包,但仍有主机没有安装IM。但是你可以下载一个静态编译的IM版本,你只需要在某个目录中通过FTP上传,使二进制文件可写,然后你可以用它来生成你的图像。我发现了一个关于如何做到这一点的教程,遗憾的是只用德语,但我相信你可以从提供的shell命令中掌握基本思想:http://www.website4all.de/support/support-typo3/imagemagick.html


虽然Imagemagick是一个可行的选择,但我最终使用客户端 javascript来创建带有嵌入字体的图形标题。

首先,我偶然发现 sIFR http://wiki.novemberborn.net/sifr/),它用flash对象替换html内容以呈现字体。虽然起初它看起来很有希望,但我抛弃它是因为:

  • 如果您有许多要替换的元素,网站会变得非常慢
  • 设置有点麻烦
  • 它依赖闪存,头条新闻不适用于iPhone或iPad

我会为你创建一个样本,但我的笔记本电脑上没有安装Adobe Flash CS。

无论如何,我终于找到了一个好的客户端javascript lib,它做了我想要的: Cufon http://cufon.shoqolate.com/generate/)。您将ttf文件上传到该服务,然后将创建的javascript文件与Cufon基本库一起使用,以便用图形标题替换标题元素。 Cufon使用canvas元素来执行此操作。详细了解如何在http://wiki.github.com/sorccu/cufon/about

上完成

我非常喜欢Cufon:

  • 适用于所有主流浏览器,包括IE 6(及以上版本)
  • 在iPhone和iPad上运行良好
  • 非常快速,即使标题很多
  • 非常简单的设置

我对Cufon唯一真正的担忧:许可。这可能是一个问题,尤其是商业字体。并非所有字体创建者都允许这种嵌入。如有疑问,请务必获得书面许可。

但无论如何,使用Cufon的简单HTML网站可能如下所示:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>Test</title>
        <script type="text/javascript" src="cufon.js"></script>
        <script type="text/javascript" src="Bleeding_Cowboys_400.font.js"></script>
        <script type="text/javascript">
          Cufon.replace('p', {fontFamily: 'Bleeding Cowboys'});
        </script>
        <style type="text/css">
        p {
            color:#000;
            font-size:23px;
        }
        </style>
    </head>
    <body>
       <p>The quick brown fox jumps over the lazy dog</p>
    </body>
</html>

生成的标题图像如下所示:

alt text http://i45.tinypic.com/pon5g.png

正如您在html网站的源代码中所看到的,您可以通过CSS定义字体大小(可能也需要调整它)和颜色。然后你打电话给Cufon.replace('p', {fontFamily: 'Bleeding Cowboys'});以告诉Cufon用什么字体系列替换(在这种情况下所有p元素)(在这种情况下,Bleeding Cowboys)。


我知道,这些都不是你问题的直接答案,但客户端标题创建给我带来了非常好的结果,更方便的设置和代码,然后我尝试了所有的服务器端解决方案。如果我是你,我会给sIFR或Cufon一个镜头,虽然IM可能值得一试,特别是如果你被限制在服务器端解决方案。

答案 1 :(得分:1)

可能是GD库发生了变化,这是你问题的根源。它也可能是字体文件,但不太可能。

你知道它多久以前有效吗?

是在PHP 4.3之前吗?那是GD Library捆绑到PHP中的时候。

如果在4.3之前,请尝试不同版本的独立GD库。 见http://www.libgd.org

如果它在Php 4.3之后运行,那么只需尝试不同版本的PHP来找到它停止工作的地方。

解决方案:检查GD库版本并构建一个使用旧版GD库(独立版或捆绑版)的php版本。

您还可以与您的ISP讨论,他们可能会记录他们何时将PHP更新为各种不同的版本。

最终,您会发现哪个版本的GD库破坏了您的软件。然后,您需要提交错误报告,希望它能够得到修复。

或者您可以创建一个只使用较旧版本的php来提供动态创建的png的小型服务器。

答案 2 :(得分:1)

imagettfbbox()有错误且可能是您问题的原因,请尝试使用http://ruquay.com/sandbox/imagettf/提供的imagettfbbox_t()功能,这可能会解决问题。

另外,你确定完全相同的ttf字体吗?因为你的版本似乎比原版更大胆