How to create multiple line-breaks in a dynamic image when needed? - php

Currently I've got the following working just fine without any problems (yet).
header ("Content-type: image/png");
$string = $_REQUEST['text'];
$font = 15;
$width = 300;
$height = 350;
$image = imagecreate($width, $height);
$back = ImageColorAllocate($image, 255, 255, 255);
$border = ImageColorAllocate($image, 0, 0, 0);
ImageFilledRectangle($image, 0, 0, $width, $height, $border);
ImageFilledRectangle($image, 1, 1, $width-2, $height-2, $back);
$text_color = imagecolorallocate($image, 255, 0, 0);
ImageStringWrap($image, $font, 3, 2, $string, $text_color, $width-2 );
imagepng($image);
function ImageStringWrap($image, $font, $x, $y, $text, $color, $maxwidth) {
$fontwidth = ImageFontWidth($font);
$fontheight = ImageFontHeight($font);
if ($maxwidth != NULL) {
$maxcharsperline = floor($maxwidth / $fontwidth);
$text = wordwrap($text, $maxcharsperline, "\n", false);
}
while (list($numl, $line) = each($lines)) {
ImageString($image, $font, $x, $y, $line, $color);
$y += $fontheight;
}
}
While the above works great, one thing I've been failing to work is be able to get line breaks like would come out akin to nl2br().
The text that this is pulling from in $_REQUEST['text'] is from the database, which was originally inserted from a textarea and passed to this script via URL. Naturally when people type in a textarea, there are line breaks that come from that. While printing it to the browser via text is easy, I can't seem to get the same result within an image.
I haven't spend a long time working with the GD library, but after searching around I really can't find anything about how to do this. Is it just not possible?

Related

PHP GD center multiple lines (dynamically text)

Im drawing a dynamically text on a image centersized with GD library.
Whats the best way to align all lines center?
<?php
function imagettfstroketext(&$image, $size, $angle, $x, $y, &$textcolor, &$strokecolor, $fontfile, $text, $px) {
for($c1 = ($x-abs($px)); $c1 <= ($x+abs($px)); $c1++)
for($c2 = ($y-abs($px)); $c2 <= ($y+abs($px)); $c2++)
$bg = imagettftext($image, $size, $angle, $c1, $c2, $strokecolor, $fontfile, $text);
return imagettftext($image, $size, $angle, $x, $y, $textcolor, $fontfile, $text);
}
$image = "12.png";
$font = "./impact.ttf";
$font_size = "50";
$image_2 = imagecreatefrompng($image);
$black = imagecolorallocate($image_2, 255,255,255);
$black2 = imagecolorallocate($image_2, 0,0,0);
$image_width = imagesx($image_2);
$image_height = imagesy($image_2);
$margin = 35;
$text = "This is the Text. It is dynamically long. This text will be split using the function under this text.";
//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] > $image_width - $margin*2){
$text_new .= "\n".$word;
} else {
$text_new .= " ".$word;
}
}
$text_box = imagettfbbox($font_size,0,$font,$text_new);
$text_width = $text_box[2]-$text_box[0]; // lower right corner - lower left corner
$text_height = $text_box[3]-$text_box[1];
$x = ($image_width/2) - ($text_width/2);
$y = ($image_height/2) - ($text_height/2);
$font_color = imagecolorallocate($image_2, 255, 255, 255);
$font_color2 = imagecolorallocate($image_2, 0, 0, 0);
$stroke_color = imagecolorallocate($image_2, 0, 0, 0);
$white = imagecolorallocate($im, 255, 255, 255);
$black = imagecolorallocate($im, 0, 0, 0);
$grey = imagecolorallocate($im, 175, 175, 175);
imagettfstroketext($image_2, $font_size ,0,$x,$y,$font_color, $stroke_color, $font, $text_new, 0);
header ("Content-type: image/png");
imagejpeg($image_2, "../img/output.png");
imagedestroy($image_2);
?>
This is what it looks right now:
This is what it should look like:
Using three times "imagettfstroketext" with adding "$y+50" would do the trick but the text is dynamic.
Any suggestions?
best regards
I would create a temporary image on one line, storing the accumulated length in an array. Then determine exactly which words fit on a line, and the offset to center each line. Then create the image.
Alternatively you can create separate images for each line, then combine them with the right offset.

How to remove reference to ttf file after using imagettftext?

