Skip to content

Commit

Permalink
Add image conversion functions
Browse files Browse the repository at this point in the history
Add several image conversion functions to use for saving avatar images into specific formats.

Also add some tests of the new functions, along with some test images.
  • Loading branch information
ExcaliburZero committed Jul 15, 2016
1 parent 721e332 commit 13c08df
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 11 deletions.
32 changes: 27 additions & 5 deletions src/Graphics/Avatars/Pixelated.hs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ module Graphics.Avatars.Pixelated
-- ** Avatar
Avatar(..), generateAvatar, scaleAvatar, saveAvatar, saveAvatarWith, convertAvatarToImage,

-- *** Image Conversion
ImageConversion, encodeToPng, encodeToGif, encodeToTiff,

-- ** Color
Color(..), getColorValue, colorFromSeed,

Expand All @@ -56,7 +59,7 @@ module Graphics.Avatars.Pixelated
)
where

import Codec.Picture (encodePng, generateImage, Image(..), PixelRGB8(..))
import Codec.Picture (encodeColorReducedGifImage, encodePng, encodeTiff, generateImage, Image(..), PixelRGB8(..))
import Data.Char (ord)
import qualified Data.ByteString.Lazy as B (ByteString, writeFile)
import Data.ByteString.Lazy.Internal (packChars)
Expand Down Expand Up @@ -118,21 +121,20 @@ scaleAvatar factor avatar = avatar { grid = AvatarGrid scaledGrid }
-- saveAvatar avatar path
-- @
saveAvatar :: Avatar -> FilePath -> IO ()
saveAvatar = saveAvatarWith encodePng
saveAvatar = saveAvatarWith encodeToPng

-- | Saves the given avatar to the given file location, using the given
-- function to encode it into a specific image format.
--
-- Some examples of encoding functions are `Codec.Picture.Tiff.encodeTiff` and
-- `Codec.Picture.Png.encodePng`.
-- Some examples of encoding functions are `encodeToGif` and `encodeToTiff`.
--
-- @
-- saveTiffAvatar :: Seed -> FilePath -> IO ()
-- saveTiffAvatar seed path = do
-- let avatar = generateAvatar seed path
-- saveAvatarWith encodeTiff avatar path
-- @
saveAvatarWith :: (Image PixelRGB8 -> B.ByteString) -> Avatar -> FilePath -> IO ()
saveAvatarWith :: ImageConversion -> Avatar -> FilePath -> IO ()
saveAvatarWith conversion avatar path = do
let image = conversion $ convertAvatarToImage avatar
B.writeFile path image
Expand All @@ -146,6 +148,26 @@ convertAvatarToImage avatar = image
colorGrid = (map . map) (toPixel $ color avatar) $ unAvatarGrid $ grid avatar
toPixel c v = if v then getColorValue c else PixelRGB8 255 255 255

----------------------------------------
-- Image Conversion

-- | A function which converts an image into a lazy ByteString.
type ImageConversion = (Image PixelRGB8 -> B.ByteString)

-- | Converts an image into a Png image ByteString.
encodeToPng :: ImageConversion
encodeToPng = encodePng

-- | Converts an image into a Gif image ByteString.
encodeToGif :: ImageConversion
encodeToGif img = case encodeColorReducedGifImage img of
Right i -> i
Left _ -> error "Unable to create valid gif color palette for avatar image."

-- | Converts an image into a Tiff image ByteString.
encodeToTiff :: ImageConversion
encodeToTiff = encodeTiff

-------------------------------------------------------------------------------
-- Colors

Expand Down
33 changes: 27 additions & 6 deletions test/Graphics/Avatars/PixelatedSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import Test.Hspec
import Test.QuickCheck

import Codec.Picture
import qualified Data.ByteString.Lazy as B (ByteString(..))
import Data.String (IsString(..))
import qualified Data.ByteString.Lazy as B (ByteString(..), readFile)
import System.IO (hGetContents)
import System.IO.Unsafe (unsafePerformIO)

import Graphics.Avatars.Pixelated
Expand Down Expand Up @@ -44,7 +46,22 @@ spec = do

describe "convertAvatarToImage" $ do
it "converts an avatar into an image" $ do
encodePng (convertAvatarToImage helloAvatar) `shouldBe` helloAvatarImage
encodePng (convertAvatarToImage helloAvatar) `shouldBe` helloAvatarImagePng

----------------------------------------
-- Image Conversion

describe "encodeToPng" $ do
it "can encode an image into png format" $ do
(encodeToPng . convertAvatarToImage) helloAvatar `shouldBe` helloAvatarImagePng

describe "encodeToGif" $ do
it "can encode an image into gif format" $ do
(encodeToGif . convertAvatarToImage) helloAvatar `shouldBe` helloAvatarImageGif

describe "encodeToTiff" $ do
it "can encode an image into tiff format" $ do
(encodeToTiff . convertAvatarToImage) helloAvatar `shouldBe` helloAvatarImageTiff

-----------------------------------------------------------------------------
-- Colors
Expand Down Expand Up @@ -145,10 +162,14 @@ helloAvatarGridString = (init . unlines) [
, " █ █ "
]

helloAvatarImage :: B.ByteString
helloAvatarImage = image
where image = unRight $ encodeDynamicPng bytestring
bytestring = unRight $ unsafePerformIO $ readImage "test/Graphics/Avatars/helloAvatar.png"
helloAvatarImagePng :: B.ByteString
helloAvatarImagePng = unsafePerformIO $ B.readFile "test/Graphics/Avatars/helloAvatar.png"

helloAvatarImageGif :: B.ByteString
helloAvatarImageGif = unsafePerformIO $ B.readFile "test/Graphics/Avatars/helloAvatar.gif"

helloAvatarImageTiff :: B.ByteString
helloAvatarImageTiff = unsafePerformIO $ B.readFile "test/Graphics/Avatars/helloAvatar.tiff"

testAvatar :: Avatar
testAvatar = Avatar {
Expand Down
Binary file added test/Graphics/Avatars/helloAvatar.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added test/Graphics/Avatars/helloAvatar.tiff
Binary file not shown.

0 comments on commit 13c08df

Please sign in to comment.