?
Solved

Preloading images that are created from a PHP file

Posted on 2009-12-22
12
Medium Priority
?
293 Views
Last Modified: 2012-05-08
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?
0
Comment
Question by:mcravenufo
  • 6
  • 6
12 Comments
 
LVL 2

Expert Comment

by:nergik
ID: 26108209
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
 

Author Comment

by:mcravenufo
ID: 26108360
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
 
LVL 2

Expert Comment

by:nergik
ID: 26108412
Weird...

do you have any public url where i can test it? maybe with firebug we can see what is exactly happening
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:mcravenufo
ID: 26108559
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
 

Author Comment

by:mcravenufo
ID: 26108604
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
 

Author Comment

by:mcravenufo
ID: 26108928
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
 
LVL 2

Expert Comment

by:nergik
ID: 26108962
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
 
LVL 2

Expert Comment

by:nergik
ID: 26108983
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
 
LVL 2

Accepted Solution

by:
nergik earned 1000 total points
ID: 26108996
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
 

Author Comment

by:mcravenufo
ID: 26109023
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
 

Author Comment

by:mcravenufo
ID: 26109034
Thanks for the time you put into this. I think my code was correct just my testing was incorrect.
0
 
LVL 2

Expert Comment

by:nergik
ID: 26109063
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

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article discusses four methods for overlaying images in a container on a web page
Originally, this post was published on Monitis Blog, you can check it here . In business circles, we sometimes hear that today is the “age of the customer.” And so it is. Thanks to the enormous advances over the past few years in consumer techno…
The viewer will learn how to dynamically set the form action using jQuery.
The viewer will learn how to look for a specific file type in a local or remote server directory using PHP.
Suggested Courses
Course of the Month15 days, 12 hours left to enroll

850 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question