2013-06-08 3 views
2

Capture d'écran du problème:texte PHP GD n'est pas lisse

enter image description here

J'essaie d'obtenir la même qualité de police tels que Font Squirrel's sample fonts widget, mais la police continue à venir ébaucher. C'est lisse dans Photoshop. Note: la partie "Le chien paresseux" n'est pas mise en gras par moi, elle le fait par elle-même.

Voici le 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="" />

Comment puis-je obtenir ce résultat de haute qualité pour la police?

Répondre

12

Vous avez seulement défini une partie de l'arrière-plan comme étant blanche, le reste est transparent. Lorsque la police est dessinée sur un fond blanc, le texte noir est anti-aliasé de sorte qu'il semble lisse, ce qui entraîne le dessin des pixels autour de la police comme un mélange entre les deux couleurs, ce qui rend également la police paraître plus petit.

Sur le côté droit, il n'y a pas de couleur d'arrière-plan, de sorte que l'anticrénelage ne fonctionne pas correctement. Au lieu de se fondre entre la couleur de la police et la couleur de l'arrière-plan, l'algorithme de dessin utilise la couleur de police d'origine pour tout pixel qui est même partiellement couvert par une lettre. Cela donne aux lettres l'aspect 'gras' car les pixels de bord sont maintenant noirs, au lieu des nuances de gris.

La manière de résoudre ce problème correctement consiste à utiliser une image qui a une couleur d'arrière-plan appropriée, même si cette couleur d'arrière-plan est transparente. Cela permet à la bibliothèque d'images d'utiliser un canal alpha approprié (qui est la seule manière sensée de faire un mélange alpha) plutôt que d'utiliser un alpha indexé, où une seule «couleur» est transparente et toutes les autres sont complètement opaques.

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

Cela rendra la taille de la police soit à droite comme l'anti-aliasing fonctionne correctement * et l'image sera transparente où par exemple approprié l'image créée avec le code ci-dessus, affichée sur un fond rouge. Les bits de l'image qui ont un arrière-plan blanc sont blancs, les bits de l'image transparents laissent passer la couleur rouge et le texte est anti-aliasé correctement pour les deux.

* en supposant que vous voulez anti-alias à ce que la couleur de fond a été définie, ce qui n'est pas toujours le cas, mais est probablement ici.

+0

Parfait. Merci et j'apprécie vraiment que vous preniez le temps de m'expliquer pourquoi cela se passe. J'en ai appris! Je vous remercie! – devs

0

Je suppose que c'est parce que vous rendez l'arrière-plan explicitement blanc seulement dans le 400 px gauche. À la droite de cela, il est probablement encore transparent et a des effets secondaires. Le r est la première lettre qui commence au-delà du fond blanc que vous avez créé précédemment.

+0

Alors, que dois-je changer pour résoudre ce problème? Je pensais que imageCreateTransparent (600, 800); est la pleine largeur. – devs

+1

'imagefilledrectangle ($ image, 0, 0, 399, 29, $ white);' ne couvre pas toute la largeur. – Joey