AC-EasyRaster-GTK-1.1.3: GTK+ pixel plotting.

Graphics.EasyRaster.GTK

Contents

Description

This module provides pixel-oriented graphics operations. It defines an ImageBuffer type, which is a thin layer over a GTK+ Pixbuf. It then provides functions for doing pixel-oriented graphics on this without having to do a lot of bit-twiddling math by hand. It also provides for quickly and easily loading and saving images, and displaying them on the screen.

In the simplest case, you can import this module alone and never need to touch the actual GTK modules; however, this module provides access to the underlying GTK resources as well, in case you want to use it as part of a larger GTK program.

Note that displaying an image on screen requires you to run the GTK event loop. If you only want to load, save and process image files, you can completely ignore the GTK event loop. (You do still need to call init_system, however.)

Synopsis

System initialisation

init_system :: IO ()Source

Initialise the GTK runtime system. This function must be called before any other functions in this module. (If not, your program will likely summarily crash with an obscure error to stderr.)

Note that Gtk2hs by default will crash with a warning message if the program is compiled with the threaded RTS; this module disables that warning. However, be warned: You must only call the GTK-based functions from thread 0.

Types

type Coord = IntSource

The type of pixel coordinates.

type Channel = Word8Source

The type of pixel channels.

data ImageFileType Source

Used to indicate image file type.

Constructors

IFT_PNG

PNG image.

IFT_JPEG

JPEG image.

type_string :: ImageFileType -> StringSource

Convert an ImageFileType to a plain string (all lower-case).

data ImageBuffer Source

An ImageBuffer is a space-efficient grid of 24-bit RGB pixels (i.e., 8 bits per channel) that the GTK library can also access. (The latter gives us the ability to load/save/display the graphics, rather than just manipulate it in memory.)

Image buffer creation

ib_new :: (Int, Int) -> IO ImageBufferSource

Make a new ImageBuffer of the specified size. Valid coordinates will be in the range (0,0) to (x-1, y-1), with (0,0) being the top-left corner of the image.

ib_load :: FilePath -> IO ImageBufferSource

Load a graphics file into a newly created ImageBuffer. The file type is determined automatically (any type that GTK+ supports), as is the size for the ImageBuffer. (This can be queried later.)

Image buffer output

ib_save :: ImageBuffer -> ImageFileType -> FilePath -> IO ()Source

Save an ImageBuffer into a file with the specified file type. Note that the filename should include an appropriate suffix (e.g., .png). The type of file is determined by the ImageFileType argument, not by the filename.

Image buffer queries

ib_size :: ImageBuffer -> (Coord, Coord)Source

Query the size of an ImageBuffer. This returns the width and height in pixels. Valid coordinates for this ImageBuffer are from (0,0) to (x-1, y-1), where (x,y) is the value returned from ib_size.

Note that this is a pure function (since the size of an ImageBuffer is immutable).

ib_coords :: ImageBuffer -> [(Coord, Coord)]Source

Return a list containing all valid coordinates for this ImageBuffer. Useful when you want to process all pixels in the image; now you can just use mapM or whatever.

ib_coords2 :: ImageBuffer -> [[(Coord, Coord)]]Source

Return all valid coordinates as a list of lists instead of a single flat list. (In case you need to do something at the end of each row.)

ib_valid_coords :: ImageBuffer -> (Coord, Coord) -> BoolSource

Determine whether the specified pixel coordinates are valid for this ImageBuffer (i.e., check they're not off the edge of the image).

Pixel I/O

ib_write_pixel :: ImageBuffer -> (Coord, Coord) -> (Channel, Channel, Channel) -> IO ()Source

Overwrite the specified pixel with the specified colour (R, G, B).

Note that pixel coordinates are not checked, for efficiency reasons. However, supplying invalid pixel coordinates may result in behaviour ranging from corrupted graphical output to random program crashes. See Graphics.EasyRaster.GTK.Paranoid for a version of this function with bounds checking turned on.

ib_read_pixel :: ImageBuffer -> (Coord, Coord) -> IO (Channel, Channel, Channel)Source

Read the current (R, G, B) colour valid of the specified pixel.

Note that pixel coordinates are not checked, for efficiency reasons. However, supplying invalid pixel coordinates will at best result in gibberish being returned, and at worst a segmentation fault. See Graphics.EasyRaster.Paranoid for a version of this function with bounds checking turned on.

Image display

ib_display :: ImageBuffer -> String -> IO ()Source

This is a quick shortcut for displaying an image on screen. Given an ImageBuffer and a window title, this will display the image in a new window. Clicking the window's close button will call GTK's mainQuit function. For example,

 ib_display buf "My Window Title"
 main_loop

will display buf on screen and halt the program (or at least thread 0) until the user clicks the close button. Crude, but useful for quick testing.

ib_canvas :: ImageBuffer -> IO DrawingAreaSource

Returns a GTK+ canvas object which displays the graphcs in the ImageBuffer and will automatically repaint itself in response to damage.

GTK event loop

process_event :: IO ()Source

Process one GTK event if there are any waiting, otherwise do nothing.

wait_event :: IO ()Source

Process one GTK event. Wait for an event to arrive if necessary.

main_loop :: IO ()Source

Run the GTK "main loop" until GTK's mainQuit function is called. (Note that this means that thread 0 can do no other work while the main loop is running.)

Low-level GTK access

ib_pixbuf :: ImageBuffer -> PixbufSource

Return the underlying GTK Pixbuf used by an ImageBuffer. (In case you want to do something to it with GTK.)

Example code

The following short program should give you an idea of how to use this library. It draws a simple graphic and saves it to disk.

 module Main where

 import Graphics.EasyRaster.GTK

 main = do
   init_system
   ibuf <- ib_new (640, 480)
   mapM_ (\p -> ib_write_pixel ibuf p (colour p)) (ib_coords ibuf)
   ib_save ibuf IFT_PNG "Example1.png"

 colour :: (Coord, Coord) -> (Channel, Channel, Channel)
 colour (x, y) = (floor $ fromIntegral x / 640 * 255, floor $ fromIntegral y / 480 * 255, 0)