tags:

views:

150

answers:

3

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

The expected result is: alt text

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]);
+1  A: 

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.

Larry K
Thanks for your answer, but as I'm on a shared hosting I can't revert the php or gd version, maybe if I can't find a better solution I'll have to install another php just to serve that file as per your suggestion.
Javier Parra
+1  A: 

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.

Alix Axel
Thanks a lot, I tried the imagegettfbox_t function, but no dice, seems like it only fixes the bounding box for rotated text. And yes, I modified the box a bit, in order to add latin characters like á ü etc... but the first thing I did was try with the original font, same result.BTW the bolder is actually a bit of bg color behind it ;-)
Javier Parra
@Javier: Then I think the best thing to do would be to submit a bug on the PHP website with all this info.
Alix Axel
+3  A: 

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 http://wiki.github.com/sorccu/cufon/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"&gt;
<html xmlns="http://www.w3.org/1999/xhtml"&gt;
    <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.

Max
+1 - SO needs the ability to add answers to favorites ;)
Moak
Thanks a lot, very thorough answer, I think I'll try something with imagemagick, for no particular reason, the only thing I'm slightly concerned about is that I calculate the font size dynamically to avoid overflowing. I'll have to think on a way to do that, I guess it shouldn't be too hard but will consume more resources.
Javier Parra