I'm currently developing a captcha system for the site I'm currently developing for a school project.. here: http://rjtestsystem.atwebpages.com/
Here's the code, err, prototype I came up with so far:
<?php
if (isset($_GET['METHOD']) && $_GET['METHOD']=='captcha')
{ session_start();
$code=rand(1000,9999);
$_SESSION["code"] = $code;
session_write_close();
$font = rand(1,4).".ttf";
if ($font == "1.ttf")
$font_size = 20;
else if ($font == "2.ttf")
$font_size = 25;
else if ($font == "3.ttf")
$font_size = 30;
else if ($font == "4.ttf")
$font_size = 35;
$angle = 0;
$width = 120;
$height = 60;
$bounding_box = imagettfbbox($font_size, $angle, $font, $code);
$textwidth = abs($bounding_box[4] - $bounding_box[0]);
$textheight = abs($bounding_box[5] - $bounding_box[1]);
$x = ($width - $textwidth) / 2;
$y = (($height*3/4) + $textheight) / 2;
$image = imagecreatetruecolor($width, $height);
$text_background = imagecolorallocate($image, 0, 0, 0);
$color = imagecolorallocate($image, 230, 230, 230);
imagefill($image, 0, 0, $text_background);
imageline($image, 0, $y-rand(0,10), $width, $y-rand(0,10), $color);
imageline($image, 0, $y, $width, $y, $color);
imageline($image, 0, $y+rand(0,10), $width, $y-rand(0,20), $color);
imageline($image, $x+rand(0,$width/2), 0, $x+rand($width/2,$width), $height, $color);
imageline($image, $x+rand(0,$width/2), $height, $x+rand($width/2,$width), 0, $color);
for($i=0;$i<400;$i++)
{ imagesetpixel($image,rand()%$width,rand()%$height,$color);
}
imagettftext($image, $font_size, $angle, $x, $y, $color, $font, $code);
header("Cache-Control: no-cache, must-revalidate");
header('Content-type: image/png');
imagepng($image);
imagedestroy($image);
exit();
}
?>
<img src = "<?php echo $_SERVER['PHP_SELF']; ?>?METHOD=captcha">
The code seems to be working fine, but when I try to move the files elsewhere, the system would give me a message that the file is being used by another program. It seems that the references to the TTF files are still there even after executing the code. I've tried to look for a way to stop this behavior but I can't seem to get my searches right. Well, the problem goes away once I restart the server, but it's a hassle when debugging. Is there a way or proper method to remove the references / file handle / etc to the TTF files or close this process as soon as it's finished? If possible, I'd like to keep using this code.
I have only a year of experience in Php so please bear with my rudimentary way of coding and asking questions. If anyone can lead me to the right discussions, please do. Thank you.
I'm using WAMP server version 2.4.

Fully looking text when using PHP and imagettftext and angle

for some reason PHP's imagettftext creates a funny looking text when I create the text at an angle.
Below the source code. I can't post the image 'cause I don't have enough reputation points but the text looks like parts of the letters are cut off.
Help!!!
$text = 'My Text Is Messed Up!!!';
$font = './fonts/arial.ttf';
$font_size = 20;
$font_multiplier = 0.5;
$x=10;
$y=190;
$angle=45;
$width= ($font_size * $font_multiplier) * strlen($text);
echo $width;
$height=200;
$size = imageTTFBBox($font_size, $angle, $font, $text);
$img = imageCreateTrueColor($width, $height);
imageSaveAlpha($img, true);
ImageAlphaBlending($img, false);
$transparentColor = imagecolorallocatealpha($img, 200, 200, 200, 127);
imagefill($img, 0, 0, $transparentColor);
$white = imagecolorallocate($img, 255, 255, 255);
// Add the text
imagettftext($img, $font_size, $angle, $x, $y, $white, $font, $text);
// Using imagepng() results in clearer text compared with imagejpeg()
imagepng($img, 'welcome-phrase.png');
imagedestroy($img);
EDIT: here's an example of the output (I changed text colour from white to black to make it visible on the white background - AG):
It seems there is an issue with it rotating each character and leaving a "mask" of sorts that isn't rotated and then obscures the text around it, causing the issue you are seeing. It is more visible when you turn off the transparent image fill.
A workaround could be to rotate the image instead of the text. You will have to fix your coordinates but something like this seems to work:
// Add the text
imagettftext($img, $font_size, 0, $x, $y, $black, $font, $text);
$img = imagerotate($img, $angle, $transparentColor);
imageSaveAlpha($img, true);
ImageAlphaBlending($img, false);
Thus the full code would be:
$text = 'My Text Is Messed Up!!!';
$font = './fonts/arial.ttf';
$font_size = 20;
$font_multiplier = 0.5;
$x=10;
$y=190;
$angle=45.0;
$width = ($font_size * $font_multiplier) * strlen($text);
echo $width;
$height=200;
$size = imageTTFBBox($font_size, $angle, $font, $text);
$img = imageCreateTrueColor($width, $height);
$transparentColor = imagecolorallocatealpha($img, 200, 200, 200, 127);
imagefill($img, 0, 0, $transparentColor);
$white = imagecolorallocate($img, 255, 255, 255);
// Add the text
imagettftext($img, $font_size, 0, $x, $y, $white, $font, $text);
$img = imagerotate($img, $angle, $transparentColor);
imageSaveAlpha($img, true);
ImageAlphaBlending($img, false);
// Using imagepng() results in clearer text compared with imagejpeg()
imagepng($img, 'welcome-phrase.png');
imagedestroy($img);
I moved the imageSaveAlpha and ImageAlphaBlending to the bottom to take care of all that after the rotation has taken place. It's not the best solution but with some tweaking will provide the correct result.

