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

发布于 2024-08-30 03:21:59 字数 2819 浏览 1 评论 0 原文

不久前,我制作了一个脚本,它接受一些文本并将其作为图像返回,并且工作完美。但我不确定从什么时候开始出现奇怪的错误。左侧有(我向字体极客道歉)“字形”的字母被推到右侧,因此字母从其开始,但只为主字母留下空间,呵呵,我认为一个例子应该做到这一点。

alt text
(来源:esbasura.com

预期结果是: 替代文本
(来源:esbasura.com

“坏”显然,一个是由我的脚本生成的,位于此处: 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]);

Some time ago I made a script that takes some text and returns it as an image, and worked flawlessly. But I'm not sure since when a weird bug started to happen. The letters that have a (my apologies to the font geeks) "glyph" on the left get pushed to the right so the letter starts on it, but leaves space only for the main letter, hehe, I think an example should do it.

alt text
(source: esbasura.com)

The expected result is:
alt text
(source: esbasura.com)

The "bad" one was generated, obviously, by my script, located here: http://www.esbasura.com/images/text.php?txt=The%20quick%20brown%20fox%20jumps%20over%20the%20lazy%20dog.&fnt=1&size=23&bg=lightgrey
And the good one was generated by dafont here: 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

I'm not doing anything fancy in the script, here is the relevant part:

                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);
    }

I'm kind of surprised, because, as I said, it used to work flawlessly. Maybe my host changed my machine.

