Copyright | (c) Alexey Kuleshevich 2016 |
---|---|
License | BSD3 |
Maintainer | Alexey Kuleshevich <lehins@yandex.ru> |
Stability | experimental |
Portability | non-portable |
Safe Haskell | None |
Language | Haskell2010 |
Haskell Image Processing (HIP) library is a wrapper around any array like data structure and is fully agnostic to the underlying representation. All of the functionality in this library relies upon a few type classes, which corresponding representation types are instances of:
- this is a base class for everyArray
arr cs eImage
arr
cs
e
, wherearr
stands for an underlying array representation,cs
is theColorSpace
of an image ande
is the type denoting precision of an image (Int
,Word
,Double
, etc.) .
- is a kind of array, that can be indexed in constant time and allows monadic operations and mutation onMArray
arr cs eMImage
st
arr
cs
e
, which isImage
's mutable cousin.
Representations using Vector and Repa packages:
VU
- Vector Unboxed representation.VS
- Vector Storable representation.RSU
- Repa Sequential Unboxed array representation (computation is done sequentially).RPU
- Repa Parallel Unboxed array representation (computation is done in parallel).RSS
- Repa Sequential Storable array representation (computation is done sequentially).RPS
- Repa Parallel Storable array representation (computation is done in parallel).
Images with RSU
, RSS
, RPU
and RPS
types, most of the time, hold
functions rather than an actual data, this way computation can be fused
together, and later changed to VU
or VS
using toManifest
, which in turn
performs the fused computation. If at any time computation needs to be
forced, compute
can be used for that purpose.
Many of the function names exported by this module will clash with the ones from Prelude, hence it can be more convenient to import like this:
import Prelude as P import Graphics.Image as I
- makeImageR :: Array arr cs Double => arr -> (Int, Int) -> ((Int, Int) -> Pixel cs Double) -> Image arr cs Double
- makeImage :: Array arr cs e => (Int, Int) -> ((Int, Int) -> Pixel cs e) -> Image arr cs e
- fromListsR :: Array arr cs e => arr -> [[Pixel cs e]] -> Image arr cs e
- fromLists :: Array arr cs e => [[Pixel cs e]] -> Image arr cs e
- toLists :: MArray arr cs e => Image arr cs e -> [[Pixel cs e]]
- module Graphics.Image.IO
- readImageY :: Array arr Y Double => arr -> FilePath -> IO (Image arr Y Double)
- readImageYA :: Array arr YA Double => arr -> FilePath -> IO (Image arr YA Double)
- readImageRGB :: Array arr RGB Double => arr -> FilePath -> IO (Image arr RGB Double)
- readImageRGBA :: Array arr RGBA Double => arr -> FilePath -> IO (Image arr RGBA Double)
- writeImage :: (Array VS cs e, Array arr cs e, Writable (Image VS cs e) OutputFormat) => FilePath -> Image arr cs e -> IO ()
- displayImage :: (Array VS cs e, Array arr cs e, Writable (Image VS cs e) TIF) => Image arr cs e -> IO ()
- rows :: BaseArray arr cs e => Image arr cs e -> Int
- cols :: BaseArray arr cs e => Image arr cs e -> Int
- dims :: BaseArray arr cs e => Image arr cs e -> (Int, Int)
- index :: MArray arr cs e => Image arr cs e -> (Int, Int) -> Pixel cs e
- maybeIndex :: MArray arr cs e => Image arr cs e -> (Int, Int) -> Maybe (Pixel cs e)
- defaultIndex :: MArray arr cs e => Pixel cs e -> Image arr cs e -> (Int, Int) -> Pixel cs e
- borderIndex :: MArray arr cs e => Border (Pixel cs e) -> Image arr cs e -> (Int, Int) -> Pixel cs e
- map :: (Array arr cs e, Array arr cs' e') => (Pixel cs' e' -> Pixel cs e) -> Image arr cs' e' -> Image arr cs e
- imap :: (Array arr cs e, Array arr cs' e') => ((Int, Int) -> Pixel cs' e' -> Pixel cs e) -> Image arr cs' e' -> Image arr cs e
- zipWith :: (Array arr cs e, Array arr cs1 e1, Array arr cs2 e2) => (Pixel cs1 e1 -> Pixel cs2 e2 -> Pixel cs e) -> Image arr cs1 e1 -> Image arr cs2 e2 -> Image arr cs e
- izipWith :: (Array arr cs e, Array arr cs1 e1, Array arr cs2 e2) => ((Int, Int) -> Pixel cs1 e1 -> Pixel cs2 e2 -> Pixel cs e) -> Image arr cs1 e1 -> Image arr cs2 e2 -> Image arr cs e
- traverse :: (Array arr cs e, Array arr cs' e') => Image arr cs' e' -> ((Int, Int) -> (Int, Int)) -> (((Int, Int) -> Pixel cs' e') -> (Int, Int) -> Pixel cs e) -> Image arr cs e
- traverse2 :: (Array arr cs e, Array arr cs1 e1, Array arr cs2 e2) => Image arr cs1 e1 -> Image arr cs2 e2 -> ((Int, Int) -> (Int, Int) -> (Int, Int)) -> (((Int, Int) -> Pixel cs1 e1) -> ((Int, Int) -> Pixel cs2 e2) -> (Int, Int) -> Pixel cs e) -> Image arr cs e
- transpose :: Array arr cs e => Image arr cs e -> Image arr cs e
- backpermute :: Array arr cs e => (Int, Int) -> ((Int, Int) -> (Int, Int)) -> Image arr cs e -> Image arr cs e
- (|*|) :: Array arr cs e => Image arr cs e -> Image arr cs e -> Image arr cs e
- fold :: Array arr cs e => (Pixel cs e -> Pixel cs e -> Pixel cs e) -> Pixel cs e -> Image arr cs e -> Pixel cs e
- sum :: Array arr cs e => Image arr cs e -> Pixel cs e
- product :: Array arr cs e => Image arr cs e -> Pixel cs e
- maximum :: (Array arr cs e, Ord (Pixel cs e)) => Image arr cs e -> Pixel cs e
- minimum :: (Array arr cs e, Ord (Pixel cs e)) => Image arr cs e -> Pixel cs e
- normalize :: (Array arr cs e, Array arr X e, Fractional e, Ord e) => Image arr cs e -> Image arr cs e
- eqTol :: (Array arr Binary Bit, Array arr cs e, Ord e) => e -> Image arr cs e -> Image arr cs e -> Bool
- exchange :: (Array arr' cs e, Array arr cs e) => arr -> Image arr' cs e -> Image arr cs e
Color Space
Here is a list of default Pixels with their respective constructors:
*Pixel
Y
e = PixelY y - Luma, also commonly denoted as Y'. *Pixel
YA
e = PixelYA y a - Luma with alpha. *Pixel
RGB
e = PixelRGB r g b - Red, Green and Blue. *Pixel
RGBA
e = PixelRGBA r g b a - RGB with alpha *Pixel
HSI
e = PixelHSI h s i - Hue, Saturation and Intensity. *Pixel
HSIA
e = PixelHSIA h s i a - HSI with alpha *Pixel
CMYK
e = PixelCMYK c m y k - Cyan, Magenta, Yellow and Key (Black). *Pixel
CMYKA
e = PixelCMYKA c m y k a - CMYK with alpha. *Pixel
YCbCr
e = PixelYCbCr y cb cr - Luma, blue-difference and red-difference chromas. *Pixel
YCbCrA
e = PixelYCbCrA y cb cr a - YCbCr with alpha. ------------------------------------------------------------------------------------------ *Pixel
Binary
Bit
=on
|off
- Bi-tonal. *Pixel
cs (Complex
e) = (Pixel
cs e)+:
(Pixel
cs e) - Complex pixels with any color space. *Pixel
X
e = PixelX g - Used for separating channels from other color spaces.
Every Pixel
is an instance of Functor
, Applicative
, Foldable
and
Num
, as well as Floating
and Fractional
if e is also an instance.
All of the functionality related to every ColorSpace
is re-exported by
Graphics.Image.Types module.
Creation
:: Array arr cs Double | |
=> arr | Underlying image representation. |
-> (Int, Int) | ( |
-> ((Int, Int) -> Pixel cs Double) | A function that takes ( |
-> Image arr cs Double |
Create an image with a specified representation and pixels of Double
precision. Note, that it is essential for Double
precision pixels to keep values
normalized in the [0, 1]
range in order for an image to be written to file
properly.
>>>
let grad_gray = makeImageR VU (200, 200) (\(i, j) -> PixelY (fromIntegral i) / 200 * (fromIntegral j) / 200)
Because all Pixel
s and Image
s are installed into Num
, above is equivalent to:
>>>
let grad_gray = makeImageR RPU (200, 200) (\(i, j) -> PixelY $ fromIntegral (i*j)) / (200*200)
>>>
writeImage "images/grad_gray.png" grad_gray
Creating color images is just as easy.
>>>
let grad_color = makeImageR VU (200, 200) (\(i, j) -> PixelRGB (fromIntegral i) (fromIntegral j) (fromIntegral (i + j))) / 400
>>>
writeImage "images/grad_color.png" grad_color
makeImage :: Array arr cs e => (Int, Int) -> ((Int, Int) -> Pixel cs e) -> Image arr cs e Source #
Create an Image by supplying it's dimensions and a pixel generating function.
fromListsR :: Array arr cs e => arr -> [[Pixel cs e]] -> Image arr cs e Source #
Type restricted version of fromLists
that constructs an image using
supplied representation.
fromLists :: Array arr cs e => [[Pixel cs e]] -> Image arr cs e Source #
Construct an image from a nested rectangular shaped list of pixels.
Length of an outer list will constitute m
rows, while the length of inner lists -
n
columns. All of the inner lists must be the same length and greater than 0
.
>>>
fromLists [[PixelY (fromIntegral (i*j) / 60000) | j <- [1..300]] | i <- [1..200]]
<Image VectorUnboxed Y (Double): 200x300>
toLists :: MArray arr cs e => Image arr cs e -> [[Pixel cs e]] Source #
Generates a nested list of pixels from an image.
img == fromLists (toLists img)
IO
module Graphics.Image.IO
Reading
Read supported files into an Image
with pixels in Double
precision. In order to read an image in a different representation, color
space or precision, use readImage
or readImageExact
from
Graphics.Image.IO instead. While reading an image,
it's underlying representation can be specified by passing one of VU
,
VS
, RSU
, RPU
, RSS
or RSU
as the first argument to readImage*
functions. Here is a quick demonstration of how two images can be read as
different representations and later easily combined as their average.
>>>
cluster <- readImageRGB VU "images/cluster.jpg"
>>>
displayImage cluster
>>>
centaurus <- readImageRGB VU "images/centaurus.jpg"
>>>
displayImage centaurus
>>>
displayImage ((cluster + centaurus) / 2)
readImageY :: Array arr Y Double => arr -> FilePath -> IO (Image arr Y Double) Source #
Read image as luma (brightness).
readImageYA :: Array arr YA Double => arr -> FilePath -> IO (Image arr YA Double) Source #
Read image as luma with Alpha
channel.
readImageRGB :: Array arr RGB Double => arr -> FilePath -> IO (Image arr RGB Double) Source #
Read image in RGB colorspace.
readImageRGBA :: Array arr RGBA Double => arr -> FilePath -> IO (Image arr RGBA Double) Source #
Read image in RGB colorspace with Alpha
channel.
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 and it currently cannot be saved with
transparency.
:: (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.
Accessors
Dimensions
rows :: BaseArray arr cs e => Image arr cs e -> Int Source #
Get the number of rows in an image.
>>>
frog <- readImageRGB VU "images/frog.jpg"
>>>
frog
<Image VectorUnboxed RGB (Double): 200x320>>>>
rows frog
200
cols :: BaseArray arr cs e => Image arr cs e -> Int Source #
Get the number of columns in an image.
>>>
frog <- readImageRGB VU "images/frog.jpg"
>>>
frog
<Image VectorUnboxed RGB (Double): 200x320>>>>
cols frog
320
dims :: BaseArray arr cs e => Image arr cs e -> (Int, Int) Source #
Get dimensions of an image.
>>>
frog <- readImageRGB VU "images/frog.jpg"
>>>
frog
<Image VectorUnboxed RGB (Double): 200x320>>>>
dims frog
(200,320)
Indexing
index :: MArray arr cs e => Image arr cs e -> (Int, Int) -> Pixel cs e Source #
Get a pixel at i
-th and j
-th location.
>>>
let grad_gray = makeImage (200, 200) (\(i, j) -> PixelY $ fromIntegral (i*j)) / (200*200)
>>>
index grad_gray (20, 30) == PixelY ((20*30) / (200*200))
True
defaultIndex :: MArray arr cs e => Pixel cs e -> Image arr cs e -> (Int, Int) -> Pixel cs e Source #
Image indexing function that returns a default pixel if index is out of bounds.
borderIndex :: MArray arr cs e => Border (Pixel cs e) -> Image arr cs e -> (Int, Int) -> Pixel cs e Source #
Image indexing function that uses a special border resolutions strategy for out of bounds pixels.
Transformation
Pointwise
map :: (Array arr cs e, Array arr cs' e') => (Pixel cs' e' -> Pixel cs e) -> Image arr cs' e' -> Image arr cs e Source #
Map a function over a an image.
imap :: (Array arr cs e, Array arr cs' e') => ((Int, Int) -> Pixel cs' e' -> Pixel cs e) -> Image arr cs' e' -> Image arr cs e Source #
Map an index aware function over each pixel in an image.
zipWith :: (Array arr cs e, Array arr cs1 e1, Array arr cs2 e2) => (Pixel cs1 e1 -> Pixel cs2 e2 -> Pixel cs e) -> Image arr cs1 e1 -> Image arr cs2 e2 -> Image arr cs e Source #
Zip two images with a function
izipWith :: (Array arr cs e, Array arr cs1 e1, Array arr cs2 e2) => ((Int, Int) -> Pixel cs1 e1 -> Pixel cs2 e2 -> Pixel cs e) -> Image arr cs1 e1 -> Image arr cs2 e2 -> Image arr cs e Source #
Zip two images with an index aware function
Geometric
traverse :: (Array arr cs e, Array arr cs' e') => Image arr cs' e' -> ((Int, Int) -> (Int, Int)) -> (((Int, Int) -> Pixel cs' e') -> (Int, Int) -> Pixel cs e) -> Image arr cs e Source #
Traverse an image
traverse2 :: (Array arr cs e, Array arr cs1 e1, Array arr cs2 e2) => Image arr cs1 e1 -> Image arr cs2 e2 -> ((Int, Int) -> (Int, Int) -> (Int, Int)) -> (((Int, Int) -> Pixel cs1 e1) -> ((Int, Int) -> Pixel cs2 e2) -> (Int, Int) -> Pixel cs e) -> Image arr cs e Source #
Traverse two images.
backpermute :: Array arr cs e => (Int, Int) -> ((Int, Int) -> (Int, Int)) -> Image arr cs e -> Image arr cs e Source #
Backwards permutation of an image.
(|*|) :: Array arr cs e => Image arr cs e -> Image arr cs e -> Image arr cs e Source #
Perform matrix multiplication on two images. Inner dimensions must agree.
Reduction
fold :: Array arr cs e => (Pixel cs e -> Pixel cs e -> Pixel cs e) -> Pixel cs e -> Image arr cs e -> Pixel cs e Source #
Undirected reduction of an image.
maximum :: (Array arr cs e, Ord (Pixel cs e)) => Image arr cs e -> Pixel cs e Source #
Retrieve the biggest pixel from an image
minimum :: (Array arr cs e, Ord (Pixel cs e)) => Image arr cs e -> Pixel cs e Source #
Retrieve the smallest pixel from an image
normalize :: (Array arr cs e, Array arr X e, Fractional e, Ord e) => Image arr cs e -> Image arr cs e Source #
Scales all of the pixels to be in the range [0, 1]
.
eqTol :: (Array arr Binary Bit, Array arr cs e, Ord e) => e -> Image arr cs e -> Image arr cs e -> Bool Source #