Gd Library Image Style imagettftext

How to make Like This Image?
I just want to learn how do i get output like this using GD library,
Thanks for your help guys..
Here is your code, you could easily find it on google tho.
<?php
header ("Content-type: image/png");
$string = "your text"; // Change this text
$font = 4; // try changing this as well
$width = imagefontwidth($font) * strlen($string) ;
$height = imagefontheight($font) ;
$im = imagecreatefrompng("/path/to/yourimagefile");
$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);
?>
Here's an example:
header('Content-Type: image/png'); // setting the content-type
$file = "yourimage.png";
$image = imagecreatefrompng($file); // creating the image
$font = "YourFont.ttf";
$size = 15; //pixels
$color = imagecolorallocate($image, 255, 255, 255); //white color
$text = "Your text here"
imagettftext($image, 15, 0, 20, 40, $color, $font, $code); // adding the text
imagepng($image); // outputting the image
For more see imagettftext().
EDIT: An example of using multiple imagettftext():
header('Content-Type: image/png'); // setting the content-type
$file = "yourimage.png";
$image = imagecreatefrompng($file); // creating the image
$font = "YourFont.ttf";
$size = 15; //pixels
$color = imagecolorallocate($image, 255, 255, 255); //white color
$text = "Your text here"
imagettftext($image, 15, 0, 20, 40, $color, $font, $code); // adding the text
$text = "Text 2";
imagettftext($image, 15, 0, 25, 45, $color, $font, $code); // adding the text
$text = "Text 3";
imagettftext($image, 15, 0, 30, 50, $color, $font, $code); // adding the text
imagepng($image); // outputting the image

how to generate multiple texts using php

How can i generate multiple texts using the imagecreatetruecolor() method? I have the following code, but this displays either the first font or the second - not both:
<?php
// Set the content-type
header('Content-type: image/png');
// The text to draw
$text = 'Hello Farooqi';
$x = 0;
$y = 0;
$w = 50;
$h = 50;
$s = 13;
// Create the image
$im = imagecreatetruecolor($w , $s);
imagesavealpha($im, true);
// Create some colors
$white = imagecolorallocate($im, 255, 255, 255);
$black = imagecolorallocate($im,0,0,0);
$text_color = imagecolorallocate($im, 200,200, 91);
$blue = imagecolorallocate($im,0,0,180);
$alpha = imagecolorallocatealpha($im, 0, 0, 0, 127);
//imagefilledrectangle($im, 0, 0, 150, 25, $black);
imagefill($im, 0, 0, $alpha);
// Replace path by your own font path
$font = 'Calibri Bold.ttf';
// Add the text
$dimensions = imagettftext($im, $s, 0, $x, $y, $black, $font, $text);
$textWidth = ($dimensions[2]);
$imm = imagecreatetruecolor($w , $s);
imagesavealpha($imm, true);
$bluem = imagecolorallocate($imm,50,50,50);
$alpham = imagecolorallocatealpha($imm, 0, 0, 0, 127);
imagefill($imm, 0, 0, $alpham);
imagettftext($imm, $s, 0, $x+3, $y+3, $bluem, $font, $text);
// Using imagepng() results in clearer text compared with imagejpeg()
imagepng($im);
imagepng($imm);
imagedestroy($im);
imagedestroy($imm);
?>
Here above in these last 4 lines only one line appears, and that's the first one. How can I have both lines?
Please help. Thanks in advance.
The imagepng($im); will be called and outputted to your HTML code and as the header is set to an image it will display this image. No matter your imagepng($inm) that comes afterwards.
A better way would be to create two different PHP files. One that does your script and ends in imagepng($im); and another one that ends in imagepng($inm);
And then in your master PHP (header = text/html) file you just mention these 2 files in your image source:
<img src="functions/first_image.php" />
<img src="functions/second_image.php" />

Categories