(here's my phpinfo: http://www.work4bandwidth.com/info.php)
Relevant bit:

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

EDIT:
Also note that the image size calculation apparently is done taking in consideration the correct rendering of the font, I'm calculating it using:

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

荆棘i 2024-09-06 03:21:59

不幸的是,我在使用 PHP 和 PHP 时也必须处理问题。用于生成标题图形的 GDLib。我的大部分项目都使用 TYPO3 作为 CMS。它可以创建图形标题并利用 GDLib。我不得不与质量问题作斗争:在我的本地开发机器(osx)上,字体以极好的质量呈现,在生产服务器(gentoo)上,它是模糊的并且“薄”。我不知道这些差异是因为平台不同还是因为 PHP/GDLib 版本略有不同。我也遇到了像你这样的问题,尤其是当网络主机升级到较新的 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" />';

该图像如下所示:

替代文字

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

我在 Windows 上使用了此 IM 版本:

ImageMagick 6.5.4-6 2009-07-25 Q16 OpenMP 

在此处阅读有关 imagemagicks 文本处理功能的更多信息:http://www.imagemagicks.com imagemagick.org/Usage/text/

虽然Imagemagick现在是一个相当常见的软件包,但仍然有主机没有安装IM。但是您可以下载静态编译的 IM 版本,只需通过 FTP 将其上传到某个目录中,使二进制文件可写,然后您就可以使用它来生成图像。我找到了一个关于如何执行此操作的教程,不幸的是只有德语版本,但我相信您可以从提供的 shell 命令中掌握基本概念:http://www.website4all.de/support/support-typo3/imagemagick.html


虽然 Imagemagick 是一个可行的选择,但我最终使用了 client side javascript 以便创建带有嵌入字体的图形标题。

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

  • 如果你有很多元素来替换设置,网站会变得非常慢,
  • 有点麻烦,
  • 它依赖于 Flash,头条新闻无法在 iPhone 或 iPad 上运行,

我会创建一个示例,但我的笔记本电脑上没有安装 Adob​​e Flash CS。

不管怎样,我终于找到了一个很好的客户端 JavaScript 库,它满足了我的要求:Cufon ( http://cufon.shoqolate.com/generate/)。您将 ttf 文件上传到该服务,然后使用创建的 javascript 文件和 Cufon 基础库,以便用图形标题替换标题元素。 Cufon 使用 canvas 元素来做到这一点。了解更多关于它是如何完成的,请访问 https://github.com/sorccu/cufon/wiki/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>

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

替代文字

正如您在 html 站点的源代码中看到的,您通过 CSS 定义字体大小(可能也需要调整)和颜色。然后调用 Cufon.replace('p', {fontFamily: 'Bleeding Cowboys'}); 来告诉 Cufon 替换什么(在本例中为所有 p元素)使用什么字体系列(在本例中为 Bleeding Cowboys)。


我知道,这些并不是您问题的直接答案,但是客户端标题创建给了我非常好的结果,并且设置和代码比我尝试过的所有服务器端解决方案更简单。如果我是您,我会尝试 sIFR 或 Cufon,尽管 IM 可能值得提前尝试,特别是如果您仅限于服务器端解决方案。

Unfortunately I also had to deal with issues when using PHP & GDLib for generating headline graphics. I use TYPO3 as CMS for most of my projects. It can create graphical headers and leverages GDLib for it. I had to struggle with quality issues: on my local dev machine (osx), the font was rendered in superb quality, on the production server (gentoo), it was blurry and to "thin". I dont know if these differences were because of the different platforms or because the PHP/GDLib versions were slightly different. I also encountered problems like yours, especially when the web host was upgraded to a newer PHP version. Yesterday the headlines looked good, after the update, the chars were misplaced, umlauts were missing etc.

A serverside alternative could be imagemagick. This small PHP snippet creates a sample image (assuming the Bleeding_Cowboys.ttf is in the same dir as the script):

<?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" />';

The image looks like this:

alt text

You probaly need to adjust the font size a bit using another value for the -pointsize 23 argument.

I used this IM version on windows:

ImageMagick 6.5.4-6 2009-07-25 Q16 OpenMP 

Read more about imagemagicks text handling capabilities here: http://www.imagemagick.org/Usage/text/

Although Imagemagick is a quite common package now, there are still hosts that dont have IM installed. But you can download a statically compiled IM version which you just upload via FTP in some directory, make the binaries writable and then you can use it to generate your images. I found a tutorial on how to do this, unfortunately in German only, but I am sure you can grasp the basic idea from the shell commands provided: http://www.website4all.de/support/support-typo3/imagemagick.html


Although Imagemagick is a viable option, I finally used client side javascript in order to create graphical headlines with embedded fonts.

First, I stumbled upon sIFR ( http://wiki.novemberborn.net/sifr/ ) which replaces html content with flash objects in order to render the font. Although it looked promising at first, I dumped it because:

  • the website gets really slow if you have many elements to replace
  • the setup is a bit of a hassle
  • it relys on flash, the headlines wont work on iPhone or iPad

I would have created a sample for you, but I dont have Adobe Flash CS installed on my laptop.

Anyway, I finally found a good client side javascript lib, that did what I wanted: Cufon ( http://cufon.shoqolate.com/generate/ ). You upload your ttf file to that service and then use the created javascript file along with the Cufon base library in order to replace the headline elements with graphical headlines. Cufon uses the canvas element in order to do this. Read more about how its done on https://github.com/sorccu/cufon/wiki/about

What I really like about Cufon:

  • works on all major browsers, including IE 6 (and above)
  • works great on iPhone and iPad
  • very fast, even with many headlines
  • very easy setup

The only real concern I have about Cufon: licensing. This may be an issue especially with commercial fonts. Not all font creators allow this kind of embedding. If in doubt, always get written permission.

But anyway, a simple HTML site using Cufon might look like this:

<!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>

The resulting headline image looks like this:

alt text

As you can see in the source code of the html site, you define font size (probably need to adjust this, too) and color via CSS. And then you call Cufon.replace('p', {fontFamily: 'Bleeding Cowboys'}); in order to tell Cufon to replace what (in this case all p elements) with what font family (in this case, Bleeding Cowboys).


I know, these are no direct answers to your question, but client side headline creation gave me very good results with way easier setup and code then with all the serverside solutions I tried. If I were you, I would either give sIFR or Cufon a shot, although IM might be worth a try beforehand, especially if you are restricted to a serverside solution.

或十年 2024-09-06 03:21:59

可能 GD 库发生了变化,这就是问题的根源。它也可能是字体文件,但这种可能性较小。

你知道它多久前开始工作了吗?

是 PHP 4.3 之前的版本吗?就在那时,GD 库被捆绑到 PHP 中。

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

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

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

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

最终,您将准确地找到哪个版本的 GD 库破坏了您的软件。然后,您需要提交错误报告,希望它能得到修复。

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

Probably the GD library changed and that's the source of your problems. It could also be the font file, but that is less likely.

Do you know how long ago it was working?

Was it before PHP 4.3? That was when GD Library was bundled into PHP.

If before 4.3, try different versions of the standalone GD library.
See http://www.libgd.org

If it worked after Php 4.3, then just try different versions of PHP to find where it stopped working.

Solution: check the GD library releases and build a version of php that uses an older GD library (either standalone or bundled).

You could also discuss with your ISP, they may have a record of when they updated PHP to the various different versions.

Ultimately, you'll find exactly which version of GD library broke your software. You'll then need to submit a bug report and hopefully it'll be fixed.

Or you can create a small server that just uses the older version of php to serve up your dynamically created png's.

一生独一 2024-09-06 03:21:59

imagettfbbox() 有错误,它可能是导致您问题的原因,请尝试使用 http://ruquay.com/sandbox/imagettf/,也许这会解决它。

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

imagettfbbox() is buggy and it may be the cause of your problem, try using the imagettfbbox_t() function available at http://ruquay.com/sandbox/imagettf/, maybe that will solve it.

Also, are you sure the exact same ttf font? Because your version seems a little bolder than the original.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文