One random photo from your flickr-stream

Note: Since ANY badge-url will work you can use randomFlickr with whatever photo you feel like, if your badge fetches the most recent photo of a category that’s what will be used, you’re only limited by what the badge-url can do

I’m a heavy flickr-user, trashing it with all my snapshots, useless party-pics, all kinds of stuff. And I like to use my flickr photos outside flickr, e.g. on my personal blog. Now there’s the flickr API and all kinds of wrappers and kits, but all of this is kind of hardcore stuff if the task as simple as: Gimme one random photo from my stream. randomFlickr.class can do this for you.

Download V 0.6

Donate (PayPal)

Applying filters requires PHP5+. There’s a PHP4 version available, too. GD Library 2 is required for image resizing, that should be included as a standard extension. If you plan to do anything above that I’d suggest having a look at the various available PHP-tools for flickr:

But if all you want to do is fetch a single photo then have a look at the randomFlickr Demo. Now for the documentation.

The initial bright idea was brought to me be an article I can’t seem to find anymore, but I’ll try to give proper credit. The class utilizes a flickr-feature: Javascript-badges. There’s a page to create a badge on flickr, which results in a JavaScript / CSS codeblock. While that works it has a few major downsides:

  • it’s javascript where javascript definitely isn’t appropriate
  • it doesn’t give control over the images themselves
  • it only can fetch kind of small images

But what it does is it provides the necessary image data we then can process with PHP. For the development I used this badge-url I set up to fetch one random medium-sized image from my whole photostream. Click the link to see what the returned HTML/JS-Stuff looks like.

Focus

While building the class I always had one thing in mind: This is for one image, nothing more, so the class was built to offer a nice variety of things to do with that one picture, however doesn’t support anything beyond. The final result should achieve three goals:

  • light-weight
  • easy to use
  • easy to integrate

Basic usage

Most of the code is kind of self-explanatory and, as I like it, heavily documented, so best you just browse through the class file you can download from the demo-page. Now for the class. It’s kind of hard to wrap my mind inside-out back to the start now that all is done, so I’ll do it the other way round and explain what’s happening from the usage point-of-view, that should work. So let’s have a look at how the thing is integrated on a webpage:

/flickpic/index.php
  1. <?php
  2. $badge  = 'http://www.flickr.com/badge_code_v2.gne?count=1&amp;display=random&amp;size=m&amp;layout=x&amp;source=user&amp;user=7353617%40N04';
  3. $width  = 400;
  4. $height = 240;
  5. $gray   = true;
  6. include_once('flickpic.php');
  7. ?>

This is the more ‘dummy-friendly’ way to integrate, since there’s hardly anything related to coding. Just replace the badge url with whatever badge you want, modify the size settings and you’re fine. The $gray-thing converts the image to grayscale, if set to true. Using the whole thing this way will result in an image linked to it’s flickr-page and doesn’t require anyone to write any php, or to alter any files. We’ll shortly reveal the real magic, so hold on for a more programmer-like approach giving you the details you want.

A few more details: flickpick.php

