Link to home
Start Free TrialLog in
Avatar of dwebber
dwebber

asked on

Changes to an existing php script that writes text onto an image

I have a simple script (written by another) at
http://209.240.138.105//test/index.php

that writes numbers onto a png image using another php file, which I have added a .txt file extension to so you can see it at...
http://209.240.138.105/test/write-to-image.php.txt

What I'd like is to have the script edited so that there are eight online input forms like the one in the example above, but allowing text and numbers to be input.
 
In addition, for each of the eight input forms, the script (not the input form itself that appears online) should also contain variables allowing me to dictate the text font, size, color and XY coordinates of the output for each of the eight input forms.
 
 
Just to be clear, I DON'T want an online user to have to select the text font, size, color and XY coordinates. I just want them in the script, so I can change them later.
 
Please add any comments into the script code that you think of that will help me later edit it.

Avatar of dwebber
dwebber

ASKER

A commenter in the past who didn't have the time to write out the script suggested the following which is over my head. If someone can make changes to the script that will do what I want and post a new version of the code for both of the files shown in the original question, that would be great!



Change
 your form to have several inputs
 

<?
php 
foreach
 
(
range
(
0
,
 
10
)
 
as
 $num
):
 
?>

  
<
input type
=
"text"
 name
=
"text[<?php echo $num ?>]"
 id
=
"text_<?php echo $num ?>"
 
/>


<?
php endforeach 
?>

 

Then
 
in
 your image generating file
:

 

<?
php
 

function
 putTextOnImage
(
$image
,
 $font_color
,
 $font_file
,
 $font_size
,
 $xPos
,
 $yPos
,
 $text
)


{

  $font_rgb 
=
 hex_to_rgb
(
$font_color
)
 
;

  $box 
=
 
@ImageTTFBBox
(
$font_size
,
0
,
$font_file
,
$text
)
 
;

 
  $text_width 
=
 abs
(
$box
[
2
]-
$box
[
0
]);

  $text_height 
=
 abs
(
$box
[
5
]-
$box
[
3
]);

  
// allocate colors and measure final text position

 
  $font_color 
=
 
ImageColorAllocate
(
$image
,
$font_rgb
[
'red'
],
$font_rgb
[
'green'
],
$font_rgb
[
'blue'
])
 
;

  $image_width 
=
 imagesx
(
$image
);

 
  $xPos 
=
 $xPos 
*
 imagesx
(
$image
);

  $ypos 
=
 $yPos 
*
 imagesy
(
$image
);

 
  
return
 imagettftext
(
$image
,
 $font_size
,
 
0
,
 $xPos
,
 $yPos
,
 $font_color
,
 $font_file
,
 $text
);


}

 
putTextOnImage
(
$image
,
 
'#ff4400'
,
 
'file.ttf'
,
 
100
,
 
0
.
1
,
 
0
.
1
,
 $_GET
[
'text'
][
0
]);

putTextOnImage
(
$image
,
 
'#004400'
,
 
'file.ttf'
,
 
10
,
  
0
.
5
,
 
0
.
1
,
 $_GET
[
'text'
][
1
]);

putTextOnImage
(
$image
,
 
'#ff44ff'
,
 
'file.ttf'
,
 
90
,
  
0
.
1
,
 
0
.
5
,
 $_GET
[
'text'
][
2
]);

putTextOnImage
(
$image
,
 
'#555555'
,
 
'file.ttf'
,
 
40
,
  
0
.
8
,
 
0
.
8
,
 $_GET
[
'text'
][
3
]);


// etc

Open in new window

Avatar of AlexanderR
This was a LONG one.

Make sure there is not a single space after the last ; sign in write-to-image.php or else the binary for the image breaks.

Also, this form is rather big and GET has a limit to it.  If not all data from form is being carried into image, will have to switch to POST instead (will require more changes).
//Save this as class.WriteToImage.php
 
<?php
class WriteToImage {
	private $image;
	
	public function __construct($image_file){
		if (! function_exists ( 'ImageCreate' ))
			$this->fatal_error ( 'Error: Server does not support PHP image generation' );
		$this->image = imagecreatefrompng($image_file);
	}
	
