[LONG POST] GD wont display the image [COMMENTED]

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

malcolmboston
DevNet Resident
Posts: 1826
Joined: Tue Nov 18, 2003 1:09 pm
Location: Middlesbrough, UK

[LONG POST] GD wont display the image [COMMENTED]

Post by malcolmboston »

basically, the picture just wont output, i get placeholder with an X, any ideas?

ps. its my first effort at a class so dont be too harsh :wink:, some things arent implemented yet even though the functions are written, but the output should be working

Code: Select all

<?php
// image class
class Ezthumb
{
	var $fpath;
	///////////////////////////////////////////////////
	//                 CONSTRUCTOR                   //
	///////////////////////////////////////////////////
	/**
	* @return void
	* @param $fpath
	* @desc EzThumb class: Automatically generate thumbnails on the fly, as well as thumbnail file output
	*/
	function EzThumb ($fpath)
	{
		$this->image->filepath = $fpath; // set a nice fpath value
		// unset filepath to make it look nicer
		unset($this->fpath); // unset it
		$this->CheckGDSupport ();
		$this->CheckUserRequirements ();
		$this->CheckImageAvailable ();
		$this->GetImageInformation(); // get width. height and type of image
		$this->GetImageFilesize(); // get the filesize of the image
		$this->FormatImageFilesize(); // format it
		$this->GetImageExtension (); // do an explode to get the extension on the filename
		$this->GetImageType (); // check type as defined from getimagesize
		$this->CheckWallpaper (); // check to see if it has the dimensions of a wallpaper image
		$this->ThumbScale (); // get the ratio to scale to
		$this->ShowImageThumbnail (); // actually generate the thumbnail (writing of thumbnail also designated here)
	}
	//
	/**
	* @return void
	* @desc Converts and checks the users settings and passes them to the object
	*/
	function CheckUserRequirements ()
	{
		// first check the expected vars are of the type required
		if (!is_numeric($_GET['max_height']) && ($_GET['max_width']))
		{
			// we're expecting numberical values, they arent numberic
			print "Expecting Numeric value for max height + max width";
			exit;
		}
		if (isset($_GET['max_height']) || ($_GET['max_width']))
		{
			// one or the other is set
			// its set
			$this->userreq->maxheight = $_GET['max_height'];
		}
		else
		{
			// its not set, set a default
			$this->userreq->maxheight = 80;
		}
		if (isset($_GET['max_height']))
		{
			// its set
			$this->userreq->maxwidth = $_GET['max_width'];
		}
		else
		{
			// its not set, set a default
			$this->userreq->maxwidth = 80;
		}
	}	
	//
	/**
	* @return void
	* @desc Checks the filesystem/url to see if the file exists
	*/
	function CheckImageAvailable ()
	{
		if (!is_file($this->image->filepath))
		{
			print "Filepath is invalid for <strong>{$this->image->filepath}</strong>";
			exit;
		}
	}
	//
	/**
	* @return void
	* @desc Generates various information about an image such as bits per channel and mime type
	*/
	function GetImageInformation ()
	{
		// get an array back with information that i can decide what to put into the object
		$array = getimagesize($this->image->filepath);
		// assign values i want to store
		$this->image->width = $array[0];
		$this->image->height = $array[1];
		$this->image->type = $array[2];
		$this->image->bits = $array['bits'];
		$this->image->channels = $array['channels'];
		$this->image->mime = $array['mime'];
	}
	//
	/**
	* @return void
	* @desc Simple function that parses the filename to retrieve the extension
	*/
	function GetImageExtension ()
	{
		$explode = explode(".", $this->image->filepath);
		$this->image->extension = array_pop($explode);
	}
	//
	/**
	* @return void
	* @desc Handles the actual output of the thumbnail, also calls the thumbnail writing process if required
	*/
	function ShowImageThumbnail ()
	{
		// check to see if the image needs resizing before output
		if ($this->imagescale < 1)
		{
			// it does Scaling down required
			// output headers
			#header ("Content-type: {$this->image->mime}");
			$this->thumbnail->width = ($this->image->scale * $this->image->width);
			$this->thumbnail->height = ($this->image->scale * $this->image->width);
			$temp = imagecreate($this->thumbnail->width, $this->thumbnail->height) or die ("Cannot Create Thumbnail: Possible Problem With Function Coding");
			$temp = imagecopyresized($temp, $this->image->filepath, 0, 0, 0, 0, $this->thumbnail->width, $this->thumbnail->height, $this->image->width, $this->image->height);
			$thumbnail = $temp;
			imagejpeg($thumbnail);
			imagedestroy($temp);
			
			
		}
		else
		{
			// it doesnt
		}
	}
	//
	/**
	* @return void
	* @desc Handles the writing of the thumbnail to the file system
	*/
	function WriteThumbnail ()
	{
		//
	}
	//
	/**
	* @return void
	* @desc function that converts the code return by getimagesize into the actual file type
	*/
	function GetImageType ()
	{
		// define the array of definitions
		$type_definitions = array(1 => "GIF", 2 => "JPG", 3 => "PNG", 4 => "SWF",5 => "PSD",
		6 => "BMP", 7 => "TIFF(intel byte order)", 8 => "TIFF(motorola byte order)", 
		9 => "JPC", 10 => "JP2", 11 => "JPX", 12 => "JB2", 13 => "SWC", 14 => "IFF", 15 => "WBMP", 16 => "XBM");
		$this->image->type = $type_definitions[$this->image->type];
	}
	//
	/**
	* @return void
	* @desc Another Simple function that gets the filesize of the passed filename/filepath
	*/
	function GetImageFilesize ()
	{
		$this->image->filesize = filesize($this->image->filepath);
		// we'll now check if its been set, if it has'nt that means its a remote file
		// and we need to change the way we check it
		if (empty($this->image->filesize))
		{
			// its empty
			// reset the value
			print "it was initially empty";
		}
	}
	//
	/**
	* @return void
	* @desc nice feature that converts the byte value given by PHP into KB + MB
	*/
	function FormatImageFilesize ()
	{
		$imgsize = filesize($this->image->filepath) / 1024;
		$imgsize = round($imgsize, 0);
		// KB is set, but now we'll check if its higher than 1000 and put it in as MB
		if ($imgsize >= 1000)
		{
			$this->image->formatfilesize = ($imgsize / 1000);
			$this->image->formatfilesizeunit = "MB";
		}
		else
		{
			$this->image->formatfilesize = $imgsize;
			$this->image->formatfilesizeunit = "Kb";
		}
	}
	//
	/**
	* @return void
	* @desc Check to see if the image has the same resolution as wallpaper
	*/
	function CheckWallpaper ()
	{
		$array_width = array("640", "800", "1024", "1152", "1280", "1280", "1600");
		$array_height = array("480", "600", "768", "864", "960", "1024", "1200");
		if (in_array($this->image->height, $array_height) && in_array($this->image->width, $array_width))
		{
			// is a wallpaper
			$this->image->wallpaper = 1;
		}
		else
		{
			$this->image->wallpaper = 0;
		}
	}
	//
	/**
	* @return void
	* @desc Automatically calculates the ratio to resize the thumbnail to
	*/
	function ThumbScale ()
	{
		$this->image->scale = min($this->userreq->maxwidth / $this->image->width, $this->userreq->maxheight / $this->image->height);
	}
	//
	/**
	* @return void
	* @desc Check to see if GD is supported on the users server,also returns GD version information
	*/
	function CheckGDSupport ()
	{
		// precedence of use should go to GD version 2 if available
		// just continue to set it as GD2 is eval'd last it will overwrite it
		// check original GD
		if (extension_loaded("gd"))
		{
			$this->env->gdavailable = 1;
			// get version of GD
			$array = gd_info();
			$this->env->gdversion = $array['GD Version'];
		}
		else
		{
			// no GD extension has been loaded
			print "No GD Library available";
			exit;
		}
	}
	//
}
the call

