JuicyPixels-repa 0.6.2 → 0.7
raw patch · 2 files changed
+51/−19 lines, 2 files
Files
- Codec/Picture/Repa.hs +50/−18
- JuicyPixels-repa.cabal +1/−1
Codec/Picture/Repa.hs view
@@ -1,8 +1,8 @@-{-# LANGUAGE EmptyDataDecls, FlexibleInstances, TypeSynonymInstances, MultiParamTypeClasses #-}+{-# LANGUAGE EmptyDataDecls, FlexibleInstances, TypeSynonymInstances, MultiParamTypeClasses, ViewPatterns #-} module Codec.Picture.Repa ( -- * Primitive types and operations Img, imgData- , convertImage+ , convertImage, imgToImage -- * Generic interface , readImage, decodeImage -- * Monomorphic image decoding functions@@ -16,6 +16,8 @@ , reverseColorChannel , flipHorizontally, flipVertically , vConcat, hConcat+ -- * Saving Images+ , module Codec.Picture.Saving -- * Internal Functionallity (exported for advanced uses) , ToRGBAChannels(..) ) where@@ -27,6 +29,7 @@ import qualified Codec.Picture as P import Codec.Picture hiding (readImage, decodeImage) import Codec.Picture.Types hiding (convertImage)+import Codec.Picture.Saving import qualified Data.Vector.Storable as S import Foreign.ForeignPtr import Data.Word@@ -64,7 +67,7 @@ -- |@toByteString arr@ converts images to bytestrings, which is often useful -- for Gloss. toByteString :: Img a -> B.ByteString-toByteString (Img arr) =+toByteString ((onImg flipVertically . reverseColorChannel) -> Img arr) = let fp = RF.toForeignPtr arr (Z :. row :. col :. chan) = extent arr in BI.fromForeignPtr fp 0 (col * row * chan)@@ -200,7 +203,7 @@ instance ToRGBAChannels PixelYA8 where toRGBAChannels = promotePixel- + instance ToRGBAChannels Pixel8 where toRGBAChannels = promotePixel @@ -228,28 +231,28 @@ convertImage (ImageRGB8 i) = convertImage i convertImage (ImageRGBA8 i) = convertImage i -- zeroCopyConvert 4 i convertImage (ImageYCbCr8 i) = convertImage i- + instance ConvertImage DynamicImage RGB where convertImage (ImageY8 i) = convertImage i convertImage (ImageYA8 i) = convertImage i convertImage (ImageRGB8 i) = convertImage i -- zeroCopyConvert 3 i convertImage (ImageRGBA8 i) = convertImage i convertImage (ImageYCbCr8 i) = convertImage i- + instance ConvertImage DynamicImage R where convertImage (ImageY8 i) = convertImage i convertImage (ImageYA8 i) = convertImage i convertImage (ImageRGB8 i) = convertImage i convertImage (ImageRGBA8 i) = convertImage i convertImage (ImageYCbCr8 i) = convertImage i- + instance ConvertImage DynamicImage G where convertImage (ImageY8 i) = convertImage i convertImage (ImageYA8 i) = convertImage i convertImage (ImageRGB8 i) = convertImage i convertImage (ImageRGBA8 i) = convertImage i convertImage (ImageYCbCr8 i) = convertImage i- + instance ConvertImage DynamicImage B where convertImage (ImageY8 i) = convertImage i convertImage (ImageYA8 i) = convertImage i@@ -260,39 +263,54 @@ instance (ToRGBAChannels a, Pixel a) => ConvertImage (Image a) RGBA where convertImage p@(Image w h dat) = let z = 4- in Img $ R.computeS $ R.fromFunction (Z :. h :. w :. z) - (\(Z :. y :. x :. z') -> getPixel x y (z - z' - 1) p)- + in Img $ R.computeS $ R.fromFunction (Z :. h :. w :. z)+ (\(Z :. y :. x :. z') -> getPixel x y z' p)+ instance (ToRGBAChannels a, Pixel a) => ConvertImage (Image a) RGB where convertImage p@(Image w h dat) = let z = 3 in Img $ R.computeS $ R.fromFunction (Z :. h :. w :. z)- (\(Z :. y :. x :. z') -> getPixel x y (z' - z -1) p)+ (\(Z :. y :. x :. z') -> getPixel x y z' p) instance (ToRGBAChannels a, Pixel a) => ConvertImage (Image a) R where convertImage p@(Image w h dat) = let z = 1 in Img $ R.computeS $ R.fromFunction (Z :. h :. w :. z) (\(Z :. y :. x :. z) -> getPixel x y 0 p)- + instance (ToRGBAChannels a, Pixel a) => ConvertImage (Image a) G where convertImage p@(Image w h dat) = let z = 1 in Img $ R.computeS $ R.fromFunction (Z :. h :. w :. z) (\(Z :. y :. x :. z) -> getPixel x y 1 p)- + instance (ToRGBAChannels a, Pixel a) => ConvertImage (Image a) B where convertImage p@(Image w h dat) = let z = 1 in Img $ R.computeS $ R.fromFunction (Z :. h :. w :. z) (\(Z :. y :. x :. z) -> getPixel x y 2 p) +-- Convert a repa-based 'Img' to a JuicyPixels Vector-based 'DynaimcImage'.+imgToImage :: Img a -> DynamicImage+imgToImage (Img arr) =+ let e@(Z :. row :. col :. z) = extent arr+ f co ro =+ let r = R.unsafeIndex arr (Z:.ro:.co:.(max 0 0))+ g = R.unsafeIndex arr (Z:.ro:.co:.(max 0 1))+ b = R.unsafeIndex arr (Z:.ro:.co:.(max 0 2))+ a = if z == 4 then R.unsafeIndex arr (Z:.ro:.co:.3)+ else 255+ in PixelRGBA8 r g b a+ in ImageRGBA8 (generateImage f col row)++-- |Flip an image vertically flipVertically :: Array F DIM3 Word8 -> Array F DIM3 Word8 flipVertically rp = (R.computeS $ backpermute e order rp) where e@(Z :. row :. col :. z) = extent rp order (Z :. oldRow :. oldCol :. oldChan) = Z :. row - oldRow - 1 :. oldCol :. oldChan +-- |Flip an image horizontally flipHorizontally :: Array F DIM3 Word8 -> Array F DIM3 Word8 flipHorizontally rp = (R.computeS $ backpermute e order rp) where@@ -311,13 +329,17 @@ | h < hb = fb (Z :. h :. w :. d) | otherwise = fa (Z :. h - hb :. w :. d) -vConcat :: [Array F DIM3 Word8] -> Array F DIM3 Word8+-- |Combines a list of images such that the first image is on top, then+-- the second, and so on.+vConcat :: [Img a] -> Img a vConcat [] = error "vConcat: Can not concat an empty list into a Repa array"-vConcat xs = R.computeS $ Prelude.foldl1 vStack (Prelude.map R.delay xs)+vConcat xs = Img $ R.computeS $ Prelude.foldl1 vStack (Prelude.map (R.delay . imgData) xs) -hConcat :: [Array F DIM3 Word8] -> Array F DIM3 Word8+-- |Combines a list of images such that the first image is on the left, then+-- the second, and so on.+hConcat :: [Img a] -> Img a hConcat [] = error "hConcat: Can not concat an empty list into a Repa array"-hConcat xs = R.computeS $ Prelude.foldl1 hStack (Prelude.map R.delay xs)+hConcat xs = Img $ R.computeS $ Prelude.foldl1 hStack (Prelude.map (R.delay . imgData) xs) -- |Stack the images horozontally, placing the first image on the left of the second. hStack :: Array R.D DIM3 Word8 -> Array R.D DIM3 Word8 -> Array R.D DIM3 Word8@@ -330,8 +352,12 @@ | c < ca = fa (Z :. r :. c :. d) | otherwise = fb (Z :. r :. c - ca :. d) +-- | A histogram is a one dimensional array where each element+-- indicates how many pixels held the value represented by the element's+-- index. type Histogram = R.Array R.D R.DIM1 Word8 +-- | Compute the RGBA historgrams of the image. histograms :: Img a -> (Histogram, Histogram, Histogram, Histogram) histograms (Img arr) = let (Z:.nrRow:.nrCol:._) = R.extent arr@@ -345,3 +371,9 @@ in (incElem r hR, incElem g hG, incElem b hB, incElem a hA)) (zero,zero,zero,zero) [ (row,col) | row <- [0..nrRow-1], col <- [0..nrCol-1] ]++-- | Threshold takes an image and a color channel and a level, returning an+-- image with each pixel of that color channel zeroed or saturated+-- depending on if it was @<=@ the bound or not (@>@).+-- threshhold :: Img a -> Int -> Word8 -> Img a+-- threshhold (Img arr) chan level = do
JuicyPixels-repa.cabal view
@@ -1,5 +1,5 @@ Name: JuicyPixels-repa-Version: 0.6.2+Version: 0.7 Synopsis: Convenience functions to obtain array representations of images. Description: This wraps the Juicy.Pixels library to convert into 'Repa' and 'Data.Vector.Storable' formats.