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

NAME

CSS::SpriteMaker - Combine several images into a single CSS sprite

VERSION

Version 0.15

SYNOPSIS

    use CSS::SpriteMaker;

    my $SpriteMaker = CSS::SpriteMaker->new(
        verbose => 1, # optional

        #
        # Options that impact the lifecycle of css class name generation
        #
        # if provided will replace the default logic for creating css classnames
        # out of image filenames. This filename-to-classname is the FIRST step
        # of css classnames creation. It's safe to return invalid css characters
        # in this subroutine. They will be cleaned up internally.
        #
        rc_filename_to_classname => sub { my $filename = shift; ... } # optional

        # ... cleaning stage happens (all non css safe characters are removed)

        # This adds a prefix to all the css class names. This is called after
        # the cleaning stage internally. Don't mess with invalid CSS characters!
        #
        css_class_prefix => 'myicon-',

        # This is the last step. Change here whatever part of the final css
        # class name.
        #
        rc_override_classname => sub { my $css_class = shift; ... } # optional
    );

    $SpriteMaker->make_sprite(
        source_images  => ['/path/to/imagedir', '/images/img1.png', '/img2.png'];
        target_file => '/tmp/test/mysprite.png',
        layout_name => 'Packed',    # optional
        remove_source_padding => 1, # optional
        add_extra_padding => 31,    # optional +31px padding around all images
        format => 'png8',           # optional
    );

    $SpriteMaker->print_css();

    $SpriteMaker->print_html();

OR

    my $SpriteMaker = CSS::SpriteMaker->new();

    $SpriteMaker->make_sprite(
       source_dir => '/tmp/test/images',
       target_file => '/tmp/test/mysprite.png',
    );

    $SpriteMaker->print_css();

    $SpriteMaker->print_html();

OR

    my $SpriteMaker = CSS::SpriteMaker->new();

    $SpriteMaker->compose_sprite(
        parts => [
            { source_dir => 'sample_icons',
              layout_name => 'Packed',
              add_extra_padding => 32       # just add extra padding in one part
            },
            { source_dir => 'more_icons',
                layout => {
                    name => 'FixedDimension',
                    options => {
                        'dimension' => 'horizontal',
                        'n' => 4,
                    }
                }
            },
        ],
        # the composing layout
        layout => {
            name => 'FixedDimension',
            options => {
                n => 2,
            }
        },
        target_file => 'composite.png',
    );

    $SpriteMaker->print_css();

    $SpriteMaker->print_html();

ALTERNATIVELY

you can generate a fake CSS only containing the original images...

    my $SpriteMakerOnlyCss = CSS::SpriteMaker->new();

    $SpriteMakerOnlyCss->print_fake_css(
        filename => 'some/fake_style.css',
        source_dir => 'sample_icons'
    );

DESCRIPTION

A CSS Sprite is an image obtained by arranging many smaller images on a 2D canvas, according to a certain layout.

Transferring one larger image is generally faster than transferring multiple images separately as it greatly reduces the number of HTTP requests (and overhead) necessary to render the original images on the browser.

PUBLIC METHODS

new

Create and configure a new CSS::SpriteMaker object.

The object can be initialised as follows:

    my $SpriteMaker = CSS::SpriteMaker->new({
        rc_filename_to_classname => sub { my $filename = shift; ... }, # optional
        css_class_prefix      => 'myicon-',                            # optional
        rc_override_classname => sub { my $css_class = shift; ... }    # optional
        source_dir => '/tmp/test/images',       # optional
        target_file => '/tmp/test/mysprite.png' # optional
        remove_source_padding => 1,             # optional
        add_extra_padding     => 1,             # optional
        verbose => 1,                           # optional
    });
    

Default values are set to:

remove_source_padding : false,
verbose : false,
format : png,
css_class_prefix : ''

The parameter rc_filename_to_classname is a code reference to a function that allow to customize the way class names are generated. This function should take one parameter as input and return a class name

compose_sprite

Compose many sprite layouts into one sprite. This is done by applying individual layout separately, then merging the final result together using a glue layout.

    my $is_error = $SpriteMaker->compose_sprite (
        parts => [
            { source_images => ['some/file.png', 'path/to/some_directory'],
              layout_name => 'Packed',
            },
            { source_images => ['path/to/some_directory'],
              layout => { 
                  name => 'DirectoryBased',
              }
              include_in_css => 0,        # optional
              remove_source_padding => 1, # optional (defaults to 0)
              add_extra_padding     => 40, # optional, px (defaults to 0px)
            },
        ],
        # arrange the previous two layout using a glue layout
        layout => {
            name => 'FixedDimension',
            dimension => 'horizontal',
            n => 2
        }
        target_file => 'sample_sprite.png',
        format => 'png8', # optional, default is png
    );

Note the optional include_in_css option, which allows to exclude a group of images from the CSS (still including them in the resulting image).

make_sprite

Creates the sprite file out of the specifed image files or directories, and according to the given layout name.

    my $is_error = $SpriteMaker->make_sprite(
        source_images => ['some/file.png', path/to/some_directory],
        target_file => 'sample_sprite.png',
        layout_name => 'Packed',

        # all imagemagick supported formats
        format => 'png8', # optional, default is png
    );

