[Solved] Display an external image

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
artoonie
Forum Newbie
Posts: 10
Joined: Sat Jun 09, 2007 3:06 am

[Solved] Display an external image

Post by artoonie »

Is there any way to make a .php load an image from a URL, rather than recreating it from the URL? (as in, without using ImageCreateFromGIF)
header redirects wont work because they cant be embedded with <img>.



Here's why i need it, maybe there's an alternate solution?
I wrote a script that allows users to embed a random image from an array of images they give, but every time the image is requested (it's in .php format), the script must run.
.
My problem is that I'm recreating the image on every load, so with every view, the image must be loaded from scratch (not cache), right?
This seems like it would kill my bandwidth, especially since the script is used on forum posts that gets lots of visits.




(sorry if this belongs in the GD forum, but i dont think GD would be able to do this)
Last edited by artoonie on Wed Jul 04, 2007 4:18 pm, edited 2 times in total.
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

Post your code.
artoonie
Forum Newbie
Posts: 10
Joined: Sat Jun 09, 2007 3:06 am

Post by artoonie »

Here's basically the only important part:

Code: Select all

header("Content-Type: image/gif");
$im = ImageCreateFromGIF($im);
ImageGIF($im);
where $im is originally a randomly chosen URL from an array.



(there's 6 files of code, i dont think it's necessary to post them all. here's the general part where i'm having problems with)
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Post by Weirdan »

Code: Select all

header("Content-Type: image/gif"); readfile($im);
artoonie
Forum Newbie
Posts: 10
Joined: Sat Jun 09, 2007 3:06 am

Post by artoonie »

ooh, thanks!


and this would use less system resources?
would i still be using up bundles of bandwidth?
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Post by Weirdan »

and this would use less system resources?
yes, because this way you would avoid using gd altogether.
would i still be using up bundles of bandwidth?
You can add caching if you need:

Code: Select all

header("Content-Type: image/gif");

$cache_filename = '/tmp/' . md5($im);
$cache_lifetime = 60*60; // one hour
if (file_exists($cache_filename) && time() - filemtime($cache_filename) < $cache_lifetime) {
   readfile($cache_filename);
} else {
   $remote_data = file_get_contents($im);
   file_put_contents($cache_filename, $remote_data);
   echo $remote_data;
}
User avatar
stereofrog
Forum Contributor
Posts: 386
Joined: Mon Dec 04, 2006 6:10 am

Re: Display an external image

Post by stereofrog »

artoonie wrote: header redirects wont work because they cant be embedded with <img>.
What makes you think so?
artoonie
Forum Newbie
Posts: 10
Joined: Sat Jun 09, 2007 3:06 am

Post by artoonie »

thanks much weirdan! hugggee help.


stereofrog, i've tried the script by doing header('location: '$im);, but it didnt work unless you typed it in directly. i want to embed.




edit-
it doesn't seem to ever be cached. i tested this by putting an echo() in the first if, and it never came up with an error (which it should have if that if statement was true), and it did give an error on the else.



here's my code, maybe it wont work in this situation?

Code: Select all

<?php
			$loc = 11833358133489; //the current directory name
			
			
			//caching- code provided by weirdan
			function cache($im)
			{
				$cache_filename = '/tmp/' . md5($im);
				$cache_lifetime = 60*60; // one hour
				if (file_exists($cache_filename) && time() - filemtime($cache_filename) < $cache_lifetime) {
				   readfile($cache_filename);
				} else {
				   $remote_data = file_get_contents($im);
				   file_put_contents($cache_filename, $remote_data);
				   echo $remote_data;
				} 
			}
			
			
			//read the file "index.php", which contains a list of 
				//BEGIN - the following code just gets the list of images, puts then into $images[], and selects an image. no need to read through it.
			$filename = 'index.php';
			
			$handle = @fopen($filename, "r");
			
			$images = array();
			
			$i = 0;
			
			while (!feof($handle)) {
				$image = fgets($handle, 100);
				$images[$i] = $image;
				$i++;
			}
			$i--;
			fclose($handle);
			$num = rand(0,$i-1);

			$im = $images[$num];
				//END getting the image of choice


					$type = substr($im,strlen($im)-4,3); //remove end line char
					$type = strtoupper($type);
					$im = substr($im,0,strlen($im)-1); //remove end line char
					if($type[1]=='E') $type = substr($im,-4); //if JPEG
					$type = strtoupper($type);
					
					switch($type){
						case "PNG":
							header("Content-Type: image/png");
							cache($im);
						break;
						
						case "GIF":
							header("Content-Type: image/gif");
							cache($im);
						break;
						
						case "JPEG":
							header("Content-Type: image/jpeg");
							cache($im);
						break;
						
						case "JPG":
							header("Content-Type: image/jpeg");
							cache($im);
						break;
					}?>
smudge
Forum Contributor
Posts: 151
Joined: Sun May 20, 2007 12:13 pm

Post by smudge »

Me thinks you could replace that last block of code to:

Code: Select all

$type=strtolower(substr($im,strlen($im)-4,3));
$type=preg_replace("/jpg/i","jpeg",$type);
header("Content-Type: image/$type");
cache($im);
$im = substr($im,0,strlen($im)-1);
artoonie
Forum Newbie
Posts: 10
Joined: Sat Jun 09, 2007 3:06 am

Post by artoonie »

smudge wrote:Me thinks you could replace that last block of code to:

Code: Select all

$type=strtolower(substr($im,strlen($im)-4,3));
$type=preg_replace("/jpg/i","jpeg",$type);
header("Content-Type: image/$type");
cache($im);
$im = substr($im,0,strlen($im)-1);
haha, didnt think of that, thanks.

i got this working, using the following function instead of the cache:

Code: Select all

<?php
//open
$filename = 'index.php';
$handle = @fopen($filename, "r");

//define things
$images = array();
$i = 0;
$cookie_unique_name = "";

//loop through list
while (!feof($handle)) {
	$image = fgets($handle, 100);
	$images[$i] = $image;
	$i++;
	$cookie_unique_name .= $image;
}
$i--;

//close
fclose($handle);

//choose a random image
$num = rand(0,$i-1);
$im = $images[$num];

//get the type
$type = strtolower( substr($im,strlen($im)-5,3) ); //remove end line character
$im = substr($im,0,strlen($im)-2); //remove end line character
if($type=='epg') $type = "jpg"; //if JPEG, change to JPG

//make cookie name unique
$cookie_unique_name = stripslashes($cookie_unique_name); //stripslashes for short filenames
$cookie_unique_name = substr(md5($cookie_unique_name),0,7); //keep it short
$cookie_unique_name .= "_pixel"; //make it recognizable

//use cookies and last-modified to save bandwidth
if( isset($_COOKIE[$cookie_unique_name]) )
{
	header("Last-Modified: Sun, 07 Aug 2005 13:27:26 GMT");
	header("Content-Type: image/".$type);
	readfile($im);
}
else{
	setcookie($cookie_unique_name, "rotating", time() + 30);
	header("Content-Type: image/".$type);
	readfile($im);
}
?>
it reads from a file, index.php, that looks like:
Post Reply