	public function putTextOnImage($font_file, $font_size, $font_color, $x_pos, $y_pos, $text){
		if (! is_readable ( $font_file )) {
			$this->fatal_error ( 'Error: The server is missing the specified font: '.$font_file );
		}
		// create and measure the text
		$font_rgb = $this->hex_to_rgb($font_color);
		$box = ImageTTFBBox ( $font_size, 0, $font_file, $text );
		$text_width = abs ( $box [2] - $box [0] );
		$text_height = abs ( $box [5] - $box [3] );
		
		if (! $this->image || ! $box) 
		{
			fatal_error ( 'Error: The server could not create this image.' );
		}
		// allocate colors and measure final text position
		$font_color = ImageColorAllocate ( $this->image, $font_rgb['red'], $font_rgb['green'], $font_rgb['blue'] );
		$image_width = imagesx ( $this->image );
		$put_text_x = $image_width - $text_width - ($image_width - $x_pos);
		$put_text_y = $y_pos;
		// Write the text
		 imagettftext ( $this->image, $font_size, 0, $put_text_x, $put_text_y, $font_color, $font_file, $text );
	}
	
	private function hex_to_rgb($hex) {
		// remove '#'
		if (substr ( $hex, 0, 1 ) == '#')
			$hex = substr ( $hex, 1 );
		// expand short form ('fff') color to long form ('ffffff')
		if (strlen ( $hex ) == 3) {
			$hex = substr ( $hex, 0, 1 ) . substr ( $hex, 0, 1 ) . 
			substr ( $hex, 1, 1 ) . substr ( $hex, 1, 1 ) . 
			substr ( $hex, 2, 1 ) . substr ( $hex, 2, 1 );
		}
		if (strlen ( $hex ) != 6)
			fatal_error ( 'Error: Invalid color "' . $hex . '"' );
		// convert from hexidecimal number systems
		$rgb ['red'] = hexdec ( substr ( $hex, 0, 2 ) );
		$rgb ['green'] = hexdec ( substr ( $hex, 2, 2 ) );
		$rgb ['blue'] = hexdec ( substr ( $hex, 4, 2 ) );
		return $rgb;
	}
	
	public function displayImage(){
		header ( 'Content-type: image/png');
		ImagePNG ( $this->image );
		ImageDestroy ( $this->image );
	}
	
	private function fatal_error($message) 
	{
		// send an image
		if (function_exists ( 'ImageCreate' )) 
		{
			$width = ImageFontWidth ( 5 ) * strlen ( $message ) + 10;
			$height = ImageFontHeight ( 5 ) + 10;
			if ($this->image = ImageCreate ( $width, $height )) 
			{
				$background = ImageColorAllocate ( $this->image, 255, 255, 255 );
				$text_color = ImageColorAllocate ( $this->image, 0, 0, 0 );
				ImageString ( $this->image, 5, 5, 5, $message, $text_color );
				header ( 'Content-type: image/png' );
				ImagePNG ( $this->image );
				ImageDestroy ( $this->image );
				exit ();
			}
		
		}
		// send 500 code
		header ( "HTTP/1.0 500 Internal Server Error" );
		print ( $message );
		exit ();
	}
}
?>
 
 
//save this as write-to-image.php
<?php 
include('class.WriteToImage.php');
// you can edit any of these
$text1 = $_GET['text1'];
$text2 = $_GET['text2'];
$text3 = $_GET['text3'];
$text4 = $_GET['text4'];
$text5 = $_GET['text5'];
$text6 = $_GET['text6'];
$text7 = $_GET['text7'];
$text8 = $_GET['text8'];
 
// tell the file name of the image to work on
$display_image = new WriteToImage('jump_empty.png');
 
