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">
Related
I have this nice bit of code that generates a gif on the fly, where I place text over an existing image:
<?
$pic_name = "test.gif";
$gif_image = imagecreatefromgif('background.gif');
$text_color = imagecolorallocate($gif_image, 0, 0, 0);
$font_path = 'arial.ttf';
$text = "E-Signed By:";
imagettftext($gif_image, 6, 0, 72, 11, $text_color, $font_path, $text);
imagegif($gif_image);
imagegif($gif_image, $pic_name);
imagedestroy($gif_image);
?>
When I am done creating the image, I redirect to the next page:
echo
"<html>
<head>
<meta HTTP-EQUIV='REFRESH' content='0; url=https://emortgagecapital.com/mlo/agreement.php'>
</head>
</html>";
The glitch is, on the redirect, for only a moment, I see a very long string of the GIF special characters, that looks something like this:
GIF87aR�9Z�9c�Bc�Jk�Rs�Z{�k��s��{�����
There is a lot more, but you get the idea.
Now, if I leave this bit of code in, the special characters don't display, but it kills the further execution of the script, and simply displays the image on screen:
header('Content-type: image/gif');
I tried placing the redirect as the header, but then the image never rendered and did not save to the server - the main reason for the script.
How do I run this script, and redirect, so the special characters do not 'flash' on the screen?
imagegif — Output image to browser or file
imagegif($gif_image);
your writing to the screen for no reason, just remove the line
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.
I have a website I am building that takes data (the person's name) from a form and posts it into a customized "note" in a table on the next page. I want the user to then be able to save their "note" as an image with their customized name on it. Is there a way to save a SPECIFIC HTML TABLE as a PNG? Maybe take a screenshot of a specific coordinate on a web page?
If not is there a way to render posted PHP content from the form in an HTML canvas?
Any help would be great. I'm in a little over my head right now.
While you can render HTML using a variety of tools, you can't be sure that those tools will render the HTML the same way your browser renders it.
If your end goal is to generate an image with text on it, then let's solve that problem instead of trying to make the solution you suggested work.
Have a look at PHP's imagettftext() function. It contains an Example #1 which creates a small, simple image from text that can be stored in any variable ... including a form variable.
By using this example, and adding a few other of PHP's GD functions, you can make a decent replica of a table, and make sure it looks exactly the way you want it, rather than the way html2ps or some other tool renders it.
<?php
// Set the content-type
header('Content-Type: image/png');
// Create the image
$im = imagecreatetruecolor(400, 30);
// Create some colors
$white = imagecolorallocate($im, 255, 255, 255);
$grey = imagecolorallocate($im, 128, 128, 128);
$black = imagecolorallocate($im, 0, 0, 0);
imagefilledrectangle($im, 0, 0, 399, 29, $white);
// The text to draw
$text = isset($_POST['name']) ? $_POST['name'] : "name";
// Replace path by your own font path
$font = 'arial.ttf';
// Add some shadow to the text
imagettftext($im, 20, 0, 11, 21, $grey, $font, $text);
// Add the text
imagettftext($im, 20, 0, 10, 20, $black, $font, $text);
// Using imagepng() results in clearer text compared with imagejpeg()
imagepng($im);
imagedestroy($im);
?>
Here's sample output generated by the above script:
Note that you'll need to provide arial.ttf per the instructions at the link above.
If things don't work, look for errors both on-screen and in your web server's error log FIRST, before following up here. It's possible that PHP's GD module is not installed on your web server. If this is the case, you should check with your server administrator to make sure what you need is available to you.
You can try this JS library on client side.
workable solution
use fpdf to create pdf from html (table)
use imagemagick to convert pdf to png
You can also use Xvfb. It's a linux package. It stands for "X-window Virtual Frame Buffer" (if you were wondering why on earth it had such an esoteric name).
What that will do, is load a page, execute any JavaScript and apply the different stylings from CSS, all in the frame-buffer of the server. Then you can save the image.
Xvfb will probably not be available on most shared-hosting services, however, if that doesn't matter, then it would be a viable solution.
You can use something like html2ps
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 :-)
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.