Preloading images that are created from a PHP file

I'm using a PHP file (image.php) that is dynamically creating images. It's final line output is:
imagepng($canvas);

I want to preload the images in my Javascript/HTML file but when I use the PHP file as the image source, the images do not preload. It appears to run the php code every time.

My preload Javascript:
<head>
<SCRIPT language="javascript">
var customImage1 = new Image(400, 300);
var customImage2 = new Image(400, 300);

customImage1 .src = "image.php?focus=1";
customImage2 .src = "image.php?focus=2";
</head>

My HTML:
<body>
<P><IMG src="image.php?focus=1" width="400" height="300" name="dynImage"></P>
</body>

So when I change the image source in my Javascript code because of some sort of user input, the image reloads every time:

// image reloads even though I've done the standard preload method
if($something == $another)
{
      document.dynImage.src = customImage1.src;
}
else
{
      document.dynImage.src = customImage2.src;
}

Is there a way to preload images that are created and returned from a PHP file?
mcravenufoAsked:
Who is Participating?
 
nergikCommented:
In firefox when you press CTRL+F5 you are forcing a FULL reload, even if firefox already has the content in cache, it will download everything again,

Pressing only F5 you will get the HTML and if the images are cached and have not expired you will se the local cached images, so wont need to fetch it from the server
0
 
nergikCommented:
Hello, that seems a cache problem, you need to send the appropiate headers using php to tell the browser if the he can use the already loaded image (from the preload) instead of querying the server again,

Controlling how those images are cached is basically done using 2 kind of headers: Expires and Cache-Control

Using the Expire header is really simple. It tells when the image should be fetched again from the web server. In order to use it in your  PHP code, just after the Content-type, you can add the the expire header as shown below:

 // calc an offset of 24 hours
 $offset = 3600 * 24;
 // calc the string in GMT not localtime and add the offset
 $expire = "Expires: " . gmdate("D, d M Y H:i:s", time() + $offset) . " GMT";
 //output the HTTP header
 Header($expire);

The Cache-Control HTTP Headers is part of the HTTP 1.1 standard. Here you are an example:

 Cache-Control: max-age=3600, must-revalidate

It has a certain number of parameters that can be used:

->max-age=seconds  the number of seconds from the time of the request you wish this objcet to be -keep into the cache;
->s-maxage=seconds  like max-age but it only applies to proxy;
->public  tell to handle the content has cacheable even if it would normally be uncacheable, it is used for example for authenticated pages;
->no-cache  force both proxy and browser to validate the document before to provide a cached copy;-
->must-revalidate  tell the browser to obey to any information you give them about a webpage;
->proxy-revalidate  like must-revalidate but applies to proxy;

But thats not all, you have to consider also the Last-Modified header

You just have to output a date in GMT here, for example:

   $gmt_mtime = gmdate('D, d M Y H:i:s', time() ) . ' GMT';
   header("Last-Modified: " . $gmt_mtime );


Try adding one by one those headers to the PHP code that generates the image and tell us the results,
Hope it works for you.
0
 
mcravenufoAuthor Commented:
I added in your suggestions 1 at a time until all 3 headers where inserted. I also tried adding each new header individually. The end of my PHP code now looks like this but it still reloads the images each time.

header("Content-type: image/png");
// =======================
// calc an offset of 24 hours
 $offset = 3600 * 24;
 // calc the string in GMT not localtime and add the offset
 $expire = "Expires: " . gmdate("D, d M Y H:i:s", time() + $offset) . " GMT";
 //output the HTTP header
 header($expire);
 header("Cache-Control: max-age=3600, must-revalidate");
 $gmt_mtime = gmdate('D, d M Y H:i:s', time() ) . ' GMT';
 header("Last-Modified: " . $gmt_mtime );
// =======================
imagepng($canvas);
imagedestroy($canvas);
0
Ultimate Tool Kit for Technology Solution Provider

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy now.

 
nergikCommented:
Weird...

do you have any public url where i can test it? maybe with firebug we can see what is exactly happening
0
 
mcravenufoAuthor Commented:
I have tried using firebug but I'm not too familiar with it.

I can put it on a public url but the images and code are confidential. I would need to make generics of both before I made it public.
0
 
mcravenufoAuthor Commented:
More Info:

I am changing the image based on a keypress:

<BODY onKeyPress="return handleOnKey(event)">

function handleOnKey(e)
{
      switch(e.which)
      {
            case KEYBOARD_W:
                  document.dynImage.src = customImage1.src;
                  break;

            case KEYBOARD_S:
                  document.dynImage.src = customImage2.src;
                  break;
      }
}
 
0
 
mcravenufoAuthor Commented:
Could it be Firefox?

When I use Ctrl-F5 to get new content the images always reload. However, if I just press F5 after Ctrl-F5 the page does not reload anymore.

0
 
nergikCommented:
Hello,

I developed a little php which produces diferent images in php, and used the html you provided,
and after Testing the amount of queries done to the webserver using Firebug within Firefox, the preload works well, i mean the image is fetched from the server only ONE time,
please see screenshot attached,

Code i used:

HTML page
--------------
<html>

<head>
<SCRIPT language="javascript">
var customImage1 = new Image(400, 300);
var customImage2 = new Image(400, 300);

customImage1 .src = "image.php?focus=1";
customImage2 .src = "image.php?focus=2";
</script>

</head>

<body>
<P><IMG src="image.php?focus=1" width="400" height="300" name="dynImage"></P>
</body>


</html>


PHP producing images  image.php
------------------------------------------
<?php
$foc = $_GET['focus'];

header("Content-type: image/png");
 $im = ImageCreate(100, 100);
 $black = ImageColorAllocate($im, 0, 0, 0);
 $red = ImageColorAllocate($im, 255, 0, 0);
 $blue = ImageColorAllocate($im, 0, 0, 255);
 
 if($foc==1) ImageFilledRectangle($im,5, 55, 75, 5, $blue);
 else ImageFilledRectangle($im,25, 25, 75, 75, $red);
 
 
 
 # Output the image to the browser
 ImagePng($im);

?>

preloadLoading.jpg
0
 
nergikCommented:
Now i just added the keyboard image change, and still works fine, theres no image reload in any case, please test it below,

key 'a' shows first image,  key 'b' shows second image

<html>

<head>
<SCRIPT language="javascript">
var customImage1 = new Image(400, 300);
var customImage2 = new Image(400, 300);

customImage1 .src = "image.php?focus=1";
customImage2 .src = "image.php?focus=2";

function handleOnKey(e)
{

      switch(e.which)
      {
            case 97:
                  document.dynImage.src = customImage1.src;
                  break;

            case 98:
                  document.dynImage.src = customImage2.src;
                  break;
      }
}

</script>

</head>

<body onKeyPress="return handleOnKey(event)">



<P><IMG src="image.php?focus=1" width="400" height="300" name="dynImage"></P>
</body>


</html>


So, it works well!!
0
 
mcravenufoAuthor Commented:
What's strange is that even though I press CTRL-F5 only once, it reloads all the images every time, even 5 minutes later without pressing any other key. However, if I press only F5 after CTRL-F5, then the images stop reloading every time.
0
 
mcravenufoAuthor Commented:
Thanks for the time you put into this. I think my code was correct just my testing was incorrect.
0
 
nergikCommented:
Yes, its happening the same on my script, but this is intended on firefox side, it wont cache anything as supposes you want to fetch everything again....  but 99% of the users wont do a CtrF5 ;)   so don't worry about that
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.