/flickpic/flickpic.php
  1. if ( !isset($_REQUEST['imageUrl']) )
  2. {
  3.     try
  4.     {
  5.         $x = new randomFlickr($user);
  6.         if ( $badge )
  7.         {
  8.             $x->setBadgeUrl($badge);
  9.         }
  10.         $x->fetch();
  11.     }

Line 08 checks if an image-url has already been submitted. That’s not the case when including the file, so what’s about to be done is to display some nice HTML to display the image. try – catch is needed due the methods throw exceptions. In line 12 the randomFlickr-object is being created using a variable $user. This variable isn’t specified here, therefore will just be ignored. Then we check if a badge-url has been specified in $badge. If so, we change the object’s badge url according. Time to fetch some data on line 17.

A few words about the fetch()-method. It will check if there’s a user id specified (the ugly flickr user-id string, that is, due the badges don’t seem to work with the usernames). If so, it uses the default badge-url for 1 random image and passes that user-id. Easy. If there’s no user specified, the badge-url will be used as-is. That way there are four possibilities to get a valid result:

  1. specify a user and rely on the default url
  2. specify a full badge-url
  3. specify a user and a badge url
  4. specify nothing and pass the user-id to fetch() (will override a stored username for this one call only)

The method doesn’t really do much, just usual dirty regex-info-fetching, no great inventions there. Most important, it doesn’t retrieve the actual image, it just sets up meta-information, like dimensions, title and that kind of stuff. So let’s go on in the code of flickpic.php:

/flickpic/flickpic.php
  1. $src_post = ( $width ? "&amp;width=$width" : '' ) . ( $height ? "&amp;height=$height" : '' ) . ( $gray ? '&amp;grayscale' : '');
  2. $http = 'http://'. $_SERVER['HTTP_HOST'] . dirname($_SERVER['REQUEST_URI'] . 'x') .'/'. $relpath;
  3.  
  4. print ( $x->getHtml(false, array('src_pre' => $http .'flickpic.php?imageUrl=', 'src_post' => $src_post, 'fixwidth' => $width, 'fixheight' => $height)))

The first line builds a parameter src_post, the next line uses the current directory (the ‘x’ is added to “simulate” a file if the home dir is being requested, otherwise we’s loose one directory here – just try, it’s stupid to explain) plus any specified relative path to build the path to this file for the output-generation later. Now the next line does some magic. It prints the result of the getHtml()-method which, obviously, generates HTML code. Let’s have a look at the method and the parameter, due this is one of the most flexible parts of the whole thing:

HTML is what we need

/flickpic/randomFlickr.class.php
  1. //  @param  string  $sFormat    the new format – anything you want, that is

So there’s the first parameter $sFormat. This parameter will, if specified, override the object’s default HTML-template (this can also be done permanently using the setDefaultHtml()-method). HTML-Template? Yessss! The class uses this default HTML to create the output: <a href=”{url}” title=”{title}” class=”{class}”><img src=”{src}” title=”{title}” alt=”{title}” {html_dim} /></a>, so nothing more than a link-wrapped image. BUT note the template-variables enclosed by {}. There’s a whole bunch of them available, namely:

  • {title} title fetched from flickr
  • {url} url for the link the image is wrapped with
  • {src} image’s src
  • {html_dim} image’s dimensions as html attributes (see getHtml() for details)
  • {width} image’s width
  • {height} image’s height
  • {hwidth} width value used for the html-attributes (image’s width or fix width)
  • {hheight} height value used for the html-attributes (image’s width or fix width)
  • {fixwidth} value passed to getHtml() to use for width-attribute
  • {fixheight} value passed to getHtml() to use for height-attribute
  • {class} a string for a css-class

All these variables can be used in custom HTML-Templatecode to suite all kinds of possible ajax or whatnot needs, thus making the display as flexible as you like. But back to getHtml(). There’s a list of special parameters to pass as indices of an associative array (second method parameter $aParams):

  • ‘fixwidth’: for the width=”" attribute of the <img>
  • ‘fixheight’: for the height=”" attribute of the <img>
  • ‘nativedim’: the image’s real dimensions will be used for width=”" & height=”"
  • ‘class’: for the <a>, by default
  • ‘src_pre’: inserted just before the image’s src
  • ‘src_post’: inserted right after the image’s src
  • ‘url_pre’: inserted right before the url to the image

Using those values the image source can be utilized as a parameter for a PHP script (that’s what flickpic.php does), giving us <strong>much</strong> more possibilities to control it’s appearance. All possibilites, that is. Now on to that part that’s responsible for generating the actual image:

Now for the image

/flickpic/flickpic.php
  1. $x = new randomFlickr();
  2. $x->init('', urldecode($_REQUEST['imageUrl']));
  3.  
  4. if ( isset($_REQUEST['width']) || isset($_REQUEST['height']) )
  5. {
  6.     $x->resize(( isset($_REQUEST['width'])   ? $_REQUEST['width']  : false ),
  7.     ( isset($_REQUEST['height'])  ? $_REQUEST['height'] : false ));
  8. }
  9.  
  10. if ( isset($_REQUEST['grayscale']) )
  11. {
  12.     $x->applyFilter(IMG_FILTER_GRAYSCALE);
  13. }
  14.  
  15. $x->send( 90 );

There you go. First of all a new randomFlickr-object is being created (the script is called again, so there’s no object there). Then the actual image is loaded with the init()-method. This method either uses the data already present within the object or any passed url (the urldecode() is necessary because the script generates XML-validating URLs, thus urlencoding all parameters. By the way the method can also be used to fetch any non-flickr image, if you only want to use it for the image manipulation the class offers). The init()-method accepts two parameters. The first one is for the image size. If not specified, the default size (large) will be used. Then for the probably most important feature the class has to offer: Intelligent image resizing:

  • Only width / height specified: The image will be resized proportionally
  • width & height specified: The image will be resized proportionally to fill the whole format, then will be cropped to it’s center

This way you can show your pictures in any unusual format, what’s not only cool but also handy if it comes to fitting them into your design. On with the code. The next thing we’re doing is we check for the grayscale-variable. If it’s set we apply the grayscale filter (we’re clever, aren’t we?). The applyFilter() method is a full-featured wrapper for the imagefilter-function, so have fun doing stuff!

Finally the last line sends the appropriate headers and the image data itself. So the endresult is kind of a recursive script (probably not, but sounds sophisticated) that doesn’t need much of editing to work for anyone, but provides a lot of flexibility if you’re willing to play around in flickpic.php.

Version History

  • 2008-04-02: V0.6

    There’s new options to choose different source-sizes. Specifying $size = “auto” will let the script guess which version to use based on the destination dimensions. This, however, may only work for close-to-standard formats, you might want to either leave everything as it is if it’s working or use one of the new constants to explicitly define which source to use:

    • xxs = 75px by 75px
    • xs = 100px by X
    • s = 240px by X
    • m = 500px by X
    • l = 1024px by X
    • xl = your uploaded file

    Note that flickr always uses the bigger side to scale the sizes, so portrait-format images will be scaled to 1024/500/240/100 Pixels height, while landscape-format images will be scaled to 1024/500/240/100 Pixels width. The three smaller sizes are the ones being used by flickr itself and are fixed-size.
    Oh, and I switched the Demo-Page from XHTML 1.1 back to XHTML 1.0, due to the inability of some browsers to handle the application/xml mime-type. Welcome to randomFlickr, Win IE6 Users.

  • 2008-03-19: V0.5

    now falling back on CURL if allow_url_fopen is disabled. As the title says the script now checks if allow_url_fopen is enabled, if not it tries to fall back on the CURL-library. One of both should be available on every hosting plan and I hope compatibility increased.

  • 2007-12-07: V0.4

    PHP4-Version: There now is also a PHP4-Version. Please note that image-filters are only available in PHP5, thus the PHP4 version can’t convert your images to grayscale, thus resizing + cropping work perfectly fine.