Copyright | (c) Alexey Kuleshevich 2017 |
---|---|
License | BSD3 |
Maintainer | Alexey Kuleshevich <lehins@yandex.ru> |
Stability | experimental |
Portability | non-portable |
Safe Haskell | None |
Language | Haskell2010 |
Synopsis
- readImage :: forall arr cs e. (Array VS cs e, Array arr cs e, Readable (Image VS cs e) InputFormat) => FilePath -> IO (Either String (Image arr cs e))
- readImage' :: (Array VS cs e, Array arr cs e, Readable (Image VS cs e) InputFormat) => FilePath -> IO (Image arr cs e)
- readImageExact :: Readable img format => format -> FilePath -> IO (Either String img)
- readImageExact' :: Readable b format => format -> FilePath -> IO b
- writeImage :: (Array VS cs e, Array arr cs e, Writable (Image VS cs e) OutputFormat) => FilePath -> Image arr cs e -> IO ()
- writeImageExact :: Writable img format => format -> [SaveOption format] -> FilePath -> img -> IO ()
- data ExternalViewer = ExternalViewer FilePath [String] Int
- displayImage :: (Array VS cs e, Array arr cs e, Writable (Image VS cs e) TIF) => Image arr cs e -> IO ()
- displayImageUsing :: (Array VS cs e, Array arr cs e, Writable (Image VS cs e) TIF) => ExternalViewer -> Bool -> Image arr cs e -> IO ()
- displayImageFile :: ExternalViewer -> FilePath -> IO ()
- defaultViewer :: ExternalViewer
- eogViewer :: ExternalViewer
- gpicviewViewer :: ExternalViewer
- fehViewer :: ExternalViewer
- gimpViewer :: ExternalViewer
- module Graphics.Image.IO.Formats
Reading
:: (Array VS cs e, Array arr cs e, Readable (Image VS cs e) InputFormat) | |
=> FilePath | File path for an image |
-> IO (Either String (Image arr cs e)) |
This function will try to guess an image format from file's extension,
then it will attempt to decode it as such. It will fall back onto the rest of
the supported formats and will try to read them regarless of file's
extension. Whenever image cannot be decoded, Left
containing all errors for
each attempted format will be returned, and Right
containing an image
otherwise. Image will be read with a type signature specified:
>>>
frog <- readImage "images/frog.jpg" :: IO (Either String (Image VS RGB Word8))
>>>
displayImage frog
readImage' :: (Array VS cs e, Array arr cs e, Readable (Image VS cs e) InputFormat) => FilePath -> IO (Image arr cs e) Source #
Just like readImage
, but will throw an exception if incorrect format is
detected.
:: Readable img format | |
=> format | A file format that an image should be read as. See Supported Image Formats |
-> FilePath | Location of an image. |
-> IO (Either String img) |
This function allows for reading all supported image in their exact
colorspace and precision. Only VS
image representation can be read
natively, but exchange
can be use later to switch to a
different representation. For instance, "frog.jpg" image can be read into
it's YCbCr
colorspace with
Word8
precision:
>>>
readImageExact JPG "images/frog.jpg" :: IO (Either String (Image VS YCbCr Word8))
Right <Image VS YCbCr (Word8): 200x320>
The drawback here is that colorspace and precision has to match exactly, otherwise it will return an error:
>>>
readImageExact JPG "images/frog.jpg" :: IO (Either String (Image VS RGB Word8))
Left "JuicyPixel decoding error: Input image is in YCbCr8 (Pixel YCbCr Word8), cannot convert it to RGB8 (Pixel RGB Word8) colorspace."
Any attempt to read an image in a color space, which is not supported by
supplied format, will result in a compile error. Refer to Readable
class
for all images that can be decoded.
readImageExact' :: Readable b format => format -> FilePath -> IO b Source #
Just like readImageExact
, but will throw an exception if incorrect format
is detected.
Writing
:: (Array VS cs e, Array arr cs e, Writable (Image VS cs e) OutputFormat) | |
=> FilePath | Location where an image should be written. |
-> Image arr cs e | An image to write. |
-> IO () |
Just like readImage
, this function will guess an output file format from the
extension and write to file any image that is in one of Y
, YA
, RGB
or
RGBA
color spaces with Double
precision. While doing necessary
conversions the choice will be given to the most suited color space supported
by the format. For instance, in case of a PNG
format, an (Image
arr
RGBA
Double
) would be written as RGBA16
, hence preserving transparency
and using highest supported precision Word16
. At the same time, writing
that image in GIF
format would save it in RGB8
, since Word8
is the
highest precision GIF
supports.
:: Writable img format | |
=> format | A file format that an image should be saved in. See Supported Image Formats |
-> [SaveOption format] | A list of format specific options. |
-> FilePath | Location where an image should be written. |
-> img | An image to write. Can be a list of images in case of formats supporting animation. |
-> IO () |
Write an image in a specific format, while supplying any format specific options. Precision and color space, that an image will be written as, is decided from image's type. Attempt to write image file in a format that does not support color space and precision combination will result in a compile error.
Displaying
data ExternalViewer Source #
External viewing application to use for displaying images.
ExternalViewer FilePath [String] Int | Any custom viewer, which can be specified:
|
Instances
Show ExternalViewer Source # | |
Defined in Graphics.Image.IO showsPrec :: Int -> ExternalViewer -> ShowS # show :: ExternalViewer -> String # showList :: [ExternalViewer] -> ShowS # |
:: (Array VS cs e, Array arr cs e, Writable (Image VS cs e) TIF) | |
=> Image arr cs e | Image to be displayed |
-> IO () |
Makes a call to an external viewer that is set as a default image viewer by the OS. This is a non-blocking function call, so it might take some time before an image will appear.
:: (Array VS cs e, Array arr cs e, Writable (Image VS cs e) TIF) | |
=> ExternalViewer | External viewer to use |
-> Bool | Should the call be blocking |
-> Image arr cs e | Image to display |
-> IO () |
An image is written as a .tiff
file into an operating system's temporary
directory and passed as an argument to the external viewer program.
Common viewers
displayImageFile :: ExternalViewer -> FilePath -> IO () Source #
Displays an image file by calling an external image viewer.
defaultViewer :: ExternalViewer Source #
Default viewer is inferred from the operating system.
eogViewer :: ExternalViewer Source #
eog /tmp/hip/img.tiff
gpicviewViewer :: ExternalViewer Source #
gpicview /tmp/hip/img.tiff
fehViewer :: ExternalViewer Source #
feh --fullscreen --auto-zoom /tmp/hip/img.tiff
gimpViewer :: ExternalViewer Source #
gimp /tmp/hip/img.tiff
Supported Image Formats
module Graphics.Image.IO.Formats
Encoding and decoding of images is done using JuicyPixels and netpbm packages.
List of image formats that are currently supported, and their exact
ColorSpace
s and precision for reading and writing without an implicit
conversion:
Hands on examples
Animated GIF
JuicyPixels is capable of encoding/decoding all sorts of poular formats, one of which is animated GIFs. Here I would like to present a short demonstration on how it is possible to work with image seqences.
So, we download and image, but it's a little bit too big, and it's in RGBA colorspace.
- Read an animated GIF as a list of images:
>>>
imgs <- readImageExact' GIFA "images/downloaded/strawberry.gif" :: IO [(GifDelay, Image VS RGBA Word8)]
- convert to
RGB
colorspace by dropping alpha channel and increasing precision, since we cannot write GIFs in RGBA colorspace:
>>>
let imgsRGB = fmap (fmap toImageRGB) imgs
- if
toImageRGB
hadn't increased the precision toDouble
in the previous step,Bilinear
interpolation would have simply destroyed the image quality in this step. Scale all images in the sequence by a half:
>>>
let imgsRGBsmall = fmap (fmap (scale Bilinear Edge (0.5, 0.5))) imgsRGB
- Here we save the sequence as a new animated image. We don't need to drop
precision back to
Word8
, it will be taken care for us:
>>>
writeImageExact GIFA [GIFALooping LoopingForever] "images/strawberry.gif" imgsRGBsmall
- Now lets extend the animation a bit:
>>>
writeImageExact GIFA [GIFALooping LoopingForever] "images/strawberry_backwards.gif" (imgsRGBsmall ++ reverse imgsRGBsmall)