NAME
FLTK::Image - Basic image handling
Description
A rectangular buffer of pixels that can be efficiently drawn on the screen. The draw()
functions will copy (or "over" composite if there is alpha in the pixeltype()
) onto the output, transformed by the current transform.
NOTE: If you already have a set of pixels sitting in your own memory, drawimage()
can draw it and is \e much easier to use. You should use this class only if you will be drawing the same image multiple times, with no changes to the pixels.
The buffer is created and filled in by setting the type of pixels with setpixeltype()
, the size with setsize()
, and then calling buffer()
(note that setpixels()
calls buffer()
for you). The initial buffer is filled with undefined contents.
The best way to put data into the buffer is to make one or more calls to setpixels()
, to replace rectangular regions.
You can directly address the buffer()
to read and write the pixels. The size of the buffer is in buffer_width()
and buffer_height()
(this may be much larger than width()
and height()
) and the distance between lines is in buffer_linedelta()
. If you change any pixels you should call buffer_changed()
before the next draw()
.
Due to operating system limitations, buffer()
is usually not an array of pixeltype()
pixels. Instead setpixels()
converts pixels into a type the operating system can use. The type of pixels in the buffer is retured by buffer_pixeltype()
. This is really inconvienent, so you can also call the method force_ARGB32()
. This will cause buffer_pixeltype()
to return ARGB32
, so you can assume this at compile time. The implementation of Image may be less efficient (actually the overhead is zero on Windows and close to zero on most other systems).
If buffer()
has not been called, draw()
will call the fetch()
virtual method. It should call setpixeltype()
, setsize()
and setpixels()
. This is used to defer reading image files or decompressing data until needed. fetch()
will also restore the buffer contents to the original values if you have written to the buffer. If fetch()
does not allocate a buffer, draw()
will draw a solid rectangle in the current color.
Because Image is a subclass of Symbol, it may be used as a Widget::image()
or as the box()
in a Style. If you give it a name it can be drawn with @name;
in a label. If resized, the Symbol::_draw()
method will use the inset()
call to decide on edge thicknesses and will dice the image up into 9 individually-scaled pieces, which is very useful for GUI buttons and background images (this is similar to how Flash draws buttons).
There are a number of subclasses such as jpgImage and pngImage that display compressed image data, either from in-memory data buffers or from files.
Functions
buffer
my $data = $image->buffer( );
-
Creates (if necessary) and returns a pointer to the internal pixel buffer. This is probably going to be shared memory with the graphics system, it may have a different pixeltype, size, and linedelta than the
Image
. If you are able to figure out the type you can read and write the pixels directly.
buffer_changed
$image->buffer_changed( );
-
Call this if you modify the contents of
buffer()
. On some systems the memory is not actually shared with the window system, and this will causedraw()
to copy the buffer to the system's memory.setpixels()
calls this for you.
buffer_depth
my $depth = $image->buffer_depth( );
-
Returns the number of bytes per pixel stored in
buffer()
. This is the same asdepth(buffer_pixeltype())
.
buffer_height
my $height = $image->buffer_height( );
-
Return the height in pixels of
buffer()
;
buffer_linedelta
my $distance = $image->buffer_linedelta( );
-
Return the distance between each row of pixels in
buffer()
.
buffer_pixeltype
my $pt = $image->buffer_pixeltype( );
-
Return the type of pixels stored in
buffer()
. Likely to beARGB32
. On older (non-XRender) X system the types 1 and 2 indicate 1 and 2-byte data, but there is no api to figure out anything more about this data.
buffer_width
my $width = $image->buffer_width( );
-
Return the width in pixels of
buffer()
.
clear_forceARGB32
depth
my $d = $image->depth( );
-
Same as
FLTK::depth($img->pixeltype())
, this returns how many bytes each pixel takes in the buffer sent tosetpixels()
.
destroy
$image->destroy( );
-
Destroys the
buffer()
and any related system structures.
draw
$image->draw( $x, $y );
-
Does
measure()
and then$image->draw(FLTK::Rectangle->new( 0, 0, $w, $h), FLTK::Rectangle->new( ( $x, $y, $w, $h ) )
. Thus the top-left corner is placed at$x, $y
and no scaling (other than due to the current transformation) is done. $image->draw( $rect );
-
Resizes the image to fit in the rectangle. This is what is called if the image is used as a label or box type.
If the destination rectangle is not the same size,
inset()
is used to figure out the edge thicknesses. The image is then diced into 9 rectangles in a 3x3 grid by the insets, and each piece is scaled individually. This is very useful for scaling paintings of buttons. Note that if the insets are zero (the default) then the whole image is scaled as one piece. If you want,inset()
can return different thicknesses depending on the size, producing very interesting scaling.It is possible this will use
drawflags(INACTIVE)
to gray out the image in a system-specific way. $image->draw( $from, $destination );
-
Draws the subrectangle
from
of the image, transformed to fill the rectangledestination
(as transformed by the CTM). If the image has an alpha channel, an "over" operation is done.Due to lame graphics systems, this is not fully operational on all systems:
X11 without XRender extension: no transformations are done, the image is centered in the output area.
X11 with XRender: rotations fill the bounding box of the destination rectangle, drawing extra triangular areas outside the source rectangle. Somewhat bad filtering when making images smaller. xbmImage does not transform.
Windows: Only scaling, no rotations. Bad filtering. xbmImage does not do any transformations.
OS/X: works well in all cases.
fetch_if_needed
fills_rectangle
forceARGB32
h
my $height = $image->h( );
-
Same as
height()
.
height
my $h = $image->height( );
-
Return the height of the image in pixels. You can change this with <
setsize()
|/"setsize">.
linebuffer
my $data = $image->linebuffer( $y );
-
Return a pointer to a buffer that you can write up to
width()
pixels inpixeltype()
to and then callsetpixels($buffer, $y)
with. This can avoid doing any copying of the data if the internal format andpixeltype()
are compatable, because it will return a pointer directly into the buffer and setpixels will detect this and do nothing.
make_current
$image->make_current( );
-
See GSave.
mem_used
my $bytes = $image->mem_used( );
-
Returns how much memory the image is using for
buffer()
and for any other structures it created. Returns zero ifbuffer()
has not been called.
new
my $self = $image->new( $name );
-
The default constructor sets
pixeltype()
toRGB32
(0x00rrggbb) andwidth()
andheight()
to 12. This means that 12x12 square with the current color will be drawn if not able to draw anything else.The optional
name
is passed to the Symbol constructor and allows the image to be drawn by putting@name;
into a label.
pixeltype
my $type = $image->pixeltype( );
-
Returns the type of pixels that are put into the image with
setpixels()
. You can change this withsetpixeltype()
. It is possible the internal data is in a different type, usebuffer_pixeltype()
to find out what that is.
refetch
$image->refetch( );
-
Cause
fetch()
to be called again. This is useful for a file image if the file name or contents have changed.
set_forceARGB32
setimage
$image->setimage( $source, $pixeltype, $w, $h, $linedelta );
-
This is equivalent to...
$image->setsize( $w, $h ); $image->setpixeltype( $p ); $image->setpixels( $source, FLTK::Rectangle->new( $w, $h ), $iamge->linedelta );
...except, if possible,
source
is used asbuffer()
(throwing away the current data!). This will happen if thepixeltype
andlinedelta
are of types that it can handle unchanged and if the image memory does not need to be allocated by the system. $image->setimage( $source, $pixeltype, $w, $h );
-
Figures out
$linedelta
for you as$w * $image->depth($p)
.
setpixels
$image->setpixels( $data, $rect, $linedelta );
-
Replace the given rectangle of
buffer()
with the supplied data, which must be in thepixeltype()
.linedelta
is the distance between each row of pixels indata
. The rectangle is assummed to fit inside thewidth()
andheight()
. $image->setpixels( $data, $rect );
-
Figures out the linedelta for you as
$image-
depth() * $rect->w()>. $image->setpixels( $data, $y );
-
Same as
$image->setpixels($data, FLTK::Rectangle->new(0, $y, $image->width(), 1))
, sets one entire row of pixels.
setpixeltype
$image->setpixeltype( $pixeltype );
-
Change the stored pixeltype. If it is not compatable then the Image is destroyed.
setsize
$image->setsize( $w, $h );
-
Change the size of the stored image. If it is not compatable with the current data size (generally if it is larger) then the Image is destroyed.
total_mem_used
my $bytes = $image->total_mem_used( );
-
Sum of all
mem_used()
calls to allImages
. This is used by SharedImage to decide when to clear out cached images.
w
my $width = $image->w( );
-
Same as
width()
.
width
my $w = $image->width( );
-
Return the width of the image in pixels. You can change this with
setsize()
.
See Also
Author
Sanko Robinson <sanko@cpan.org> - http://sankorobinson.com/
License and Legal
Copyright (C) 2008-2010 by Sanko Robinson <sanko@cpan.org>
This program is free software; you can redistribute it and/or modify it under the terms of The Artistic License 2.0. See the LICENSE file included with this distribution or notes on the Artistic License 2.0 for clarification.
When separated from the distribution, all original POD documentation is covered by the Creative Commons Attribution-Share Alike 3.0 License. See the clarification of the CCA-SA3.0.