PHP generated image as an overlay?

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

Post Reply
Zu
Forum Commoner
Posts: 33
Joined: Wed Dec 06, 2006 4:21 am

PHP generated image as an overlay?

Post by Zu »

I have hit a bit of a snag. I have 2 PHP files, portion.php and template.php. Template uses a default image as a template and uses Portion to overlay an image onto it.

Portion works fine, when you go to the page it will create the image I need, everything okay there.

When I go to Template uses the imagecreatefrompng() function to create a PNG image from the Portion class, this is where the snag is.

The problem comes when I try and make the overlay image PHP generated. If I reference it to a standard PNG file, it works perfectly. I am guessing that the Portion class isn't making a true PNG image for the imagecreatefrompng() function.

Here are the two files I am using:

Code: Select all

<?php
// Header mime type
header('Content-type: image/png');

// Only get a small part of the image
$image = imagecreatefromgif('overlay.gif');
$crop = imagecreatetruecolor(75, 20);

// Make the small part of the image smaller
imagecopy($crop, $image, 0, 0, 40, 13, 75, 20);
imagecopyresampled($crop, $crop, 0, 0, 0, 0, 55, 20, imagesx($crop), imagesy($crop));

// Only get what we need from the new smaller image
$crop2 = imagecreatetruecolor(55, 20);
imagecopy($crop2, $crop, 0, 0, 0, 0, 55, 20);

// Create the PNG graphic
imagepng($crop2);

Code: Select all

<?php
// Header mime type
header('Content-type: image/png');

// The overlay image
$overlay = 'portion.php';
$overlay = imagecreatefrompng($overlay);
$overlayX = imagesx($overlay);
$overlayY = imagesy($overlay);

// The template image
$template = imagecreatefromgif('template.gif');
$templateX = imagesx($template);
$templateY = imagesy($template);

// The dimentions of the final graphic
$imageX = 90;
$imageY = 50;

// Where to place the overlay
$offsetX = 30;
$offsetY = 12;

// Create the basic graphic holder
$image = imagecreatetruecolor($imageX, $imageY);

// Put the template in the image
imagecopyresampled($image, $template, 0, 0, 0, 0, $imageX, $imageY, $templateX, $templateY);

// Overlay the overlay graphic onto the template
imagecopymerge($image, $overlay, $offsetX, $offsetY, 0, 0, $overlayX, $overlayY, 99);

// Create the PNG graphic
imagepng($image);
If I change the line

Code: Select all

$overlay = 'portion.php';
to

Code: Select all

$overlay = 'portion.png';
it works fine, so here is my question to you PHP guru's, is there another header I need in the portion.php file???

Thanks :)
User avatar
onion2k
Jedi Mod
Posts: 5263
Joined: Tue Dec 21, 2004 5:03 pm
Location: usrlab.com

Post by onion2k »

You've not said what the problem is.
Zu
Forum Commoner
Posts: 33
Joined: Wed Dec 06, 2006 4:21 am

Post by Zu »

In essence, the imagecreatefrompng() function in the template.php file does not like the source as portion.php, but works fine if I save the output of the portion.php file as portion.php.png.

The error is that is says imagesx() and imagesy() contain invalid arguments (off the top of my head, at work at the moment).
User avatar
onion2k
Jedi Mod
Posts: 5263
Joined: Tue Dec 21, 2004 5:03 pm
Location: usrlab.com

Post by onion2k »

Right.

Code: Select all

$overlay = 'portion.php';
$overlay = imagecreatefrompng($overlay);
portion.php is not a PNG file, it's a text file containing PHP. If you access it locally on the fileserver your script will try to open it as if it's a PNG and fail, then imagesx() and imagesy() will fail because $overlay isn't a valid image resource. You need to rewrite the script so that portion.php creates $crop2 but doesn't generate a PNG file from it, then include() it and use $crop2 in template.php. Better yet, rewrite portion.php as a function or an object and call it in template.php.
Zu
Forum Commoner
Posts: 33
Joined: Wed Dec 06, 2006 4:21 am

Post by Zu »

Thanks, will have a go at it in a while.

And I was going to make in into a class, was just getting the barebones done first. The GD lib unfortunatly isn't my speciality.
User avatar
onion2k
Jedi Mod
Posts: 5263
Joined: Tue Dec 21, 2004 5:03 pm
Location: usrlab.com

