Reputation: 541
Screenshot of problem:
I'm trying to get the same font quality such as Font Squirrel's sample fonts widget, but the font keeps coming out rough. It's smooth in Photoshop. Note: the "The lazy dog" part isn't being bolded by me, its doing it by itself.
Here's the PHP:
<?php
putenv('GDFONTPATH=' . realpath('.'));
$font = $_GET['font'] . '.ttf';
$text = 'The Quick Brown Fox Jumps over the Lazy Dog';
// Create the image
function imageCreateTransparent($x, $y) {
$imageOut = imagecreate($x, $y);
$colourBlack = imagecolorallocate($imageOut, 0, 0, 0);
imagecolortransparent($imageOut, $colourBlack);
return $imageOut;
}
$image = imageCreateTransparent(600, 800);
// Create some colors
$white = imagecolorallocate($image, 255, 255, 255);
$grey = imagecolorallocate($image, 128, 128, 128);
$black = imagecolorallocate($image, 0, 0, 0);
imagefilledrectangle($image, 0, 0, 399, 29, $white);
// Add the text
imagettftext($image, 20, 0, 10, 20, $black, $font, $text);
imagepng($image);
imagealphablending($image, true);
imagedestroy($image);
?>
HTML: <img src="fontgen.php?font=Aller_Rg" alt="" />
How can I get that high quality result for the font?
Upvotes: 3
Views: 5574
Reputation: 25701
You've only set part of the background to be white, the rest of it is transparent.
When the font is drawn over a white background, the black text is anti-aliased so that it looks smooth, which results in the pixels around the font being drawn as a blend between the two colours, which also makes the font look smaller.
On the right hand side there is no background colour so the anti-aliasing is not working properly. Instead of blending between the font colour and the background colour, the drawing algorithm is using the original font colour for any pixel that is even partly covered by a letter.
This makes the letters look 'bold' as the edge pixels are now black, instead of shades of grey.
The way to fix this properly is to use an image that has a proper background colour, even if that background colour is transparent. This makes the image library use a proper alpha-channel (which is the only sensible way of doing alpha blending) rather than using an indexed based alpha, where only one 'colour' is transparent and all the others are fully opaque.
$font = '../../fonts/Aller_Rg.ttf';
$text = 'The Quick Brown Fox Jumps over the Lazy Dog';
// Create the image
function imageCreateTransparent($x, $y) {
$imageOut = imagecreatetruecolor($x, $y);
$backgroundColor = imagecolorallocatealpha($imageOut, 0, 0, 0, 127);
imagefill($imageOut, 0, 0, $backgroundColor);
return $imageOut;
}
$image = imageCreateTransparent(600, 800);
// Create some colors
$white = imagecolorallocate($image, 255, 255, 255);
$grey = imagecolorallocate($image, 128, 128, 128);
$black = imagecolorallocate($image, 0, 0, 0);
imagefilledrectangle($image, 0, 0, 399, 29, $white);
//// Add the text
imagettftext($image, 20, 0, 10, 20, $black, $font, $text);
//imagealphablending($image, true); //not needed as we created the image with alpha
imagesavealpha($image, true);
//imagepng($image, '../../var/log/wtf5.png');
imagepng($image);
imagedestroy($image);
This will make the font size be right as the anti-aliasing will work correctly* and the image will be transparent where appropriate e.g. the image created with the code above, shown over a red background.
The bits of the image that have a white background are white, the bits of the image that are transparent let the red colour come through, and the text is anti-aliased correctly to both.
*assuming that you want to anti-alias to what the background colour was set to, which is not always the case but probably is here.
Upvotes: 15
Reputation: 354576
I suspect it's because you're making the background explicitly white only in the left 400 px. To the right of that it's probably still transparent and has some side-effects. The r
is the first letter that starts beyond the white background you created earlier.
Upvotes: 0