Image generating problem with PHP form a class - php

i wrote this code:
class Generate{
private $canvas;
function __construct($width, $height){
$this->canvas = imagecreatetruecolor($width, $height);
}
public function bg($r=0,$g=0,$b=0){
$color = imagecolorallocate($this->canvas, $r, $g, $b);
imagefill($this->canvas, 0, 0, $color);
}
public function gen(){
header('Content-Type: image/png');
imagepng($this->canvas, NULL, 9);
imagedestroy($this->canvas);
}
}
and called it with this:
$G = new Generate(100, 100);
$G->bg(255, 255, 255);
$G->gen();
its generating image fine when i comment out the header in the gen() function and set it to save the image. Like this:
imagepng($this->canvas, 'img.png', 9);
but i want it to send the header(output the image) but it gives me an error. can someone please tell me what i'm doing wrong? can you even send headers with-in a PHP class?
this code works fine when i don't use OOP

The answer to your question is yes, you can. You can send headers at any time before you send any output to the client, which I suspect is what your issue is.
You can also check the encoding that you're saving your file in. If you are saving your file as UTF-8, make sure you save it without a byte order mark. This counts as output, and will always be the first character in your file meaning any call to header() will generate a warning.

The code works perfectly for me when I run it as you posted it; are you sure that you aren't just losing your 100x100 white image on a white background? Try changing the color to, say, 127,255,255 (a lovely aqua) and see if it shows up.

Related

Don't show processed GD PHP image in browser

this is my first question and I'm planning to hang around in this forum. I'm very new to programming since I'm studying but I'm making great progress. So, with this in mind I'll try to be as detailed as possible.
The project I am working with is about creating a png-image using GD PHP. The script recieves data, calculates image WIDTH/HEIGHT according to these. From this data I then print out pixels on the image in different spots. Everything works great, it displays the image and saves it on the server, there's nothing wrong with that. But when I run the script, it outputs the image to the browser. I don't want that. I just want the script to process the image and save it to the server. I have searched plenty but haven't found anything about it.
Code for creating the image: I have to remove some code though, but it's not needed to answer my question. I suspect it's something with the header and imagecreatetruecolor. This is all the data I can give.
<?php
//Some calculations before
// --- START: CREATE IMAGE ---
$png = imagecreatetruecolor($WIDTH, $HEIGHT);
imagesavealpha($png, true);
$trans_colour = imagecolorallocatealpha($png, 0, 0, 0, 127);
imagefill($png, 0, 0, $trans_colour);
//Here's just a loop to print pixels
header("Content-type: image/png");
imagepng($png);
save($png); //Function used for saving
//Erase from memory
imagedestroy($png);
?>

PHP issue with imagepng showing broken image

I'm trying to create a dynamic image generator that also caches the images.
Everything works perfectly, except that for some reason when I save an images and try to display it at the same time, it shows a broken image icon (like: http://cl.ly/image/3K1f0R0n1R0U).
Code sample:
// some string parsing junk happens up here, but removing that didn't change
// what I've been having a problem with
header("Content-type: image/png;");
if(file_exists($fullFileName)){ // serve the file if it already exists
ob_clean();
flush();
readfile($fullFileName);
exit;
} else { // create the file if it doesn't exist
$my_img = imagecreate(200, 80);
$background = imagecolorallocatealpha($my_img, 0, 0, 0, 127);
$line_colour = imagecolorallocatealpha($my_img, $color["r"], $color["g"], $color["b"], $color["a"]);
imagesetthickness($my_img, 1);
imageline($my_img, 30, 45, 165, 45, $line_colour);
//////////////////////////////////////////
// the line that's causing my troubles: //
//////////////////////////////////////////
imagepng($my_img, $fullFileName);
imagecolordeallocate($line_color);
imagecolordeallocate($background);
imagedestroy($my_img);
}
So, the images are created just fine, save just fine, and display exactly like I want when I refresh the page (because it grabs the saved file).
If I switch that darn line above to:
imagepng($my_img);
Then the image shows up fine, but it doesn't save (since I'm not telling it to).
I thought that this topic:
PHP echoing jpeg image fails, but writing same image to file works great. Why?
Sounded similar, but removing the trailing white space still didn't change what's happening. Other threads mentioned it could be a problem with other content being sent before the headers, but there is nothing like that in this file.
Any ideas on what could be going wrong? No errors are being logged, and I'm out of ideas.
Thanks!
-Zach
EDIT:
It was explained that I was destroying my image, which I missed. I ended up using this:
header("Content-type: image/png");
if(!file_exists($fullFileName)) {
$my_img = imagecreate($dashWidth + $dashSpace, $height);
$background = imagecolorallocatealpha($my_img, 0, 0, 0, 127);
$line_colour = imagecolorallocatealpha($my_img, $color["r"], $color["g"], $color["b"], $color["a"]);
imagesetthickness($my_img, 1);
imageline($my_img, 0, $height-1, $dashWidth-1, $height-1, $line_colour);
imagepng($my_img, $fullFileName);
imagecolordeallocate($my_img, $line_color);
imagecolordeallocate($my_img, $background);
}
ob_clean();
flush();
readfile($fullFileName);
exit;
you mean
header("Content-type: image/png"); // without ;
and also, you are destroying your image, read again the file
readfile($fullFileName);
because imagepng($my_img, $fullFileName); only saves it.
From the manual, imagepng
Outputs or saves a PNG image from the given image
Note the "or". Try making two calls to imagepng. One call to save it to a file and one call without the filename parameter to output the image to the browser.
Try to open image with you text editor.
Turn off error_reporting.
Show you broken image.

