uni-htk-2.2.0.0: HTk/Components/Image.hs
{-# LANGUAGE FlexibleInstances #-}
-- | This module provides access to image resources from files or base64
-- encoded strings.
module HTk.Components.Image (
HasPhoto(..),
Image,
newImage,
intToImage,
imageToInt,
Format(..),
imgData,
imgGamma,
imgPalette
) where
import HTk.Kernel.Core
import HTk.Kernel.BaseClasses(Widget)
import HTk.Kernel.Configuration
import Util.Computation
import Events.Synchronized
import Events.Destructible
-- -----------------------------------------------------------------------
-- class image
-- -----------------------------------------------------------------------
-- | Image containers instantiate the @class HasPhoto@.
class GUIObject w => HasPhoto w where
-- Associates an image container (e.g. a label) with the given image.
photo :: Image -> Config w
-- Gets the image associated with the given image container.
getPhoto :: w -> IO (Maybe Image)
photo img w = imageToInt img >>= cset w "image"
getPhoto w = cget w "image" >>= intToImage
-- -----------------------------------------------------------------------
-- type image
-- -----------------------------------------------------------------------
-- | The @Image@ datatype.
newtype Image = Image GUIOBJECT deriving Eq
-- -----------------------------------------------------------------------
-- constructor
-- -----------------------------------------------------------------------
-- | Constructs a new image object and returns a handler.
-- The image object can be packed like a widget, then it is implicitely
-- displayed inside a label widget.
newImage :: [Config Image]
-- ^ the list of configuration options for this image
-- object.
-> IO Image
-- ^ An image object.
newImage cnf =
do
w <- createWidget ROOT LABEL
configure (Image w) cnf
-- | Sets the image data from a base64 encoded string.
imgData :: Format -> String -> Config Image
imgData f str w =
execTclScript [tkImageCreateFromData no f str] >> cset w "image" no
where no = getObjectNo (toGUIObject w)
-- | The @Format@ datatype - represents the format of a base64
-- encoded image (see @Image.imgData@).
data Format = GIF | PPM | PGM
formatToString :: Format -> String
formatToString f =
case f of
GIF -> "GIF"
PPM -> "PPM"
_ -> "PGM"
-- | The @gamma@ correction factor. Values less than one
-- darken the image, values greater than one brighten up the image.
imgGamma :: Double -> Config Image
imgGamma g = tkImgConfig ("-gamma "++ show g)
-- | The colour palette specifies a private palette for this image.
-- You can either specify a grayscale palette (of n shades of grey), or an
-- RGB triple.
class PaletteSpec p where
-- Internal function only
tkShowPalette :: p-> String
instance PaletteSpec Int where
tkShowPalette p = show p
instance PaletteSpec (Int, Int, Int) where
tkShowPalette (r, g, b) = show r ++ "/"++ show g++ "/"++ show b
imgPalette :: PaletteSpec p=> p-> Config Image
imgPalette p = tkImgConfig ("-palette "++ tkShowPalette p)
-- We leave the getImgGamma and getImgPalette functions as exercises
-- to the interested reader of this source code.
-- -----------------------------------------------------------------------
-- instantiations
-- -----------------------------------------------------------------------
-- | Internal.
instance GUIObject Image where
toGUIObject (Image w) = w
cname _ = "Image"
-- | An image object can be destroyed.
instance Destroyable Image where
-- Destroys an image object.
destroy = destroy . toGUIObject
-- | An image object has standard widget properties
-- (concerning focus, cursor \/ if implicitely displayed inside a label
-- widget).
instance Widget Image
-- | An image object has a configureable border (if implicitely displayed
-- inside a label widget).
instance HasBorder Image
-- | An image object has a configureable foreground and background colour
-- (if implicitely displayed inside a label widget).
instance HasColour Image where
legalColourID = hasForeGroundColour
-- | You can specify the size of the containing label, if the image is
-- implicitely displayed inside a label widget.
instance HasSize Image
-- | Images can be read from files.
instance HasFile Image where
-- Specifies the image file path.
filename str w =
execTclScript [tkImageCreate no str] >> cset w "image" no
where no = getObjectNo (toGUIObject w)
-- Gets the image\'s file name.
getFileName w = evalTclScript [tkGetImageFile no]
where no = getObjectNo (toGUIObject w)
-- | You can synchronize on an image object.
instance Synchronized Image where
-- Synchronizes on an image object.
synchronize = synchronize . toGUIObject
-- -----------------------------------------------------------------------
-- auxiliary functions
-- -----------------------------------------------------------------------
-- | Internal.
intToImage :: Int -> IO (Maybe Image)
intToImage 0 = return Nothing
intToImage no = lookupGUIObject (ObjectID no) >>= return . Just . Image
{- this function converts the Tk representation of an image to the HTK
representation. Needed by several other image retrieval function.
-}
-- | Internal.
imageToInt :: Image -> IO Int
imageToInt = return . getObjectNo . toGUIObject
-- -----------------------------------------------------------------------
-- Tk Commands
-- -----------------------------------------------------------------------
tkImageCreate :: Int -> String -> String
tkImageCreate no file = "image create photo " ++ show no ++ " -file " ++ show file
{-# INLINE tkImageCreate #-}
tkGetImageFile :: Int -> String
tkGetImageFile no = (show no) ++ " cget -file "
{-# INLINE tkGetImageFile #-}
tkImageCreateFromData :: Int -> Format -> String -> String
tkImageCreateFromData no f dat = "image create photo " ++ show no ++ " -data " ++ show dat ++ " -format " ++ show (formatToString f)
tkImgConfig :: String-> Config Image
tkImgConfig cstr w =
do execTclScript [show no++ " configure "++ cstr]
return w
where no = getObjectNo (toGUIObject w)
{-# INLINE tkImgConfig #-}