Page 1 of 1

[Solved] Display an external image

Posted: Sun Jul 01, 2007 2:57 pm
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)

Posted: Sun Jul 01, 2007 3:03 pm
by feyd
Post your code.

Posted: Sun Jul 01, 2007 3:37 pm
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)

Posted: Sun Jul 01, 2007 3:41 pm
by Weirdan

Code: Select all

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

Posted: Sun Jul 01, 2007 4:59 pm
by artoonie
ooh, thanks!


and this would use less system resources?
would i still be using up bundles of bandwidth?

Posted: Sun Jul 01, 2007 6:15 pm
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;
}

Re: Display an external image

Posted: Sun Jul 01, 2007 6:15 pm
by stereofrog
artoonie wrote: header redirects wont work because they cant be embedded with <img>.
What makes you think so?

Posted: Sun Jul 01, 2007 7:11 pm
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;
					}?>

Posted: Sun Jul 01, 2007 8:55 pm
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);

Posted: Wed Jul 04, 2007 3:58 pm
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: