I tried to make my own basic little captcha out of boredom. It seems to be working except that every now and then it doesn't seem to output anything. when it happens in firefox with the webdeveloper console open I get the message "The image "http://....verimage.php" cannot be displayed because it contains errors." I'm not sure what the errors are or why its not working but this is what I have... I was hoping someone could spot the error.

<?php

// START THE SESSION
session_start();

// RESOURCES
$base_images = array('base1.png','base2.png','base3.png','base4.png','base5.png');
$fonts = array('ARBLANCA.ttf','ARBERKLEY.ttf','ARDECODE.ttf','CHILLER.TTF','GIGI.TTF','HARNGTON.TTF','INFROMAN.TTF','MTCORSVA.TTF');
$colors = array(
		'red' 	=> array('r'=>200,'g'=>0,	'b'=>0),
		'blue'	=> array('r'=>0,	'g'=>0,	'b'=>200),
		'black'	=> array('r'=>0,	'g'=>0,	'b'=>0),
		'grey'	=> array('r'=>50,	'g'=>50,	'b'=>50)
 	);

// BUILD THE TEXT
$letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$size = rand(4,7);
$code = '';
for( $i=0; $i<$size; $i++ ) {
	$code .= $letters[rand(0,52)];
}

// SELECT BASE IMAGE
$base = $base_images[array_rand($base_images)];
$im = imagecreatefrompng($base);

// PUT THE CODE IN THE IMAGE
for( $i=0; $i<$size; $i++ ) {
	$f = $fonts[array_rand($fonts)]; // FONT TO USE
	$c = $colors[array_rand($colors)];
	$c = imagecolorallocate($im,$c['r'],$c['g'],$c['b']); // COLOR FOR FONT
	$s = rand(20,23); // FONT SIZE
	$a = rand(-10,10); // FONT ANGLE
	$x = isset($r) ? 1+$r : 3; // LEFT - X POSITION OF FONT
	$y = rand(30,35); // BASELINE - Y POSITION OF FONT
	$r = imagettftext($im, $s, $a, $x, $y, $c, $f, $code[$i]); // PUT TEXT ON IMAGE
	if( $r === FALSE ) die('Error putting text to image'); // DIE IF TEXT WRITE FAILS
	$lr = $r[2]; // BOTTOM RIGHT MOST POSITION OF TEXT
	$tr = $r[4]; // TOP RIGHT MOST POSITION OF TEXT
	$r = $lr < $tr ? $lr : $tr; // RIGHT MOST POSITION OF TEXT
}

// STORE THE CODE IN SESSIONS
$_SESSION['veriCode'] = md5(strtolower($code));

// OUTPUT THE IMAGE AND FREE THE RESOURCE
header('Content-type: image/png');
imagepng($im);
imagedestroy($im);

    Do you have error logging enabled and error_reporting set to E_ALL? If so, are any errors logged in the PHP error log? Also, [man]die/man isn't going to help you if an error occurs since you'll likely never see that text. Instead, you might consider something like [man]trigger_error/man instead.

    As a blind guess, I'd say that perhaps one of the images and/or font files is corrupt, unreadable, or otherwise throwing a wrench into things.

      1) Why wouldn't die work? its before the header call, and I'm accessing the script directly (not thru an img html tag)
      2) I've tried each font I'm using individually and each image individually. AKA before I put them into an array to randomly select from, I used each one hard coded, with success. There is nothing in my error log error_reporting is E_ALL and logging is enabled so... The only errors are from when I first started and made stupid typos (like pgn etc)

        Derokorian;10991780 wrote:

        1) Why wouldn't die work? its before the header call, and I'm accessing the script directly (not thru an img html tag)

        It'll work just fine, I just figured in the long run (or if not viewing the image directly) it would make debugging easier to log such error messages rather than outputting them.

        Derokorian;10991780 wrote:

        I've tried each font I'm using individually and each image individually. AKA before I put them into an array to randomly select from, I used each one hard coded, with success. There is nothing in my error log error_reporting is E_ALL and logging is enabled so... The only errors are from when I first started and made stupid typos (like pgn etc)

        Since that pretty much covers all of the random behavior in the code, I'm not sure what else to suggest debugging.

        Only other option I can suggest is to find some way to view the raw data sent back (e.g. using Chrome's "developer tools" or a Firefox plugin such as Firebug) when the error occurs and see if the image data appears at all, or if something appears that shouldn't be there.

        As an example of the latter, you said you are logging error messages... but are you also displaying them? If, for example, display_errors was On and PHP encountered a non-fatal error at either of the last two statements, the error message would of course muddle up the binary output of the image.

          Only other option I can suggest is to find some way to view the raw data sent back (e.g. using Chrome's "developer tools" or a Firefox plugin such as Firebug)

          I'm having trouble finding how to view the raw data with either of these. I found a page that says to use the Net panel in firebug, however it is showing me a different image than the one displayed when it works, almost as if its making a new request for that panel.

          I tried turning display_errors Off and still get this problem.

          If you'd like to try I can zip the directory with the images, font, and script?

            Is this script live somewhere that is world-accessible, e.g. could you give us a URL to your script above?

              Ok now I'm thuroughly confused.

              On my local WAMP: I can access localhost/veriCode/base1.png without issue, and the script works about 95% of the time, as explained before.

              On my host LAMP: I cannot acces domain.com/veriCode/base1.png I get a blank screen. If i try to do domain.com/veriCode.base.png (non existent file) I get 404 not found. The script doesn't work at all, I get '/path/to/base3.png' is not a valid PNG file

              I added a $dir variable. I thought not having an absolute path might be why it didn't work when I uploaded but with no luck. I'm very lost now lol...

              veriCode.zip Too big to upload here apparently lol.

                Thuroughly confused - its not working at all at work. Made a new PNG in photoshop (just like I did at home) then I got problems with the fonts, so I copied a font from this system and its working fine with no problems at all. I couldn't open any of the PNGs I made a home here at work, same with the font files. I'm completely confused as to why. If anyone has any thoughts why images / fonts from home wouldn't be working I'd appreciate it! OR Why those same images / fonts work at home O_o this has me boggled!

                  Dumb question, perhaps, but ... is ftp involved in how you're working at all?

                    Well to upload to my webhost I use ftp. But to try it at home I didn't have to move it, and to try it at work I FTP'd it AND thumb drive transfered it but it didn't work. However I made new PNGs at work and copied fonts from my work computer and all is working fine. So the questions leaving me puzzled are:

                    1) Why were the PNGs considered corrupt or damaged that I made at home?
                    2) Why were the fonts from home considered corrupt or damaged at work and on my server?
                    3) Why did the PNGs and fonts work at home, even tho every other system seems to see them as corrupt? O_o

                    At any rate, while this is puzzling why my home pc seems to be goofing things up, it is working now as intended on all 4 places (Work - IIS, Home - WAMP, Work Host - LAMP, and Personal Host - LAMP) Click here to see the image output working.

                      I thought of ftp because transferring them in text mode instead of binary would be likely to corrupt them; but that wouldn't explain why they'd break if you just transferred them to a thumb drive....

                      Could you attach one of these broken "but it works on MY machine" images? I'd be curious to have a look at it.

                        Here you go!

                        Uploaded: base3.png corrupted on other systems, base5.png corrupted on other systems, base1.png working on all systems... Also show up just fine even in windows explorer at home, but not at work (or on the servers)

                          ...And all work here as well. About the only differences I can see between base1.png and the others is that its file size is noticeably smaller and its resolution is 96dpi instead of 72dpi, presumably due to its being massaged with ImageReady.

                            Write a Reply...