-
Notifications
You must be signed in to change notification settings - Fork 1
/
Image.hs
85 lines (69 loc) · 3.09 KB
/
Image.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
module Image ( ColourStream(..),
ImageData(..),
imageColourspace,
serialiseImage ) where
import System.Exit
import Data.Vector.Storable (toList)
import Codec.Picture
import Codec.Picture.Types
import Options (ColourSpace(..))
data ColourStream = Greys [Pixel8]
| Colours [PixelRGB8]
type Width = Int
type Height = Int
data ImageData = ImageData Width Height ColourStream
imageColourspace :: ImageData -> ColourSpace
imageColourspace (ImageData _ _ (Greys _)) = Greyscale
imageColourspace (ImageData _ _ (Colours _)) = Colour
dynamicColourspace :: DynamicImage -> ColourSpace
dynamicColourspace (ImageY8 _) = Greyscale
dynamicColourspace (ImageYA8 _) = Greyscale
dynamicColourspace _ = Colour
-- Open image and serialise meta data and pixels
serialiseImage :: FilePath -> ColourSpace -> IO ImageData
serialiseImage file colourspace = do
dynImage <- readImage file
case dynImage of
Left errStatus -> do putStrLn $ "Failed to load '" ++ file ++ "': " ++ errStatus
exitFailure
Right image -> normaliseImage image colourspace
-- Normalise image to either 8-bit greyscale or 24-bit RGB
normaliseImage :: DynamicImage -> ColourSpace -> IO ImageData
normaliseImage image colourspace = case colourspace of
Greyscale -> do
normalisedImage <- toGrey image
return $ ImageData (imageWidth normalisedImage)
(imageHeight normalisedImage)
(Greys $ (toList . imageData) normalisedImage)
Colour -> do
normalisedImage <- toRGB image
return $ ImageData (imageWidth normalisedImage)
(imageHeight normalisedImage)
(Colours $ (toColours . toList . imageData) normalisedImage)
where toColours :: [Pixel8] -> [PixelRGB8]
toColours (r:g:b:xs) = PixelRGB8 r g b : toColours xs
toColours _ = []
Adaptive ->
normaliseImage image (dynamicColourspace image)
cannotNormalise :: IO a
cannotNormalise = do putStrLn "Cannot normalise image: Unhandled colourspace"
exitFailure
-- Convert image to 8-bit greyscale
toGrey :: DynamicImage -> IO (Image Pixel8)
toGrey (ImageY8 img) = return img
toGrey (ImageYA8 img) = return $ pixelMap dropTransparency img
toGrey (ImageRGB8 img) = return $ pixelMap computeLuma img
toGrey (ImageRGBA8 img) = return $ pixelMap computeLuma img
toGrey (ImageYCbCr8 img) = return $ pixelMap computeLuma img
toGrey (ImageCMYK8 img) = return $ pixelMap computeLuma $ convertCMYK img
where convertCMYK = convertImage :: Image PixelCMYK8 -> Image PixelRGB8
toGrey _ = cannotNormalise
-- Convert image to 24-bit (RGB) colour
toRGB :: DynamicImage -> IO (Image PixelRGB8)
toRGB (ImageY8 img) = return $ promoteImage img
toRGB (ImageYA8 img) = return $ promoteImage img
toRGB (ImageRGB8 img) = return img
toRGB (ImageRGBA8 img) = return $ pixelMap dropTransparency img
toRGB (ImageYCbCr8 img) = return $ convertImage img
toRGB (ImageCMYK8 img) = return $ convertImage img
toRGB _ = cannotNormalise