Code: Select all

if ($_GET['call'] == "y")
{
	$call = new EzThumb($_GET['filename']); // filepath relative to document
}
usage

Code: Select all

http://127.0.0.1/test/index.php?call=y&amp;filename=picture.jpg
any help would be much appreciated
as a side note, ive tried commenting the line..

Code: Select all

header ("Content-type: {$this->image->mime}");
thinking maybe that was the error, alas, no

also firefox says
firefox wrote: The image "http://path/to/image" cannot be displayed, because it contains errors.
also thought i would add a print out of the actual object

Code: Select all

ezthumb Object
(
    &#1111;image] =&gt; stdClass Object
        (
            &#1111;filepath] =&gt; pureskillz.jpg
            &#1111;width] =&gt; 200
            &#1111;height] =&gt; 200
            &#1111;type] =&gt; JPG
            &#1111;bits] =&gt; 8
            &#1111;channels] =&gt; 3
            &#1111;mime] =&gt; image/jpeg
            &#1111;filesize] =&gt; 19359
            &#1111;formatfilesize] =&gt; 19
            &#1111;formatfilesizeunit] =&gt; Kb
            &#1111;extension] =&gt; jpg
            &#1111;wallpaper] =&gt; 0
            &#1111;scale] =&gt; 0.4
        )

    &#1111;env] =&gt; stdClass Object
        (
            &#1111;gdavailable] =&gt; 1
            &#1111;gdversion] =&gt; bundled (2.0.28 compatible)
        )

    &#1111;userreq] =&gt; stdClass Object
        (
            &#1111;maxheight] =&gt; 80
            &#1111;maxwidth] =&gt; 80
        )

)
i understand this is a long post, but in suggestions would be much appreciated, its all a learning experience for me atm with classes..

