{-# LANGUAGE BangPatterns, MultiParamTypeClasses #-} {-# OPTIONS_GHC -fno-warn-orphans #-} module Vision.Image.Grey.Conversion () where import Data.Convertible (Convertible (..)) import qualified Data.Vector.Storable as V import Data.Word import Vision.Image.Grey.Type (GreyPixel (..)) import Vision.Image.RGBA.Type (RGBAPixel (..)) import Vision.Image.RGB.Type (RGBPixel (..)) instance Convertible GreyPixel GreyPixel where safeConvert = Right {-# INLINE safeConvert #-} instance Convertible RGBAPixel GreyPixel where safeConvert !(RGBAPixel r g b a) = Right $ GreyPixel $ word8 $ int (rgbToGrey r g b) * int a `quot` 255 {-# INLINE safeConvert #-} instance Convertible RGBPixel GreyPixel where safeConvert !(RGBPixel r g b) = Right $ GreyPixel $ rgbToGrey r g b {-# INLINE safeConvert #-} -- | Converts the colors to greyscale using the human eye colors perception. rgbToGrey :: Word8 -> Word8 -> Word8 -> Word8 rgbToGrey !r !g !b = (redLookupTable V.! int r) + (greenLookupTable V.! int g) + (blueLookupTable V.! int b) {-# INLINE rgbToGrey #-} redLookupTable, greenLookupTable, blueLookupTable :: V.Vector Word8 redLookupTable = V.generate 256 (\val -> round $ double val * 0.299) greenLookupTable = V.generate 256 (\val -> round $ double val * 0.587) blueLookupTable = V.generate 256 (\val -> round $ double val * 0.114) double :: Integral a => a -> Double double = fromIntegral int :: Integral a => a -> Int int = fromIntegral word8 :: Integral a => a -> Word8 word8 = fromIntegral