The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

Image::Base - base class for loading, manipulating and saving images.

SYNOPSIS

 # base class only
 package My::Image::Class;
 use base 'Image::Base';

DESCRIPTION

This class should not be used directly. Known inheritors are Image::Xbm and Image::Xpm and in see "SEE ALSO" below.

    use Image::Xpm ;

    my $i = Image::Xpm->new( -file => 'test.xpm' ) ;
    $i->line( 1, 1, 3, 7, 'red' ) ;
    $i->ellipse( 3, 3, 6, 7, '#ff00cc' ) ;
    $i->rectangle( 4, 2, 9, 8, 'blue' ) ;

Subclasses like Image::Xpm and Image::Xbm are stand-alone Perl code implementations of the respective formats. They're good for drawing and manipulating image files with a modest amount of code and dependencies.

Other inheritors like Image::Base::GD are front-ends to big image libraries. They can be handy for pointing generic Image::Base style code at a choice of modules and their various file formats. Some like Image::Base::X11::Protocol::Drawable even go to a window etc for direct display.

More Methods

If you want to create your own algorithms to manipulate images in terms of (x,y,colour) then you could extend this class (without changing the file), like this:

    # Filename: mylibrary.pl
    package Image::Base ; # Switch to this class to build on it.
    
    sub mytransform {
        my $self  = shift ;
        my $class = ref( $self ) || $self ;

        # Perform your transformation here; might be drawing a line or filling
        # a rectangle or whatever... getting/setting pixels using $self->xy().
    }

    package main ; # Switch back to the default package.

Now if you require mylibrary.pl after you've used Image::Xpm or any other Image::Base inheriting classes then all these classes will inherit your mytransform() method.

FUNCTIONS

new_from_image()

    my $bitmap = Image::Xbm->new( -file => 'bitmap.xbm' ) ;
    my $pixmap = $bitmap->new_from_image( 'Image::Xpm', -cpp => 1 ) ;
    $pixmap->save( 'pixmap.xpm' ) ;

Note that the above will only work if you've installed Image::Xbm and Image::Xpm, but will work correctly for any image object that inherits from Image::Base and respects its API.

You can use this method to transform an image to another image of the same type but with some different characteristics, e.g.

    my $p = Image::Xpm->new( -file => 'test1.xpm' ) ;
    my $q = $p->new_from_image( ref $p, -cpp => 2, -file => 'test2.xpm' ) ;
    $q->save ;

line()

    $i->line( $x0, $y0, $x1, $y1, $colour ) ;

Draw a line from point ($x0,$y0) to point ($x1,$y1) in colour $colour.

ellipse()

    $i->ellipse( $x0, $y0, $x1, $y1, $colour ) ;
    $i->ellipse( $x0, $y0, $x1, $y1, $colour, $fill ) ;

Draw an oval enclosed by the rectangle whose top left is ($x0,$y0) and bottom right is ($x1,$y1) using a line colour of $colour. If optional argument $fill is true then the ellipse is filled.

rectangle()

    $i->rectangle( $x0, $y0, $x1, $y1, $colour, $fill ) ;

Draw a rectangle whose top left is ($x0,$y0) and bottom right is ($x1,$y1) using a line colour of $colour. If $fill is true then the rectangle will be filled.

new()

Virtual - must be overridden.

Recommend that it at least supports -file (filename), -width and -height.

new_from_serialised()

Not implemented. Recommended for inheritors. Should accept a string serialised using serialise() and return an object (reference).

serialise()

Not implemented. Recommended for inheritors. Should return a string representation (ideally compressed).

get()

    my $width = $i->get( -width ) ;
    my( $hotx, $hoty ) = $i->get( -hotx, -hoty ) ;

Get any of the object's attributes. Multiple attributes may be requested in a single call.

See xy get/set colours of the image itself.

set()

Virtual - must be overridden.

Set any of the object's attributes. Multiple attributes may be set in a single call; some attributes are read-only.

See xy get/set colours of the image itself.

xy()

Virtual - must be overridden. Expected to provide the following functionality:

    $i->xy( 4, 11, '#123454' ) ;    # Set the colour at point 4,11
    my $v = $i->xy( 9, 17 ) ;       # Get the colour at point 9,17

Get/set colours using x, y coordinates; coordinates start at 0.