also if any of you guys could give me some tips on the structure of my class (not my coding of the functions) that would be very appreicated also as i feel it is better to learn the standard than do things wrong from the beginning
Syranide
Forum Contributor
Posts: 281
Joined: Fri May 20, 2005 3:16 pm
Location: Sweden

Post by Syranide »

try turning on full error reporting
and opening the picture as a webbpage, that will likely show you what's wrong... I bet it all boils down to an E_NOTICE or so. (that's something to remember too, turn of error reporting completely when you are not making webpages, but images and so on (for non-debug).)

EDIT: one warning though, referencing pictures using variables (?...) will result in some browsers screwing it up, as they think they are getting an homepage, such a browser i firefox, so you have to explicitly set the Content-Type.
malcolmboston
DevNet Resident
Posts: 1826
Joined: Tue Nov 18, 2003 1:09 pm
Location: Middlesbrough, UK

Post by malcolmboston »

Syranide wrote: EDIT: one warning though, referencing pictures using variables (?...) will result in some browsers screwing it up, as they think they are getting an homepage, such a browser i firefox, so you have to explicitly set the Content-Type.
could you explain this please, ive used the same sort of methodology before without classes and its worked fine, they've all been online now for around a year with not a single bug that ive noticed
Syranide
Forum Contributor
Posts: 281
Joined: Fri May 20, 2005 3:16 pm
Location: Sweden

Post by Syranide »

try outputing an image through a webpage, and make the name of the image appear as only a variable, that will make browsers such as firefox etc screw up if they don't recieve a header, which they don't get if you output a file...

however, if you use imagepng etc to output the image this is likely overcome by internally sent headers. HOWEVER, this would not be true for cached thumbnails or any files already stored on the disk, as you would output everything in the files as it is, without any header, or even the header "text/plain". firefox blindly trusts this type.
malcolmboston
DevNet Resident
Posts: 1826
Joined: Tue Nov 18, 2003 1:09 pm
Location: Middlesbrough, UK

Post by malcolmboston »

Syranide wrote:try outputing an image through a webpage, and make the name of the image appear as only a variable,
i havent slept yet so my thijnking may be retarded, what do you mean output it through a webpage? i am already doing this obviously, and how / why would i want to make the name of the file appear as a variable, if your checking to make sure everything is corret meaning that GD is getting the actual filename to use then see the last bit of my initial post for my prin_r on the object
you wrote:that will make browsers such as firefox etc screw up if they don't recieve a header, which they don't get if you output a file...
like i said earlier, i dont think this is ther problem, ive tried both sending and not sending headers, both dont work
you wrote: however, if you use imagepng etc to output the image this is likely overcome by internally sent headers. HOWEVER, this would not be true for cached thumbnails or any files already stored on the disk, as you would output everything in the files as it is, without any header, or even the header "text/plain". firefox blindly trusts this type.
I am passing the image from a seperate page which is called by

Code: Select all

<img src=&quote;class.php?filename=whatever.jpg&quote;>
exactly the same way i did it before and worked, without meaning to criticise you mention headers many times in this post, read my initial post, it explains headers are not the problem
Syranide
Forum Contributor
Posts: 281
Joined: Fri May 20, 2005 3:16 pm
Location: Sweden

Post by Syranide »

ok, frankly I'm a little tired myself (like (30C at work) and mixed up a few things in my head...
first thing I meant was, as a note, make sure you send headers if you use "file" or such functions that read files and output them directly. as it won't specify the type of the content, and firefox will show it as a textfile... I've had this "problem" with my own thumbnailing system, and it's pretty logical to why.

and forget about the rest, they will just screw up your mind apparently, however, take my first advice, open the image as a webpage you will then see a lot of garbage, or no garbage... or some errors and garbage... I bet there are some errors outputed along with the image. check them.
malcolmboston
DevNet Resident
Posts: 1826
Joined: Tue Nov 18, 2003 1:09 pm
Location: Middlesbrough, UK

