PerceivedBrightness

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
module Main () where

import Codec.Image.STB
import Data.Word
import Foreign
import Control.Monad
import System.Environment
import Text.Printf

byteValue :: Ptr Word8 -> Int -> Int -> Int -> IO Float
byteValue ptr i c b = do
    byte <- peek $ plusPtr ptr (i * c + b)
    return ((fromIntegral (byte :: Word8) :: Float) / 0xff)

greyValue :: Ptr Word8 -> Int -> Int -> IO Float
greyValue ptr i 1 = byteValue ptr i 1 0
greyValue ptr i 2 = byteValue ptr i 2 0
greyValue ptr i c = do
    r <- byteValue ptr i c 0
    g <- byteValue ptr i c 1
    b <- byteValue ptr i c 2
    return (r * 0.30 + g * 0.59 + b * 0.11)

mean :: [Float] -> Float
mean a = (sum a) / (fromInteger (toInteger (length a)))

toList :: Ptr Word8 -> (Int, Int) -> Int -> IO [Float]
toList ptr (w, h) c = mapM getValue [1.. w * h]
    where getValue i = greyValue ptr i c

brightness :: Either String Image -> IO Float
brightness (Left x) = return 0.0
brightness (Right img) = liftM mean $ withImage img toList

main = do
    args <- getArgs
    img <- loadImage $ head args
    b <- brightness img
    printf "%.2f\n" b