returns true if an error occurred during the procedure.

Available layouts are:

  • Packed: try to pack together the images as much as possible to reduce the image size.

  • DirectoryBased: put images under the same directory on the same horizontal row. Order alphabetically within each row.

  • FixedDimension: arrange a maximum of n images on the same row (or column).

Creates and prints the css stylesheet for the sprite that was previously produced.

You can specify the filename or the filehandle where the output CSS should be written:

    $SpriteMaker->print_css(
       filehandle => $fh, 
    );

OR

    $SpriteMaker->print_css(
       filename => 'relative/path/to/style.css',
    );

Optionally you can provide the name of the image file that should be included in the CSS file instead of the default one:

    # within the style.css file, override the default path to the sprite image
    # with "custom/path/to/sprite.png".
    #
    $SpriteMaker->print_css(
       filename => 'relative/path/to/style.css',
       sprite_filename => 'custom/path/to/sprite.png', # optional
    );

NOTE: make_sprite() must be called before this method is called.

Fake a css spritesheet by generating a stylesheet containing just the original images (not the ones coming from the sprite!)

    $SpriteMaker->print_fake_css(
       filename        => 'relative/path/to/style.css',
       fix_image_path => {
           find: '/some/absolute/path',  # a Perl regexp 
           replace: 'some/relative/path'
       }
    );

NOTE: unlike print_css you don't need to call this method after make_sprite.

Creates and prints an html sample page containing informations about each sprite produced.

    $SpriteMaker->print_html(
       filehandle => $fh, 
    );

OR

    $SpriteMaker->print_html(
       filename => 'relative/path/to/index.html',
    );

NOTE: make_sprite() must be called before this method is called.

get_css_info_structure

Returns an arrayref of hashrefs like:

    [
        {
            full_path => 'relative/path/to/file.png',
            css_class => 'file',
            width     => 16,  # pixels
            height    => 16,
            x         => 173, # offset within the layout
            y         => 234,
        },
        ...more
    ]

This structure can be used to build your own html or css stylesheet for example.

NOTE: the x y offsets within the layout, will be always positive numbers.

PRIVATE METHODS

_generate_css_class_names

Returns a mapping id -> class_name out of the current information structure.

It guarantees unique class_name for each id.

_image_locations_to_source_info

Identify informations from the location of each input image, and assign numerical ids to each input image.

We use a global image identifier for composite layouts. Each identified image must have a unique id in the scope of the same CSS::SpriteMaker instance!

_get_image_id

Returns a global numeric identifier.

_locate_image_files

Finds the location of image files within the given directory. Returns an arrayref of hashrefs containing information about the names and pathnames of each image file.

The returned arrayref looks like:

    [   # pathnames of the first image to follow
        {
            name => 'image.png',
            pathname => '/complete/path/to/image.png',
            parentdir => '/complete/path/to',
        },
        ...
    ]

Dies if the given directory is empty or doesn't exist.

_get_stylesheet_string

Returns the stylesheet in a string.

_generate_css_class_name

This method generates the name of the CSS class for a certain image file. Takes the image filename as input and produces a css class name (excluding the prepended ".").

_ensure_filehandle_write

Inspects the input %options hash and returns a filehandle according to the parameters passed in there.

The filehandle is where something (css stylesheet for example) is going to be printed.

_ensure_sources_info

Makes sure the user of this module has provided a valid input parameter for sources_info and return the sources_info structure accordingly. Dies in case something goes wrong with the user input.

Parameters that allow us to obtain a $rh_sources_info structure are:

- source_images: an arrayref of files or directories, directories will be visited recursively and any image file in it becomes the input.

If none of the above parameters have been found in input options, the cache is checked before giving up - i.e., the user has previously provided the layout parameter, and was able to generate a sprite.

_ensure_layout

Makes sure the user of this module has provided valid layout options and returns a $Layout object accordingly. Dies in case something goes wrong with the user input. A Layout actually runs over the specified items on instantiation.

Parameters in %options (see code) that allow us to obtain a $Layout object are:

- layout: a CSS::SpriteMaker::Layout object already; - layout: can also be a hashref like

    {
        name => 'LayoutName',
        options => {
            'Layout-Specific option' => 'value',
            ...
        }
    }

- layout_name: the name of a CSS::SpriteMaker::Layout object.

If none of the above parameters have been found in input options, the cache is checked before giving up - i.e., the user has previously provided the layout parameter...

_get_image_properties

Return an hashref of information about the image at the given pathname.

_compose_sprite_with_glue

Compose a layout though a glue layout: first each image set is layouted, then it is composed using the specified glue layout.

_compose_sprite_without_glue

Compose a layout without glue layout: the previously lay-outed image set becomes part of the next image set.

_generate_color_histogram

Generate color histogram out of the information structure of all the images.

_verbose

Print verbose output only if the verbose option was passed as input.

LICENSE AND COPYRIGHT

Copyright 2013 Savio Dimatteo.

This program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License.

See http://dev.perl.org/licenses/ for more information.