Post by malcolmboston »

ive seen all this junk before in a previous attempt at doing it which i fixed, however now i am not even getting the junk
malcolmboston
DevNet Resident
Posts: 1826
Joined: Tue Nov 18, 2003 1:09 pm
Location: Middlesbrough, UK

Post by malcolmboston »

any ideas, someone, anyone please!!! *cries*
Syranide
Forum Contributor
Posts: 281
Joined: Fri May 20, 2005 3:16 pm
Location: Sweden

Post by Syranide »

as always, try braking your problem into smaller pieces, go step by step and make sure it does it all as it should, and finally you should end up with the error, perhaps start from the back as I guess that is your problem.

output all values to make sure they are sane, and so on, isolate the problem first, just giving code won't give you many answers.
malcolmboston
DevNet Resident
Posts: 1826
Joined: Tue Nov 18, 2003 1:09 pm
Location: Middlesbrough, UK

Post by malcolmboston »

the problem is, GD is not outputting any error messages at all, does anyone know of any other ways of debugging it.

ive been removing bits and testing but nothing points out to me "this is your error"
User avatar
scorphus
Forum Regular
Posts: 589
Joined: Fri May 09, 2003 11:53 pm
Location: Belo Horizonte, Brazil
Contact:

Post by scorphus »

Some simple errors, most with imagecopyresized (line 123). Couple changes and you have a go:

Code: Select all

//
    /**
    * @return void
    * @desc Handles the actual output of the thumbnail, also calls the thumbnail writing process if required
    */
    function ShowImageThumbnail ()
    {
        // check to see if the image needs resizing before output
        if ($this-&gt;imagescale &lt; 1)
        {
            // it does Scaling down required
            // output headers
            header (&quote;Content-type: {$this-&gt;image-&gt;mime}&quote;);
            $this-&gt;thumbnail-&gt;width = ($this-&gt;image-&gt;scale * $this-&gt;image-&gt;width);
            $this-&gt;thumbnail-&gt;height = ($this-&gt;image-&gt;scale * $this-&gt;image-&gt;width);
            $temp = imagecreate($this-&gt;thumbnail-&gt;width, $this-&gt;thumbnail-&gt;height) or die (&quote;Cannot Create Thumbnail: Possible Problem With Function Coding&quote;);
            imagecopyresized($temp, imagecreatefromjpeg($this-&gt;image-&gt;filepath), 0, 0, 0, 0, $this-&gt;thumbnail-&gt;width, $this-&gt;thumbnail-&gt;height, $this-&gt;image-&gt;width, $this-&gt;image-&gt;height);
            $thumbnail = $temp;
            imagejpeg($temp);
            imagedestroy($temp);
            
            
        }
        else
        {
            // it doesnt
        }
    }
    //
Compare and see what was changed.

-- Scorphus
malcolmboston
DevNet Resident
Posts: 1826
Joined: Tue Nov 18, 2003 1:09 pm
Location: Middlesbrough, UK

Post by malcolmboston »

ok im now using this more streamlined code

Code: Select all

header ("Content-type: {$this->image->mime}");
$thumb = imagecreatetruecolor($this->thumbnail->width, $this->thumbnail->height);
$source = imagecreatefromjpeg($this->image->filepath);
imagecopyresized($thumb, $source, 0, 0, 0, 0, $this->thumbnail->width, $this->thumbnail->height, $this->image->width, $this->image->height);
imagejpeg($thumb);
still not working *baffled*
User avatar
pickle
Briney Mod
Posts: 6445
Joined: Mon Jan 19, 2004 6:11 pm
Location: 53.01N x 112.48W
Contact:

Post by pickle »

Try removing the curly braces from your header string.

Also, I'd recommend use imagecopyresampled() over imagecopyresized() if you've got GD2. Thumbnails look worlds better.
Real programmers don't comment their code. If it was hard to write, it should be hard to understand.
User avatar
scorphus
Forum Regular
Posts: 589
Joined: Fri May 09, 2003 11:53 pm
Location: Belo Horizonte, Brazil
Contact:

Post by scorphus »

malcolmboston wrote:(...) still not working *baffled*
Strange. I get it working at http://scorphus.no-ip.com/lab/ezthumb_test.php - sources included.

-- Scorphus
User avatar
Buddha443556
Forum Regular
Posts: 873
Joined: Fri Mar 19, 2004 1:51 pm

Post by Buddha443556 »

Any whitespace outside PHP tags?
Post Reply