note 104239 modified in function.imagettftext by danbrown

From: 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

« previous php.notes (#180209) next »