note 104239 modified in function.imagettftext by danbrown
| From: | danbrown@php.net | Date: | Thu, 02 Jun 2011 21:48:02 +0000 |
| Subject: | note 104239 modified in function.imagettftext by danbrown | ||
| References: | 1 | Groups: | php.notes |
| Request: | Send a blank email to php-notes+get-180209@lists.php.net to get a copy of this message | ||
If you need to render text to an exact sized image that then you will run into problems depending on
the font you use.
Use the code below to render text to an image that is exactly sized to fit.
This code will also take into consideration the baseline. You can safely render seperate pieces of
text and place them side by side without annoying pixel discrepencies.
<?php
//vars
$font = 'QuatroUltraBlack.ttf';
$text = 'hello world!';
$size = 40;//pt
$color = '#ffffff';
//over compensate dimensions!
$cropPadding = 6;
$fontRange = 'xgypqXi';
$bounds = imagettfbbox($size,0,$font,$fontRange);
$height = abs($bounds[1]-$bounds[5])+$cropPadding;
$y = abs($bounds[7])-1;
$bounds = imagettfbbox($size,0,$font,$text);
$width = abs($bounds[0]-$bounds[2])+$cropPadding+$cropPadding;
$x = ($bounds[0] * -1)+$cropPadding;
//create transparent image
$image = imagecreatetruecolor($width,$height);
imagesavealpha($image, true);
imagealphablending($image, false);
$background = imagecolorallocatealpha($image, 255, 255, 255, 127);
imagefilledrectangle($image, 0, 0, $width, $height, $background);
imagealphablending($image, true);
//make color
$rgb = str_split(ltrim($color,'#'),2);
$color = imagecolorallocatealpha($image,hexdec($rgb[0]),hexdec($rgb[1]),hexdec($rgb[2]),0);
//render text to image
imagettftext($image,$size,0,$x,$y,$color,$font,$text.' '.$fontRange);
//calculate crop
$trim_bottom = 0;
$trim_left = 0;
$trim_right = 0;
//bottom
for($trim_y = $height-1;$trim_y >= 0; $trim_y--) {
for($trim_x = 0; $trim_x < $width; $trim_x++) {
$alpha = (imagecolorat($image, $trim_x, $trim_y) >> 24) & 0xFF;
if($alpha != 127) { break 2; }
}
$trim_bottom++;
}
//left
for($trim_x = 0;$trim_x < $width; $trim_x++) {
for($trim_y = 0; $trim_y < $height; $trim_y++) {
$alpha = (imagecolorat($image, $trim_x, $trim_y) >> 24) & 0xFF;
if($alpha != 127) { break 2; }
}
$trim_left++;
}
//right
for($trim_x = $width-1;$trim_x >= 0; $trim_x--) {
for($trim_y = 0; $trim_y < $height; $trim_y++) {
$alpha = (imagecolorat($image, $trim_x, $trim_y) >> 24) & 0xFF;
if($alpha != 127) { break 2; }
}
$trim_right++;
}
//do crop
if ($trim_left || $trim_right || $trim_bottom) {
//create new image
$newWidth = $width-$trim_left-$trim_right;
$newHeight = $height-$trim_bottom;
$newImage = imagecreatetruecolor($newWidth,$newHeight);
imagesavealpha($newImage,true);
imagealphablending($newImage, false);
$background = imagecolorallocatealpha($newImage,255,255,255,127);
imagefilledrectangle($newImage,0,0,$newWidth,$newHeight,$background);
imagealphablending($newImage,true);
imagecopyresampled($newImage,$image,$trim_left,0,0,0,$imageWidth,$imageHeight,$imageWidth,$imageHeight);
//swap the new image
imagedestroy($image);
$image = $newImage;
}
//do something with image
imagepng($image);
//free image
imagedestroy($image);
?>
--was--
This is a correct to previous post (DOH!)
If you need to render text to an exact sized image that then you will run into problems depending on
the font you use.
Use the code below to render text to an image that is exactly sized to fit.
This code will also take into consideration the baseline. You can safely render seperate pieces of
text and place them side by side without annoying pixel discrepencies.
<?php
//vars
$font = 'QuatroUltraBlack.ttf';
$text = 'hello world!';
$size = 40;//pt
$color = '#ffffff';
//over compensate dimensions!
$cropPadding = 6;
$fontRange = 'xgypqXi';
$bounds = imagettfbbox($size,0,$font,$fontRange);
$height = abs($bounds[1]-$bounds[5])+$cropPadding;
$y = abs($bounds[7])-1;
$bounds = imagettfbbox($size,0,$font,$text);
$width = abs($bounds[0]-$bounds[2])+$cropPadding+$cropPadding;
$x = ($bounds[0] * -1)+$cropPadding;
//create transparent image
$image = imagecreatetruecolor($width,$height);
imagesavealpha($image, true);
imagealphablending($image, false);
$background = imagecolorallocatealpha($image, 255, 255, 255, 127);
imagefilledrectangle($image, 0, 0, $width, $height, $background);
imagealphablending($image, true);
//make color
$rgb = str_split(ltrim($color,'#'),2);
$color = imagecolorallocatealpha($image,hexdec($rgb[0]),hexdec($rgb[1]),hexdec($rgb[2]),0);
//render text to image
imagettftext($image,$size,0,$x,$y,$color,$font,$text.' '.$fontRange);
//calculate crop
$trim_bottom = 0;
$trim_left = 0;
$trim_right = 0;
//bottom
for($trim_y = $height-1;$trim_y >= 0; $trim_y--) {
for($trim_x = 0; $trim_x < $width; $trim_x++) {
$alpha = (imagecolorat($image, $trim_x, $trim_y) >> 24) & 0xFF;
if($alpha != 127) { break 2; }
}
$trim_bottom++;
}
//left
for($trim_x = 0;$trim_x < $width; $trim_x++) {
for($trim_y = 0; $trim_y < $height; $trim_y++) {
$alpha = (imagecolorat($image, $trim_x, $trim_y) >> 24) & 0xFF;
if($alpha != 127) { break 2; }
}
$trim_left++;
}
//right
for($trim_x = $width-1;$trim_x >= 0; $trim_x--) {
for($trim_y = 0; $trim_y < $height; $trim_y++) {
$alpha = (imagecolorat($image, $trim_x, $trim_y) >> 24) & 0xFF;
if($alpha != 127) { break 2; }
}
$trim_right++;
}
//do crop
if ($trim_left || $trim_right || $trim_bottom) {
//create new image
$newWidth = $width-$trim_left-$trim_right;
$newHeight = $height-$trim_bottom;
$newImage = imagecreatetruecolor($newWidth,$newHeight);
imagesavealpha($newImage,true);
imagealphablending($newImage, false);
$background = imagecolorallocatealpha($newImage,255,255,255,127);
imagefilledrectangle($newImage,0,0,$newWidth,$newHeight,$background);
imagealphablending($newImage,true);
imagecopyresampled($newImage,$image,$trim_left,0,0,0,$imageWidth,$imageHeight,$imageWidth,$imageHeight);
//swap the new image
imagedestroy($image);
$image = $newImage;
}
//do something with image
imagepng($image);
//free image
imagedestroy($image);
?>
http://php.net/manual/en/function.imagettftext.php