I am working with my little project which need the following:
There must be a text at the front of image.
The text is on centered.
My code follows the instruction but i want to change the font family of the text..
ImageString($background, $font_size, $position_center, $position_middle, $text, $textcolor);
Here is my full code:
header('Content-type: image/png');
$background1 = "files/bg.png";
$background = imagecreatefrompng($background1);
$width = 630;
$height = 315;
$text = "EXAMPLE TEXT";
$font_size = 50;
$font_family = "files/tahoma.ttf";
$font_width = ImageFontWidth($font_size);
$font_height = ImageFontHeight($font_size);
$text_width = $font_width * strlen($text);
$position_center = ceil(($width - $text_width) / 2); //CENTER THE TEXT
$text_height = $font_height;
$position_middle = ceil(($height - $text_height) / 2); // MIDDLE THE TEXT
$textcolor = ImageColorAllocate($background, 255, 255, 255);
$image_string = ImageString($background, $font_size, $position_center, $position_middle, $text, $textcolor);
imagepng($background);
imagedestroy($background);
Have a look at the last 2 statements, $image_string is not used.
imagettftext can be used to write text to an image using a TrueType font.
The position parameters for the functino refers to the left edge, to get it centered you need to calculate the correct coordinates, take a look at this php.net comment for how to do it: http://no2.php.net/manual/en/function.imagettftext.php#83248
Related
I have a script that is writing a text over an image.
It works fine, but the text is aligned to the left.
I am trying to center the text horizontally, but not sure how can I do that.
Here is the code that I have at the moment
//content type
header('Content-Type: image/png');
if (isset($_GET['text'])){$text = $_GET['text'];}else{$text = "";}
//font
$font = 'Ubuntu-Medium.ttf';
//font size
$font_size = 18;
//image width
$width = 400;
//text margin
$margin = 90;
//explode text by words
$text_a = explode(' ', $text);
$text_new = '';
foreach($text_a as $word){
//Create a new text, add the word, and calculate the parameters of the text
$box = imagettfbbox($font_size, 0, $font, $text_new.' '.$word);
//if the line fits to the specified width, then add the word with a space, if not then add word with new line
if($box[2] > $width - $margin*2){
$text_new .= "\n".$word;
} else {
$text_new .= " ".$word;
}
}
//trip spaces
$text_new = trim($text_new);
//new text box parameters
$box = imagettfbbox($font_size, 0, $font, $text_new);
//new text height
$height = $box[1] + $font_size + $margin * 2;
//create image
$im = imagecreatefromjpeg('source.jpg');
//create colors
$white = imagecolorallocate($im, 255, 255, 255);
$black = imagecolorallocate($im, 51, 95, 32);
//color image
imagefilledrectangle($im, 0, 0, $width, $black);
// determine the size of the text so we can center it
$box = imagettfbbox($font_size, 0, $font, $text_new);
$text_width = abs($box[2]) - abs($box[0]);
$text_height = abs($box[5]) - abs($box[3]);
$image_width = imagesx($im);
$image_height = imagesy($im);
$x = ($image_width - $text_width) / 2;
$y = ($image_height + $text_height) / 2;
//add text to image
imagettftext($im, $font_size, 0, $x, $y, $black, $font, $text_new);
//return image
imagepng($im);
//frees any memory associated with image
imagedestroy($im);
Any ideas on how can I center the text?
I already centered the box that the text is placed, so the box is in the center of the image. The problem is that the text is aligned left and I need it in the center.
I want to add a text to a image. The text should be displayed in multiple areas of the image (not just one).
For example I want to watermark with a text stack. Stack should be displayed in the image at least 8 times in different areas in the image.
I just learned about imagestring() and imagettftext(), but these two only displays my text on a single spot.
Image is not fixed size, so i cannot specify exact and multiple location in advance. It should work on all sizes of images
<?php
/*
image.php
*/
header("Content-type: image/jpeg");
$imgPath = 'olximage.jpg';
$image = imagecreatefromjpeg($imgPath);
$color = imagecolorallocate($image, 255, 255, 255);
$string = "stack overflow";
$fontSize = 3;
$x = 15;
$y = 185;
imagestring($image, $fontSize, $x, $y, $string, $color);
$x = 15;
$y = 175;
imagestring($image, $fontSize, $x, $y, $string, $color);
imagejpeg($image);
?>
Thanks in advance
For example:
<?php
/*
image.php
*/
header("Content-type: image/jpeg");
$imgPath = 'olximage.jpg';
$image = imagecreatefromjpeg($imgPath);
$color = imagecolorallocate($image, 255, 255, 255);
$string = "stack overflow";
$fontSize = 3;
$imageHeight = imagesy($image);
$distanceY = 10;
$maxImageStrings = max(8, $imageHeight / $distanceY);
$x = 15;
for ($i = 0; $i < $maxImageStrings; $i++) {
$y = $i * $distanceY;
imagestring($image, $fontSize, $x, $y, $string, $color);
}
imagejpeg($image);
You can finetune calculations for your needs.
I'm using Imagick extension for same. If you want to go with this then follow detail:
PHP:
// Create objects
$image = new Imagick('image.png');
$watermark = new Imagick();
// Watermark text
$text = 'Copyright';
// Create a new drawing palette
$draw = new ImagickDraw();
$watermark->newImage(140, 80, new ImagickPixel('none'));
// Set font properties
$draw->setFont('Arial');
$draw->setFillColor('grey');
$draw->setFillOpacity(.5);
// Position text at the top left of the watermark
$draw->setGravity(Imagick::GRAVITY_NORTHWEST);
// Draw text on the watermark
$watermark->annotateImage($draw, 10, 10, 0, $text);
// Position text at the bottom right of the watermark
$draw->setGravity(Imagick::GRAVITY_SOUTHEAST);
// Draw text on the watermark
$watermark->annotateImage($draw, 5, 15, 0, $text);
// Repeatedly overlay watermark on image
for ($w = 0; $w < $image->getImageWidth(); $w += 140) {
for ($h = 0; $h < $image->getImageHeight(); $h += 80) {
$image->compositeImage($watermark, Imagick::COMPOSITE_OVER, $w, $h);
}
}
// Set output image format
$image->setImageFormat('png');
// Output the new image
header('Content-type: image/png');
echo $image;
although there are plenty of command-line examples to be found on the ImageMagick website, so that is where we shall begin.
I'm creating images with different sizes. How can I write text on those images so that the texts always fit to the images?
$text = "some text as example";
$font = "arialbd.ttf"
$fontsize = 26;
offset_x = 0;
offset_y = 0;
$image01 = imagecreate( 1120 , 900 );
$image02 = imagecreate( 400 , 300 );
$image03 = imagecreate( 1120 , 900 );
I know that there is the imagefttext function that can apply text to the images but with that function I can only change the font size to make the text bigger. How can I find out that it fits into my image?
If you are looking to scale the font size so that text string fills the image width, try this.
Using imagettfbbox, determine the current text box width:
$bbox = imagettfbbox($fontsize,0,$fontpath,$string);
$tbwidth = $bbox[2];
Then divide the image width by the $tbwidth to get a factor
$factor = round(($imgwidth / $tbwidth), 0, PHP_ROUND_HALF_DOWN); //ie. 800/240=3
Multiple the $factor by you $fontsize to get an approximate increase.
$newfontsize = $fontsize * $factor; //ie. 12(pt) * 3 = 36
Keep in minds, if you're using GD 2.0, fontsize is in Points and not pixels. Your algorithm is going to calculate the difference between your default font size text box (expressed as a text box width) and the image width.
// Set the content-type
header('Content-Type: image/png');
// Create the image
$im = imagecreatetruecolor(800, 600);
// Create some colors
$white = imagecolorallocate($im, 255, 255, 255);
$grey = imagecolorallocate($im, 128, 128, 128);
$black = imagecolorallocate($im, 0, 0, 0);
imagefill($im, 0, 0, $white);
// The text to draw
$text = 'Testing...';
// Replace path by your own font path
$font_file = 'arial.ttf';
$font_size = '15';
$bbox = imageftbbox($font_size, 0, $font_file, $text);
$width = $bbox[2] - $bbox[6];
$height = $bbox[3] - $bbox[7];
// Add the text
imagettftext($im, $font_size, 0, 10, 20, $black, $font_file, $text);
// Using imagepng() results in clearer text compared with imagejpeg()
imagepng($im);
imagedestroy($im);
I recently came across the same situation with transparent backgrounds but the current examples are either not a solution but clues or a solution that doesn't work, so hereby a combined and working solution if anyone need it.
function imagecreater($width = 600, $height = 600) {
//Create an empty transparent image
$img = imagecreatetruecolor($width, $height);
imagealphablending($img, false);
imagesavealpha($img, true);
$transparent = imagecolorallocatealpha($img, 255, 255, 255, 127);
imagefill($img, 0, 0, $transparent);
//Text information
$text = "some text as example";
$font = "arialbd.ttf"
$fontsize = 26; //default font to be altered later
//simulate a complete text box and get the width
$bbox = imageftbbox($fontsize, 0, $font, $text);
$tbwidth = $bbox[2];
//Calculate different between our transparent image and text box
//I've added a little padding (20px) since the text sometimes crossing the edge..
$factor = (($width - 20) / $tbwidth);
//Alter font size with difference to fit fully image
$newfontsize = $fontsize * $factor;
//Find the horisontal center
$bbox = imageftbbox($newfontsize, 0, $font, $text);
$newheight = ($height / 2) + (($bbox[3] - $bbox[7]) / 2);
//Set Color of text
$color = imagecolorallocate($img, 200, 0, 0);
//Produce our image
imagettftext($img, $newfontsize, 0, 0, $newheight, $color, $font, $text);
//Copy image to file and free the cached image
$target = "testimage.png";
imagepng($img, $target);
imagedestroy($img);
}
As rwhite35 mentioning here, please keep in mind that GD 2.0 write font size is in points and not pixels.
Use the imageftbbox function to get the size of the bounding box of the text. You can then adjust the text size to fit the size of the image exactly.
http://www.php.net/manual/en/function.imageftbbox.php
My goal is to draw a horizontally centered m. I therefore calculate the width of the letter, substract that value from the total width and finally divide by 2. The result should be the distance from the left (or equally from the right).
However, the 'm' is always misplaced. I also noticed that some fonts may not trigger the problematic behavior. Note that my script correctly works for all other latin characters.
Arial:
Bitstream Vera Sans:
<?php
$totalWidth = 100;
$totalHeight = 100;
$font = 'Arial.ttf';
$img = imagecreatetruecolor($totalWidth, $totalHeight);
$red = imagecolorallocate($img, 255, 0, 0);
$fontSize = 100;
$bbox = imagettfbbox($fontSize, 0, $font, 'm');
$width = max($bbox[2], $bbox[4]) - max($bbox[0], $bbox[6]);
$centeredX = ($totalWidth - $width) / 2;
imagettftext($img, 100, 0, $centeredX, 100, $red, $font, 'm');
imagepng($img, 'testcase.png');
imagedestroy($img);
There is a small space left of each letter, and this is different each letter. Somebody on PHP.net wrote a solution for this: http://www.php.net/manual/en/function.imagettfbbox.php#97357
You need to adjust your code a little bit.
$totalWidth = 100;
$totalHeight = 100;
$font = 'Arial.ttf';
// change letter to see it with different letters
$letter = "m";
$img = imagecreatetruecolor($totalWidth, $totalHeight);
$red = imagecolorallocate($img, 255, 0, 0);
$fontSize = 100;
$bbox = calculateTextBox($fontSize, 0, $font, $letter);
$centeredX = (($totalWidth - $bbox['width']) / 2);
// here left coordinate is subtracted (+ negative value) from centeredX
imagettftext($img, 100, 0, $centeredX + $bbox['left'], 100, $red, $font, $letter);
header('Content-Type: image/png');
imagepng($img);
imagedestroy($img);
I'm trying to use the following PHP in order to apply randomly generated text files to an image. (I'm just using a random image right now.)
<?php
header ("Content-type: image/png");
$textfile = "quote.txt";
$quotes = array();
if(file_exists($textfile)){
$quotes = file($textfile);
srand ((float) microtime() * 10000000);
$string = $quotes[array_rand($quotes)];
$string = substr($string,0,strlen($string)-1);
}
else{
$string = "No 'Quote' available at this time.";
}
//$string = "your text";
// try changing this as well
$font = 4;
$width = imagefontwidth($font) * strlen($string) ;
$height = imagefontheight($font) ;
$im = imagecreatefrompng("test.png");
$x = imagesx($im) - $width ;
$y = imagesy($im) - $height;
$backgroundColor = imagecolorallocate ($im, 255, 255, 255);
$textColor = imagecolorallocate ($im, 0, 0,0);
imagestring ($im, $font, $x, $y, $string, $textColor);
imagepng($im);
ImageDestroy($im);
?>
However, when I run that code the imported image just becomes very blockish.
Here is the image I am testing with:
http://i.stack.imgur.com/LhNkv.png
And here is how it actually appears:
http://i.stack.imgur.com/AAcHZ.png
My research shows that "imagecreate" generates a "palette" image - and I thought that might have something to do with my error, but I have seen plenty of examples where the base image is by no means distorted.
Thanks in advance for your insights.
(Ugh. It wouldn't let me post images but let me upload them just fine?)
Update
Changing the code to:
<?php
header ("Content-type: image/png");
$textfile = "quote.txt";
$quotes = array();
if(file_exists($textfile)){
$quotes = file($textfile);
srand ((float) microtime() * 10000000);
$string = $quotes[array_rand($quotes)];
$string = substr($string,0,strlen($string)-1);
}
else{
$string = "No 'Quote' available at this time.";
}
//$string = "your text";
// try changing this as well
$font = 4;
$width = imagefontwidth($font) * strlen($string) ;
$height = imagefontheight($font) ;
$im = imagecreatefrompng("test.png");
//$x = imagesx($im) - $width ;
//$y = imagesy($im) - $height;
//$backgroundColor = imagecolorallocate ($im, 255, 255, 255);
//$textColor = imagecolorallocate ($im, 0, 0,0);
//imagestring ($im, $font, $x, $y, $string, $textColor);
imagepng($im);
ImageDestroy($im);
?>
Produces the same block-like effects as above, except now no text is being written to the image, either (obviously?).
Could be an alpha blending problem. Try adding these before saving the image:
imagealphablending($im, true);
imagesavealpha($im, true);