// make as much of these as you want. Make sure you include font file name.
// FontFileName, FontSize, FontColor, X Position, Y Position, Text from the form or your own text in quotes.
$display_image->putTextOnImage('ambient.ttf',23,'#ffffff',127,103, $text1);
$display_image->putTextOnImage('ambient.ttf',23,'#ffffff',227,107, $text2);
$display_image->putTextOnImage('ambient.ttf',23,'#ffffff',227,110, $text3);
$display_image->putTextOnImage('ambient.ttf',23,'#ffffff',227,115, $text4);
$display_image->putTextOnImage('ambient.ttf',23,'#ffffff',227,120, $text5);
$display_image->putTextOnImage('ambient.ttf',23,'#ffffff',227,125, $text6);
$display_image->putTextOnImage('ambient.ttf',23,'#ffffff',227,130, $text7);
$display_image->putTextOnImage('ambient.ttf',23,'#ffffff',427,157, $text8);
 
 
// give final image to browser
$display_image->displayImage();
 
 
 
// and this is your form
<style>
body {margin:0; font-family:garamond; background:#FFFFFF}
table {background:white; font-size:14px}
form {display:inline}
 
</style>
 
 
<br>
<br>
<br>
<br>
<br>
<br>
<script>
function CreateSign() {
var text1 = document.textform.imtext1.value;
var text2 = document.textform.imtext2.value;
var text3 = document.textform.imtext3.value;
var text4 = document.textform.imtext4.value;
var text5 = document.textform.imtext5.value;
var text6 = document.textform.imtext6.value;
var text7 = document.textform.imtext7.value;
var text8 = document.textform.imtext8.value;
document['simage'].src='write-to-image.php?text1='+text1+'&text2='+text2+'&text3='+text3+'&text4='+text4+'&text5='+text5+'&text6='+text6+'&text7='+text7+'&text8='+text8
}
</script>
 
<center>
<form name=textform>
        <input type=text name=imtext1>
        <input type=text name=imtext2>
        <input type=text name=imtext3>
        <input type=text name=imtext4>
        <input type=text name=imtext5>
        <input type=text name=imtext6>
        <input type=text name=imtext7>
        <input type=text name=imtext8>
        <input type=button value='Show Image' onClick="CreateSign();" \>
 
</form><br /><br>
<br>
 
 
<img src="write-to-image.php?text=0.0" name=simage>
<br>
<br>
 
 
 
</center>
 
 
<title>Sign Builder</title>  

Open in new window

Avatar of dwebber

ASKER

I replaced the old write-to-image.php file with your WriteToImage.php file and made sure the index.php file now calls this new file and it doesn't work at all : (
No, no.
There are 3 files.  class.WriteToImage.php , write-to-image.php and   form.php
Avatar of dwebber

ASKER

Oops, let me go back and retest. I thought the whole thing was one file - Sorry
Avatar of dwebber

ASKER

I did exactly as you said and created three files named as you stated above and the image no longer appears even though there are no spaces.

I can add.txt extensions to the files if you want to view them
Yes, add phps extension to them, please.  (most web setups have phps enabled which is better for viewing source code)

Also, compare what you have with my setup:
http://65.75.100.169/
Avatar of dwebber

ASKER

They all have the .txt extension and I'll take a look at yours as well. I noticed that yours works except that nothing in any of the inputs appears on the image. I know it's probably because the xy coordinates are not set but if we can get this to work  on my server it would help alot to see that it writes all 8 inputs onto the image : )

Nothing appears on the image?  That can't be because i tested it all prior to showing the code to you.  Its most likely because my upload speed is terrible, so you have to give it some time.  Try again, please while i will look at your code.
Avatar of dwebber

ASKER

You were right, it was the upload speed on your site. Now if we can get it to work on mine, we're done : )
I think i see your problem.  If you browse directly to the file you get
Parse error: syntax error, unexpected T_STRING, expecting T_OLD_FUNCTION or T_FUNCTION or T_VAR or '}' in /usr3/home/buyontv.com/htdocs/test/class.WriteToImage.php on line 3

so you may have made a copy/paste mistake somewhere.  BTW,  there should not beanything to change in class file.  All options that you've asked for can be changed through write-to-text.php  
Avatar of dwebber

ASKER

I'll go back and look at that file again
Avatar of dwebber

ASKER

I just upload the class.WriteToImage.php again and still the image doesn't appear. Does it have to do with a chmod setting or something?
what version of php are you on? 4 or 5?
Avatar of dwebber

ASKER

Funny you asked because I emailed my hosting service and they said 5. They said  a script writer might be assuming 4
This is so strange!!!

it says there is an error at around where i have
private $image;
I know that php4 does not support OOP.