Post by onion2k »

Zu wrote:The GD lib unfortunatly isn't my speciality.
Feel free to ask any questions because it is mine. :)
Zu
Forum Commoner
Posts: 33
Joined: Wed Dec 06, 2006 4:21 am

Post by Zu »

Right, I found a spare 5 mins and gave it another go.
You need to rewrite the script so that portion.php creates $crop2 but doesn't generate a PNG file from it, then include() it and use $crop2 in template.php.
I must be misreading you (or doing it wrong), as whenever I call the resource into imagecreatefrompng() it outputs errors saying it failed to open the file. It is expecting an actual image file rather than a resource.

Code: Select all

Warning: imagecreatefrompng(Resource id #5) [function.imagecreatefrompng]: failed to open stream: No such file or directory in F:\localhost\htdocs\GenerateImage.class.php on line 91

Warning: imagecopyresampled(): supplied argument is not a valid Image resource in F:\localhost\htdocs\GenerateImage.class.php on line 103

Warning: imagesx(): supplied argument is not a valid Image resource in F:\localhost\htdocs\GenerateImage.class.php on line 109

Warning: imagesy(): supplied argument is not a valid Image resource in F:\localhost\htdocs\GenerateImage.class.php on line 109

Warning: imagecopymerge(): supplied argument is not a valid Image resource in F:\localhost\htdocs\GenerateImage.class.php on line 110
This is the code I am using, I found time to put it into a class:

Code: Select all

<?php
/**
 * Generated an overlay onto a template
 * @author Zu
 * @version 0.2
 * @package ImageManipulation
 */
class GenerateOverlayImage
{
    /**
     * The URL of the original image
     * @access private
     * @var string 
     */
	private $originalLocation;
	
    /**
     * The URL of the template image
     * @access private
     * @var string 
     */
	private $templateLocation;
	
    /**
     * The overlay image
     * @access private
     * @var string 
     */
	private $overlay;
	
    /**
     * The template image
     * @access private
     * @var string 
     */
	private $template;
	
    /**
     * The final image
     * @access private
     * @var string 
     */
	private $image;

    /**
     * Class constructor
     * @access public
     */
	public function GenerateOverlayImage()
	{
		$this -> originalLocation = 'original.gif';
		$this -> originalLocation = 'template.gif';
		
		$this -> generateOverlay();
		$this -> generateTemplate();
	}
	
    /**
     * Generates the overlay image
     * @access private
     */
	private function generateOverlay()
	{
		// Get the image, then get a small part of it
		$tempImage = imagecreatefromgif($this -> originalLocation);
		$crop = imagecreatetruecolor(75, 20);

		// Shrink that small part of the image
		imagecopy($crop, $tempImage, 0, 0,
									 40, 13,
									 75, 20);
		imagecopyresampled($crop, $crop, 0, 0, 0, 0,
										 55, 20,
										 imagesx($crop),
										 imagesy($crop));
		
		// Remove the unessecary excess from the crop
		$this -> overlay = imagecreatetruecolor(55, 20);
		imagecopy($this -> overlay, $crop, 0, 0,
										   0, 0,
										   55, 20);
	}
	
    /**
     * Generates the template image
     * @access private
     */
	private function generateTemplate()
	{
		// The overlay image
		$this -> overlay = imagecreatefrompng($this -> overlay);
		
		// The template image
		$this -> template = imagecreatefromgif($this -> templateLocation);
		
		// Create the basic graphic holder
		$this -> image = imagecreatetruecolor(90, 50);
		
		// Put the template in the image
		imagecopyresampled($this -> image, $this -> template,
							0, 0, 0, 0,
							90, 50,
							30, 12);
		
		// Begin the overlaying
		imagecopymerge($this -> image, $this -> overlay,
						30, 12,
						0, 0,
						imagesx($this -> overlay), imagesy($this -> template),
						99);
	}

    /**
     * Returns the image
     * @access public
     * @return string overlayed template image
     */
	public function getImage()
	{
		return imagepng($this -> image);
	}
}

header('Content-type: image/png');
$image = new GenerateOverlayImage();
$image -> getImage();
One thing I thought about doing is saving the generated overlayed image to a file, and then calling that... would get round the problem, but I would prefer not to do that if at all possible.

Go easy on me, I'm fragile :\
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

$this->overlay is an image resource after calling generateOverlay().
Post Reply