The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Image::Magick::Thumbnail::NotFound - Create thumbnails as http requests for them fail

SYNOPSIS

        # 1) in your .htaccess file, add/modify this line:
        
        ErrorDocument 404 /cgi-bin/error.cgi
        
        
        # 2) in /cgi-bin/error.cgi:
        
        use Image::Magick::Thumbnail::NotFound;
                
        new Image::Magick::Thumbnail::NotFound; # used as auto, no need to receive object.

        # if this is a normal 404 response..    
        print "Content-type: text/html\n\n";
        print "The requested resource returned a 404, File Not Found error.";

        exit;
        

        # 3) Try it out, in your html 

        <a href="/images/1.jpg">
                <img src="/.thumbnails/images/1.jpg">
        </a>

        # on in your web browser
        
        http://yoursiteaddress/.thumbnails/images/1.jpg
        

DESCRIPTION

This was written to create thumbnails on a per request basis. That is, create a thumbnail on an Apache 404 error.

To be more specific, it makes thumbnails as http requests for them fail, and only when they fail.

Thumbnails are stored mirroring the structure of your website, under the thumbnails directory (/.thumbnails by default). A mirror tree structure of a website is created.

METHODS

Only method new() can be made use of if auto is set to 0. See EXAMPLES.

new()

Parameters are supplied in an anonymous hash. There are no required parameters. Optional parameters follow.

thumbnails_directory

        Let's you change where your thumbnails will be. This is I<relative> 
        to $ENV{DOCUMENT_ROOT}/index.html, default is /.thumbnails/

size

        If a thumbnail is made, this is the maximum pixel height or width that it will be

square

        This will make square thumbnails- Undistorted, sides chopped accordingly.
        Default is 0, uses C<Image::Magick::Square>.

auto

        by default a thumbnail is creted from the source image, given to the request, and
        saved to disk. If you want to do something else with the thumbnail object before
        you save it, or some for some reason you don't even want to save it.. set this to
        auto => 0 and the o     
        ater, the
        default is 0, so if a failed thumbnail request is detected, the thumbnail
        is made and output to browser (to the request caller, your html, whatever)
        

quality

        jpeg quality of thumbnail

debug

        print status data to STDERR

save_thumbnail()

Saves thumbnail, accepts no arguments. Called inernally if auto is left on default.

display()

Displays to requesting entity, accepts no arguments.

get_status()

Returns status anonymous hash. Key 'steps' contains an anonymous array with the order of the events (request, thumbnail_created, etc). Which are also the rest of the keys in the status anon hash.

display_and_exit()

Display and exit script. Accepts no arguments. Called inernally if auto is left on default.

USAGE

After installing this module you will need two things to create thumbnails on the fly. A line in a .htaccess file, and a script to handle your 404 responses (referred to in this document as error.cgi ).

.htaccess

In your $ENV{DOCUMENT_ROOT} make sure you have an .htaccess file In it must be this line:

        ErrorDocument 404 /cgi-bin/error.cgi

This is what makes apache call error.cgi when a request for a resource fails. In turn, error.cgi will examine the request uri to see if the failed request seems to be for a thumbnail.

error.cgi

In your error.cgi file you must have this:

        #!/usr/bin/perl 
        use Image::Magick::Thumbnail::NotFound;

        new Image::Magick::Thumbnail::NotFound; # will exit on success

        print "Content-Type: text/html\n\n";
        print "That resource is missing.";
        exit;

EXAMPLES

The following examples are error.cgi examples.

EXAMPLE A

Use a directory that will reside in (htdocs) /.thumbs instead (will be created). Also make the thumbnails 125px squares. And show debug info (status steps). In your error.cgi:

        use strict;

        use Image::Magick::Thumbnail::NotFound;

        new Image::Magick::Thumbnail::NotFound ({
                thumbnails_directory    => '/.thumbs',          
                size            => 125,                 
                square  => 1,   
                debug           => 1,
        });

        # if a failed request for a thumbnail was not made, continue..  
        print "Content-type: text/html\n\n";
        print "That resource is not here.";
        exit;

EXAMPLE B

Set auto off. Let's put a border around our thumbnail after it is created, before we save it to disk. We will let it default to /.thumbnails directory. We will also be using default size, etc. Show debug info to STDERR. In your error.cgi:

        use strict;

        use Image::Magick::Thumbnail::NotFound;

        my $thumb = new Image::Magick::Thumbnail::NotFound ({
                auto => 0,      
        });

        # we have to check that the 404 error was for an image thumbnail
        if ($n->get_status('requested')){
        
                # we treat $n->{thumb} just like we do a regular Image::Magick loaded image 
                $n->{thumb}->Border(geometry=>'1x1', color=>'black');
                
                # save it - optional.. strongly encoluraged though! 
                $n->save_thumbnail();
                
                # show it and exit. 
                $n->display_and_exit();
        }       
        
        #  continue..   
        print "Content-type: text/html\n\n";
        print "That resource is not here.";
        exit;
        

LOCATION OF THUMBNAILS

If you have images in (htdocs) /tmp like so:

        tmp
        |-- a.jpg
        `-- one
            `-- b.jpg

Your thumbnails (with default settings) will be in:

        .thumbnails/
        `-- tmp
            |-- a.jpg
            `-- one
               `-- b.jpg

MOTIVATION

This really separates thumbnail 'management' from the rest of your website. This can be use stand alone with static html pages, as with scripts. All the rest of your website can make believe the thumbnails are there as if they were hand made and uploaded in photoshop.

The edge in this system is that it uses the 404 error to call it. Thus, you do not call a thumbnail script like 'thumbnail_please.cgi?thumb=/bla/bla.jpg', nor do you have to pre run anything to make them. As the thumbnails are requested, if they are not found on the server, they are made. No error to the end user is reported. The next call for the same thumbnail will not go through the script, since the request will no longer generate a 404 (file not found) error.

By default this module needs little work on your part. It will detect if a request failed for a thumbnail and if so create it, show it, and save it, so next time there is no 404 error.

But- This script does not hog the Image::Magick object, you can disable auto, and make changes to the thumbnail as you wish- before you save it to the disk, display, or both.

NOTES

Sample public_html/.htacces file and cgi-bin/error.cgi files are included in the download.

If only want a request in /.thumbnails/ to call this at all, then place your .htaccess file in /.thumbnails/.htaccess

I've tried this software on quite differnt servers, Suse, Fedora, and FreeBSD. If you have any comments bugs, etc. Please do contact me, and I will do the best I can to keep this code up to date.

TODO

A down of this system is that if a thumbnail is made for an image that is no longer there, you have to manually delete the thumbnail, or you just have orphans lingering around. You will have to recreate the .htaccess file. You can safely delete the whole thumbnails directory and have it automatically recreated, that's a present solution.

WISHLIST

Would if be of use to anyone to make an "orphans_reaper" script? Maybe a sample cron entry for that?

Per directory configuration files, with size, style (square?), and quality settings. The hesitation is the added overhead.

Have more thumbnail options? Too out of scope.

BUGS

I had a query string encrypted with Crypt::CBC, it generated an error and this took me to error.cgi, there was a problem in parsing the query string to match a request (it looks to see if a failed request uri matches jpg, gif, etc in the end.

SEE ALSO

Image::Magick::Thumbnail

AUTHOR

Leo Charre, <leo@leocharre.com>

COPYRIGHT AND LICENSE

Copyright (C) 2006 by Leo Charre

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.8.6 or, at your option, any later version of Perl 5 you may have available.