Trouble passing variable from page to page using $_SESSION php

I am doing an assignment for school where we are to make two php files. First file invokes session, generates a random 5 char string, and saves the string to the session array. The second script generates an image, and takes the string from the first file and incorporates it over the image to make a captcha.
I am having an issue passing the value to the second script. The session variable 'captcha_string' is fully visible in the first script, but is not passed to the second page. I am brand new at this, and frustrated. My understanding is, that as long as I start session, the entire $_SESSION array should be available. When I run the first script, I get a broken image tag, not the captcha i am hoping for. Hope this clears up my problem.
This is what I have done for the first file:
<?php
session_start();
$possible_chars = array_merge(range('A','Z'),range('0','9'));
shuffle($possible_chars);
$string = substr(implode($possible_chars),0,5);
$_SESSION['captcha_string']=$string;
?>
<img src="captcha_generator.php" alt="Weinerdog!" />
and this is the bit from the second file where I try to grab the $string (captcha_string), which is named "captcha_generator.php:
<?php
session_start();
putenv('GDFONTPATH=' . realpath('.'));
header("Content-type: image/png");
//import string for the captcha from $_SESSION
$string = $_SESSION['captcha_string'];
// Build an image resource using an existing image as a starting point.
$backgroundimage = "captcha_wiener.jpg";
$im=imagecreatefromjpeg($backgroundimage);
$colour = imagecolorallocate($im, rand(0,255), rand(0,255), rand(0,255));
// Output the string of characters using a true type font.
// Above we set the font path to the current directory, this
// means that arial.ttf font file must be in this directory.
$font = 'arial.ttf';
$angle = rand(-5,5);
imagettftext($im, 120, $angle, 50, 250, $colour, $font, $string);
// Draw some annoying lines across the image.
imagesetthickness($im, 10);
for ($i = 0; $i <3; $i++) {
imageline($im, rand(100,50), rand(150,200), rand(450,550), rand(200,250), $colour);
}
// Output the image as a PNG and the free the used memory.
imagejpeg($im);
imagedestroy($im);
?>
This is, of course, strictly an exercise to make sure we can pass values using session. There is no problem with the rest of the code making the captcha, it has been tested and works.
You're echo-ing some values with a content-type set to image/png, hence either you'll have the error of headers already sent, or, if the text wasn't sent yet (because cached by PHP), you'll have a broken image and you won't be able to see the text.
Don't worry, it has happened to everyone including me :-)

Having problems with captchas and headers (PHP)