When called to set the colour the value returned is class specific; when called to get the colour the value returned is the colour name, e.g. 'blue' or '#f0f0f0', etc, e.g.

    $colour = xy( $x, $y ) ;  # e.g. #123456 
    xy( $x, $y, $colour ) ;   # Return value is class specific

We don't normally pick up the return value when setting the colour.

load()

Virtual - must be overridden. Expected to provide the following functionality:

    $i->load ;
    $i->load( 'test.xpm' ) ;

Load the image whose name is given, or if none is given load the image whose name is in the -file attribute.

save()

Virtual - must be overridden. Expected to provide the following functionality:

    $i->save ;
    $i->save( 'test.xpm' ) ;

Save the image using the name given, or if none is given save the image using the name in the -file attribute. The image is saved in xpm format.

add_colours()

Add colours to the image palette (if applicable).

    $i->add_colours( $name, $name, ...)

The drawing functions add colours as necessary, so this is just a way to pre-load the palette.

add_colours does nothing for images which don't have a palette or can't take advantage of pre-loading colour names. The base code in Image::Base is a no-op.

ATTRIBUTES

The attributes for new, get and set are up to the subclasses, but the common settings, when available, include

-width and -height (integers)

The size of the image. These might be create-only with a size given to new and then fixed. If the image can be resized then set of -width and/or -height does a resize.

-file (string)

Set by new reading a file, or load or save if passed a filename, or just by set in readiness for a future load or save.

-hotx and -hoty (integers, or maybe -1 or maybe undef)

The coordinates of the "hotspot" position. For images which can be a mouse cursor or similar this is the position of the active pixel for clicking etc. Eg. XPM and ICO (or CUR rather) formats have hotspot positions.

-zlib_compression (integer -1 to 9, or undef)

The compression level for images which use Zlib, such as PNG. 0 is no compression, up to 9 for maximum compression. -1 is the Zlib compiled-in default (usually 6). undef means no setting, for an image library default if it has one, or the Zlib default.

For reference, the PNG format doesn't record a compression level used, so -zlib_compression might be set for a save, but generally won't read back in a load.

ALGORITHMS

Lines

Sloping lines are drawn by a basic Bressenham line drawing algorithm with integer-only calculations. It ends up drawing the same set of pixels no matter which way around the two endpoints are passed.

Would there be merit in rounding odd numbers of pixels according to which way around line ends are given? Eg. a line 0,0 to 4,1 might do 2 pixels on y=0 and 3 on y=1, but 4,1 to 0,0 the other way around. Or better to have consistency either way around? For reference, in the X11 drawing model the order of the ends doesn't matter for "wide" lines, but for implementation-dependent "thin" lines it's merely encouraged, not required.

Ellipses

Ellipses are drawn with the midpoint algorithm. It chooses between two points x,y and x,y-1 according to whether the position x,y-0.5 is inside or outside the ellipse (and similarly x+0.5,y on the near-vertical parts).

The current ellipse code ends up with 0.5's in the values, which means floating point, but is still exact since binary fractions like 0.5 are exactly representable. Some rearrangement and factors of 2 could make it all-integer. The "discriminator" in the calculation may exceed 53-bits of float mantissa at around 160,000 pixels wide or high, possibly affecting the accuracy of the pixels chosen, but should be no worse than that.

Image Libraries

The subclasses like GD or PNGwriter which are front-ends to other drawing libraries don't necessarily use these base algorithms, but can be expected to something sensible within the given line endpoints or ellipse bounding box.

SEE ALSO

Image::Xpm, Image::Xbm, Image::Pbm, Image::Base::GD, Image::Base::PNGwriter, Image::Base::Text, Image::Base::Multiplex

Image::Base::Gtk2::Gdk::Drawable, Image::Base::Gtk2::Gdk::Pixbuf, Image::Base::Gtk2::Gdk::Pixmap, Image::Base::Gtk2::Gdk::Window

Image::Base::Prima::Drawable, Image::Base::Prima::Image

Image::Base::X11::Protocol::Drawable, Image::Base::X11::Protocol::Pixmap, Image::Base::X11::Protocol::Window

http://user42.tuxfamily.org/image-base/index.html

AUTHOR

Mark Summerfield. I can be contacted as <summer@perlpress.com> - please include the word 'imagebase' in the subject line.

COPYRIGHT

Copyright (c) Mark Summerfield 2000. All Rights Reserved.

Copyright (c) Kevin Ryde 2010, 2011.

This module may be used/distributed/modified under the LGPL.