Is there a way to detect missing images and redirect them to a static image?

Basically if I had an image that I was displaying from a different site (with permission), and that image were removed, is there a way I can default that image to a default .gif? I have tried PHP getimagesize, but to do that multiple times per page REALLY slowed things down.

Is there a better way? The only other thing I could think of was to create a background image of the default gif, load the images on top of the background, and use blank alt text so that if the image I'm trying to load doesn't exist, just the background default image will show, but this won't work very well, as sometimes the background image would show through as the size of the images are variable.

Thanks in advance

Maybe use something in javascript along the lines of:

function validateImage(url){
  var img = new Image();
  img.src = url;
  return img.height>0;
}

which should return true if the image exists (i.e. height is greater than 0). This might fail if the image takes time to load, so test a lot. You might be able to mitigate this by running your validation function using the body onload event. And in this case, you should be able to avoid the image loading lag, because your browser would have cached the image and the height would be readily available. Hmm, so something like:

function replaceMissingImages(){
  for (var i=0; i<document.images.length; i++){
    img = new Image();
    img.src = document.images[i].src;
    if (img.height == 0)
      document.images[i].src = 'mydefault.jpg';
  }
}

Alternatively, you can do an XMLHTTPRequest to the image, to get the return code (I think you can use some kind of HTTP HEAD instruction to avoid actually requesting/retrieving the entire image). 404 would indicate a missing picture, 200 it's good, 304 it's not modified if you use the right headers, etc.. There are plenty of pages where they have these codes available..

The function you stated is working, i put a little twist on it to get it to work..

function replaceMissingImages(){
  for (var i=0; i<document.images.length; i++){
    img = new Image();
    img.src = document.images[i].src;
    if (img.height == 0) {
      document.images[i].src = '/images/no-image.jpg';
    }

1 problem as you stated the delay of the images loading is telling the script hey these images are not here and we need to replace them before giving the image time to load.. How can I add a delay to the function so it doesnt start until the end of the page loading?

Edited 7 Years Ago by nav33n: Use [code] tags to wrap your code for better readability.

Try to call the function at the end of the script.

<?php "<script type="text/javascript">replaceMissingImages()</script>"; ?>

Here's my two-penneth worth. If JS not on - problems with JS solution. WHat about file_get_contents?

The reason I suggest this is that the display of the page if using JS is at the mercy of the client's (user's) settings. The following should work regardless as it is processed on the server (although you may need full control of your php.ini file).

$file is the image to check (from DB value I take it)

if( false == ($str=@file_get_contents('$file',NULL,NULL,0,1))){
    echo "<img src=\"$default_file\" ...other_attributes... />";
  }else{
    echo <img src=\"$file\" ...other_attributes... />";
  }

The parameters for file_get_contents (0 and 1) relate to start at character 1 and read 1 character - so you're not reading the whole file - should save time - should be quick.

The '@' is required to surpress errors.

CAVEAT - if allow_url_fopen is set to false (0) - this will not work, if you have access to your php.ini file, turn allow_url_fopen on. The alternative would be to use cURL, but I assume this would be sloooooow.
?>

***
Linking to remote images may be asking for trouble. If this is an "avatar"/"profile" type image, perhaps it would be better if users could upload their image (which could be resized via GD2 or ImageMagick library) and the filename stored in a db.

Edited 7 Years Ago by diafol: n/a

This article has been dead for over six months. Start a new discussion instead.