I'm trying to add a captcha to a site somebody else has made.
I've been following this tutorial and if I make it in a separate file, it works just fine (so it's not an issue with the server setup)
However, when I try to add it to an existing page, it's not working at all. When I load the page in Internet Explorer, the source code is displayed with random characters where the image should have been displayed such as:
‰PNGIHDRé1°8ö[IDATxœÍ]kp×u>»X‹± (4 ›–9¦:‰-C£V™©4–[ÓL•4“Dm~„njR3ª]*qÒÚ‰£ŽãD–&~Ô±ØØŽ$
In Firefox, I get the message: The image “myurl” cannot be displayed, because it contains errors.
I'm assuming this is something to do with the headers, but I'm not really sure.
This is the code I'm using to create the image:
$md5 = md5(microtime() * mktime());
$string = substr($md5,0,5);
$captcha = imagecreatefrompng("./captcha.png");
$black = imagecolorallocate($captcha, 0, 0, 0);
$line = imagecolorallocate($captcha,233,239,239);
imageline($captcha,0,0,39,29,$line);
imageline($captcha,40,0,64,29,$line);
imagestring($captcha, 5, 20, 10, $string, $black);
$_SESSION['key'] = md5($string);
header("Content-type: image/png");
imagepng($captcha);
Any advice would be greatly appreciated. Thanks.
Those random characters are actually the contents of a PNG file.
What's happening is you're dumping the PNG data into your HTML file, rather than linking to it with an <img> tag.
You need to put the code into its own file and embed it like this:
<img src="image.php">

Calling a PHP function

I've got the following function that generates and saves an image based a text parameter. How can I call this in my file? I tried
INCLUDE 'outPrice.php';
to link to the external PHP and called it with this command,
outPrice($text);
To which I got the following response.
Warning: Cannot modify header information - headers already sent
Any help would be appreciated.
function outPrice($textval){
$textcolor = '666666';
$font="bgtbt.ttf";
$size = 20;
$padding= 1;
$bgcolor= "ffffff";
$transparent = 0;
$antialias = 0;
$fontfile = $fontpath.$font;
$box= imageftbbox( $size, 0, $fontfile, $textval, array());
$boxwidth= $box[4];
$boxheight= abs($box[3]) + abs($box[5]);
$width= $boxwidth + ($padding*2) + 1;
$height= $boxheight + ($padding) + 0;
$textx= $padding;
$texty= ($boxheight - abs($box[3])) + $padding;
// create the image
$png= imagecreate($width, $height);
$color = str_replace("#","",$bgcolor);
$red = hexdec(substr($bgcolor,0,2));
$green = hexdec(substr($bgcolor,2,2));
$blue = hexdec(substr($bgcolor,4,2));
$bg = imagecolorallocate($png, $red, $green, $blue);
$color = str_replace("#","",$textcolor);
$red = hexdec(substr($textcolor,0,2));
$green = hexdec(substr($textcolor,2,2));
$blue = hexdec(substr($textcolor,4,2));
$tx = imagecolorallocate($png, $red, $green, $blue);
imagettftext( $png, $size, 0, $textx, $texty, $tx, $fontfile, $textval );
header("content-type: image/jpeg");
imagejpeg($png, "price".$textval.".jpg");
imagedestroy($png);
}
How are you invoking this file? If you are calling it inside of an <img> tag, or from a CSS directive, then do as C. Walsh says and check for whitespace in the file (tip: for binary data, don't include a closing ?> tag in your script) as well as a Byte Order Mark at the beginning of your file (use a HEX editor like PSPad for this).
You may also want to consider, since errors may occur during your image script's execution, wrapping the script contents in ob_start() and ob_end_clean(), where ob_end_clean() is called just before the headers are sent and the image is generated.
If you are invoking it directly from the file in which you wish to embed the image, then use the following HTML scheme:
<img src="data:image/png;base64,DATADATADATA" alt ="" />
Where DATADATADATA is the base64 encoded version of your image.
See:
Data URI Scheme
PHP Manual Entry for base64_encode()
The message means that the page has already sent some data to the browser – if you don’t think this should have happened then it could be some whitespace somewhere in your PHP files. You’ll need to find where it’s coming from and remove it.
If it does turn out to be whitespace then this thread might be helpful.
Using the header() function (third last line) after any content has been sent as response, is not possible, because headers need to be sent first in all http communications. Make sure that your php files don't have whitespace before <?php or after ?>
The error you're getting is caused by output being sent to the browser before you call "header" near the end of the function.
Chances are you've got some white space sitting outside of your first and last <?php ?> tags. When this happens, PHP automagically sends headers to the browser indicating that you're outputting an HTML document. Once this has happened, you can no longer alter the headers, and PHP issues an error.
Track down where the output is coming from; try viewing the source of the document, and making sure you have no leading/trailing whitespace in the files that are included.

Categories