Just to be sure that the hosting support is corret, create another file with
<?php
phpinfo();
?>
in it and see what the version is.

Also, your http://209.240.138.105/test/write-to-image.php.txt points to the old code.  Can you update that please.
Avatar of dwebber

ASKER

RE: Also, your http://209.240.138.105/test/write-to-image.php.txt points to the old code.  Can you update that please.

If you've had that open without refreshing, it was changed much earlier. I just checked it again : )


Go here to check php
http://209.240.138.105/test/testphp.php
Well of course it wouldn't work!! Its php 4.4.7 (that is OLD), while your technical support promissed you php 5.  PHP 4 does not support the type of syntax i am using.

3 things can be done.
1) find out why your account is on php 4 while you are promissed 5.  This could be as simple as switching it in your account configs. (Godaddy does this.  They give you php4 by deafault and if you want 5 you have to change the interpreter in .htaccess.  Email your host for more info)
2) try another host, if not perminently but just so that you can get this thing to work.  Try http://byethost.com/
3) i can ATTEMPT to rewrite this in php4 style but i am not really sure, + i will have no way to test.
Avatar of dwebber

ASKER

Alexander, I misspoke, here is what my hosting company emailed me when I was trying to install a similar script I gave up on two weeks ago. It's all Greek to me but maybe it will help you figure out what's occurring with regard to the php version




I took a look at the phpinfo() function that will display all of the
included libraries for PHP4, which appears to be the version you are using
by default.  I did find the "gd" library which included "Freetype".  Doing a
search for TTF support with PHP, it appears most functions are already
included with the "gd" library, it looks like a similar thing is true of the
XPM functions.

I would suggest you try changing the OnClick to point to "newimage.php5"
instead of "newimage.php".  This will force version 5 to load instead of 4,
my guess is anyone that's written or worked on these scripts is assuming
you're running version 5.  
Avatar of dwebber

ASKER

Here's what else my hosting company says in the developer section after I log into my account...


TierraNet currently has both PHP versions 5.0.3, 4.3.10 and 3.0.18.
The "CGI redirect" version of PHP is installed.
PHP files should end with the extension .php5, .php3 or .php to use the appropriate version of PHP.
PHP files should be placed with your web documents; not in your /cgi-bin directory.
GIF creation via PHP is supported and permitted.

For advanced users who wish to have different extensions handled as PHP scripts, this can be added to a .htaccess file.
AddType application/x-httpd-php4 .html
or
AddType application/x-httpd-php5 .htm
Alright. This is good info, thanks.
2 options.  I suggest #2 since it will save you future headaches, but it will require carefull editing of your .htaccess file.  If unsure do #1 (but not both together).

Option #1.
Rename all of your files to   .php5
+ these changes
1)  in form.php
document['simage'].src='write-to-image.php?text1='+text1+'&text2='+text2+'&text3='+text3+'&text4='+text4+'&text5='+text5+'&text6='+text6+'&text7='+tex

to

document['simage'].src='write-to-image.php5?text1='+text1+'&text2='+text2+'&text3='+text3+'&text4='+text4+'&text5='+text5+'&text6='+text6+'&text7='+tex

2) in write-to-image.php
include('class.WriteToImage.php');
to
include('class.WriteToImage.php5');

Option #2
in your .htaccess (please back it up first)
find anything that looks like
AddType application/x-httpd-php ..........
and change it to
AddType application/x-httpd-php5 .php
AddType application/x-httpd-php4 .php4
Avatar of dwebber

ASKER

OK, I'll work on it now (option 2) and report back asap : )
Avatar of dwebber

ASKER

Actually, I'm going to use option 1 to wrap this up since I couldn't find my htaccess file (I have an email in to my hosting service). I'll save these instruction and switch to option 2 later.

I'll let you know how option 1 works in a few minutes : )
if its not there you can just create it :)
Avatar of dwebber

ASKER

Still doesn't work. I have a txt version of all the new php5 files with the changes in two of them, as well.

I'm going to email this thread to my hosting company and see what's wrong. Maybe something's not right in my hosting account : (

