2

I want to make something that I've not seen done in web development, but it seems possible. I want a URL that can be put into any arbitrary HTML <IMG/> tag or CSS background-image property that, when accessed, is a random image. I don't want the page to point or redirect to a random image, and I don't want it to display or embed a random image, as these things won't work with the above-stated requirements. I've seen solutions for displaying a random image in a webpage using Javascript to swap a property or hide an element, but this has to make the entire page the image, with no preceding or succeeding binary or ASCII data. I want it to be usable by people who don't know anything about programming. What I'm aiming for is something like this:

http://example.com/randomImage/

In theory, every time a page is loaded with this URL in the CSS or HTML, a random image will be displayed in the referenced element. It should work so that if you have several <IMG/> elements or several elements with their background-image referencing this page, they should all show randomly different images.

My first thought is to use PHP (in the structure described below) to look into a particular directory, pick an image file at random, and echo its binary data. If this is possible, then how would I go about doing it? If not, then does anyone have any other ideas?

My primary idea as pseudocode:

<?PHP
$chosenImage = getRandomFileFrom("./rand/");
$bytes = readFileAsBinary($chosenImage);
foreach($bytes as $byte){
    echo $byte;
}
?>

I don't care about true or pseudo-random. It could cycle each time for all I care; all I require in this endeavor is that multiple images can be referenced as a single URL

Ky -
  • 30,724
  • 51
  • 192
  • 308

2 Answers2

1

You certainly could do this with PHP.

First, choose a random file (see Select random file from directory )

function random_pic($dir = 'imagedir') {
    $files = glob($dir . '/*.jpg');
    if (!$files) return false;

    $file = array_rand($files);
    return $files[$file];
}

Then you can use the PHP readfile function to send it to the user. You can read up on it here: http://www.php.net/readfile see Example 1, which I've modified slightly below:

function outputImage( $filename ) {
    header('Content-Description: File Transfer');
    header("Content-type: image/jpeg");
    header('Content-Disposition: attachment; filename='.basename($filename ));
    header('Content-Transfer-Encoding: binary');
    header('Expires: 0');
    header('Cache-Control: must-revalidate');
    header('Pragma: public');
    header('Content-Length: ' . filesize($filename ));
    ob_clean();
    flush();
    readfile($filename );
    exit;
}

Then pull it all together:

// Get a filename
$filename = random_pic();

// Check that a file was found
if (!$filename) {
    header('HTTP/1.0 404 Not Found');
    die();
}

// Output the image
outputImage( $filename );

You could also change the $files = glob($dir . '/*.jpg'); to look for different image formats, but you would also have to change outputImage to detect the format and set the Content-type type header to image/jpeg or image/png etc...

If you're only serving one type of image, you could always setup Apache to handle requests to 'randomImage.jpg' to a PHP script, and then the client browser would be absolutely none the wiser. For more info check out How to redirect all requests to a file, except images using Apache? (although you would of course be doing the opposite) Also check out Apache rewrite rules: http://httpd.apache.org/docs/current/rewrite/flags.html

I haven't tested this code, but it should work without too much effort. Hope that helps!

Community
  • 1
  • 1
Mike Blouin
  • 290
  • 4
  • 15
  • I'm trying it out on http://bhstudios.org/_img/bg/rand/ but I'm not seeing anything... – Ky - Mar 01 '13 at 06:07
  • Using firebug, I see that its giving a 404 not found. Try echoing something inside the `if (!$filename)` that sets the 404 header. It looks like the `glob($dir . '/*.jpg')` which searches the `$dir` directory for files with the extension .jpg is returning false, see http://php.net/manual/en/function.glob.php – Mike Blouin Mar 01 '13 at 06:11
  • yeah, glob is returning false. I changed 'imagedir' to '/_img/bg', but that doesn't seem to have done anything. All that's in that folder, now, are two PNG files (and I also changed references to jpg/jpeg to png) – Ky - Mar 01 '13 at 06:30
  • You're running ASP.NET right? Try giving glob the full path to your images directory and/or a relative path such as: "C:\www\_img\bg" or "..\..\_img\bg". If you are on Windows make sure all paths are backslashes (also try to change the path within '/*.jpg' to '\*.jpg'). If you are on Linux, you'll want forward slashes. – Mike Blouin Mar 01 '13 at 06:37
  • Alternatively, even try remove the path from glob completely, placing the image files in the same directory as the PHP script and using: `$files = glob('*.jpg');` – Mike Blouin Mar 01 '13 at 06:44
  • AHA! I changed `glob($dir . '/*.png');` to `glob($_SERVER['DOCUMENT_ROOT'] . $dir . '/*.png');` and it works! – Ky - Mar 01 '13 at 17:28
  • Does this display *different* images on the *same* page? I thought that browsers would access the URL only one time (although it is referenced several times in the source) – unor Mar 02 '13 at 09:10
  • A browser will only access another page file if the file is not already in the browser cache. We avoid this by using the HTTP Expires Header (set inside outputImage()). See http://stackoverflow.com/questions/11357430/http-expires-header-values-0-and-1 for more info. – Mike Blouin Mar 02 '13 at 11:47
1

Are you running Apache? There's a RandomLocation Apache module that deals with this kind of thing. Their docs describe almost the exact thing you're trying to do.

Ian Hunter
  • 9,466
  • 12
  • 61
  • 77