Basic image processing with JuicyPixels in Haskell
This is an unfinished Post
I will introduce some basic ways to read/write/manipulate image file with JuicyPixels.
Pixel!
Byte-level Manipulation in Haskell
In haskell, usually we use Data.ByteString or Data.ByteString.Lazy as a container of raw data. Which means we will use some thing like Word8 to present one byte and thus manipulate data byte by byte.
Additionally, since Word8 are an instance of type class Num and Integral, one could simply use
to handle bytes as integers. The module Data.ByteString and Data.ByteString.Lazy are both provide some functions to convert between ByteString and [Word8].
Present Pixels in JuicyPixels
Pixel 是一個 type class 內涵一些 operation 和一個 associated type synonym - PixelBaseComponent
Firstly JuicyPixels provides several basic pixel types,
type Pixel8 = Word8
data PixelRGB8 = PixelRGB8 !Pixel8 !Pixel8 !Pixel8
data PixelRGBA8 = PixelRGBA8 !Pixel8 !Pixel8 !Pixel8 !Pixel8
data PixelCMYK8 = PixelCMYK8 !Pixel8 !Pixel8 !Pixel8 !Pixel8However, this is
A type a can be one kind of pixel if it: (1) is Storable into Vector; (2) is a number; (3) provides equality operator.
class ( Storable (PixelBaseComponent a)
, Num (PixelBaseComponent a)
, Eq a ) => Pixel a where
type PixelBaseComponent a :: *
pixelOpacity :: a -> PixelBaseComponent a
-- skippedLoad image with JuicyPixels
In JuicyPixels, …
Define Image
As its name implies, the Image contains information of width and height and a Vector of (some kind of) pixels. The detail of Vector is beyond this post, the only thing we should know is that Vector is just an efficient linear structure which will be used to preserve pixels.
data Image a = Image
{ imageWidth :: {-# UNPACK #-} !Int
, imageHeight :: {-# UNPACK #-} !Int
, imageData :: Vector (PixelBaseComponent a)
}PS. About that {-# UNPACK #-}, please read Unpacking strict fields
Load Image as DynamicImage
JuicyPixels provides functions to enable directly loading images or decoding loaded images, which should be ByteString, into haskell. Either way the result will be presented by a DynamicImage structure. As shown in following code, a DynamicImage includes an Image structure with corresponding pixel type. Please notice, here we only show the most common cases.