You've spent alot of time on this already. Let's maybe wait to hear what my hosting company says. They have historically been excellent and then we can resume. It appears to be something very minor at this point since it works for you.
@DWebber: I've been lurking here.  Is your host by any chance GoDaddy?

In any case, you will probably find that they have a simple .htaccess file you can use to get PHP5.

Best, ~Ray
class.WriteToImage.php5

has a space at the end: take it out.  (the output is almost as expected!!)
Avatar of dwebber

ASKER

I'm using Tierra.net
Avatar of dwebber

ASKER

I took the space out and still no luck on the image appearing : (
Roger that.  I've bumped up against this at GoDaddy.  But Tierra is probably different.

Over and out, ~Ray
Yes it does!! i just tested it...
Oh, you are probably looking at the default default state.  Thats one thing i over looked in JavaScript

in form.php5
change

to
Avatar of dwebber

ASKER

??. I took the space out and just rechecked. You got it to work on my server?
ASKER CERTIFIED SOLUTION
Avatar of AlexanderR
AlexanderR
Flag of Canada image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of dwebber

ASKER


This last change of yours did the trick!!!

in form.php5
change

to




You're the man!!

Soon as I submit this comment, I'm going back to pdf the thread and hit accept solution - Thank you for sticking it out with me!!!!!!!!


Avatar of dwebber

ASKER

EXCELLENT FOLLOW THROUGH!
This was one hot question.  I had fun.  True accept should have really been my first comment, but whatever; you got it working at last.
Avatar of dwebber

ASKER

Thank you again. Many would have given up. In fact, in the past they did. This was my third post on the same script. I had to cancel the others after "experts" gave up and repost. I'm thrilled you came through!
Avatar of dwebber

ASKER

Alexander, I forgot to ask and just realized after putting this aside for awhile, that all the outputs write right to left. What changes to the script will write the outputs centered (preferable, if possible) otherwise I need them to write out from left to right.

Thanks and last question, promise
Sorry, i don't relly understand the problem.

The position of the text is controlled by 4th and 5th parameter in
$display_image->putTextOnImage('ambient.ttf',23,'#ffffff',127,103, $text1);
each of those lines found in write-to-image.php are completely independent of each other. Just change 4th and 5th parameters in whichever one and they will be exactly where you want them.
Avatar of dwebber

ASKER

Thanks Alexander. Yes I understand this, but wherever the XY coordinates are placed to start at, once the text is input into the form, the text starts writing onto the image going from right to left (aligns to the right) instead of writing out from left to right (align to the left) which is more normal.

Seems like no more that five or so characters would need to be changed in the script to make it write out text on the image starting from the left side going right.

It would be even better if it just centered the output starting at the XY coordinate used in the script.

Thanks Alexander
Well, this is a completely separate issue, due to the way imagettftext works, but i'll let is slide this time, since its only one short line ;)

Add
$text_width = $text_width / 2;
after line 27
so your putTextOnImage method in class.WriteToImage.php looks like
public function putTextOnImage($font_file, $font_size, $font_color, $x_pos, $y_pos, $text){
		if (! is_readable ( $font_file )) {
			$this->fatal_error ( 'Error: The server is missing the specified font: '.$font_file );
		}
		// create and measure the text
		$font_rgb = $this->hex_to_rgb($font_color);
		$box = ImageTTFBBox ( $font_size, 0, $font_file, $text );
		$text_width = abs ( $box [2] - $box [0] );
		$text_height = abs ( $box [5] - $box [3] );
		
		if (! $this->image || ! $box) 
		{
			fatal_error ( 'Error: The server could not create this image.' );
		}
		// allocate colors and measure final text position
		$font_color = ImageColorAllocate ( $this->image, $font_rgb['red'], $font_rgb['green'], $font_rgb['blue'] );
		$image_width = imagesx ( $this->image );
		$text_width = $text_width / 2;
		$put_text_x = $image_width - $text_width - ($image_width - $x_pos);
		$put_text_y = $y_pos;
		// Write the text
		 imagettftext ( $this->image, $font_size, 0, $put_text_x, $put_text_y, $font_color, $font_file, $text );
	}

Open in new window

Avatar of dwebber

ASKER

That did it, man YOU ARE GOOD!!!

Thank you!!!