pixelated-avatar-generator 0.1.0 → 0.1.1
raw patch · 7 files changed
+183/−29 lines, 7 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ Graphics.Avatars.Pixelated: encodeToGif :: ImageConversion
+ Graphics.Avatars.Pixelated: encodeToPng :: ImageConversion
+ Graphics.Avatars.Pixelated: encodeToTiff :: ImageConversion
+ Graphics.Avatars.Pixelated: saveAvatarWith :: ImageConversion -> Avatar -> FilePath -> IO ()
+ Graphics.Avatars.Pixelated: type ImageConversion = Image PixelRGB8 -> ByteString
Files
- CHANGELOG.md +10/−0
- CONTRIBUTING.md +25/−0
- README.md +24/−1
- example_image.png binary
- pixelated-avatar-generator.cabal +3/−2
- src/Graphics/Avatars/Pixelated.hs +88/−14
- test/Graphics/Avatars/PixelatedSpec.hs +33/−12
CHANGELOG.md view
@@ -1,5 +1,15 @@ # Changelog +## 0.1.1+* Implement saving with different image formats.+* Add image format conversion functions for PNG, GIF, and TIFF.+* Change the example image in the readme file.+* Add a link to the Hackage package to the readme file.+* Document the process of making a release of the package.+* Add information on the library to the readme file.+* Improve the documentation of the library.+* Improve some of the avatar colors.+ ## 0.1.0 * Implement generation and saving of avatars. * Implement avatar upscaling.
+ CONTRIBUTING.md view
@@ -0,0 +1,25 @@+# Contributing++## Releases+Whenever a new release of the program is made, there are a few things that should be updated:++* `CHANGELOG.md` - Information the changes in the new release should be added.+* `pixelated-avatar-generator.cabal` - The version should be updated.++Once those changes have been made, a release for the application should be made on GitHub, and the following files should be included:++* `doc.zip` - A zip archive of the generated haddock documentation.+* `pixelated-avatar-generator` - An executable Linux binary of the program.++The Haddock documentation and Linux binary can be generated by running the following commands:++```+stack build+stack haddock+```++Once the release on GitHub has been made, the package should then be released on Hackage. This can be done by generating the package with the following command, and uploading it to Hackage.++```+stack sdist+```
README.md view
@@ -10,8 +10,28 @@ seed = createSeed s ``` -+ +## Library+Pixelated Avatar Generator is a library which provides functions and data types for generating, altering, and saving pixelated avatars.++For information on how to use the library, see the documentation for the [`Graphics.Avatars.Pixelated`](https://hackage.haskell.org/package/pixelated-avatar-generator/docs/Graphics-Avatars-Pixelated.html) module.++### Documentation+The documentation for the latest release of the library can be found in [the library's Hackage entry](https://hackage.haskell.org/package/pixelated-avatar-generator).++Documentation of the development versions of the library can be generated by running the following command in the main directory of the project:++```+$ stack haddock+```++The generated html documentation can then be found in the following directory:++```+.stack-work/dist/x86_64-linux/Cabal-1.22.5.0/doc+```+ ## Executable An example executable program that uses the library is also provided. It creates an avatar from a given seed string and saves the created `.png` image to a given file location. @@ -45,6 +65,9 @@ FILEPATH -- The location to save the generated avatar at. "img/test.png" SEEDSTRING -- The string to use to generate the avatar. "Hello" ```++## Links+* [Pixelated Avatar Generator package on Hackage](https://hackage.haskell.org/package/pixelated-avatar-generator) ## License The source code of Pixelated Avatar Generator is available under the [MIT license](https://opensource.org/licenses/MIT), see `LICENSE` for more information.
example_image.png view
binary file changed (1711 → 610 bytes)
pixelated-avatar-generator.cabal view
@@ -1,8 +1,8 @@ name: pixelated-avatar-generator-version: 0.1.0+version: 0.1.1 synopsis: A library and application for generating pixelated avatars. description:- <<data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEAAQMAAABmvDolAAAABlBMVEWWlpb///+oiwZLAAAAUElEQVRo3u3XsQ0AIAgAQfZfGhsLoxAH4L7CeLXBiF1mZjUHAADAFQAAQHX5IAAARoLzUM4AAIwF9igAAH5AkqruR6NdLgAAGAX8swAAaMACTyHw4mh6Rv4AAAAASUVORK5CYII=>>+ <<data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA1AAAACABAMAAAD345WwAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4AcREioaDb4fhAAAABVQTFRFKSkpaLb/lpaW0JT//4xB/+eU////Sm1svwAAAeBJREFUeNrt2bFxwzAQBEC2oBbUglpwC2zB/ZfgRHbwMzf/oKUAmr0M4IHg/IY87iXfz6zu13w1SefOZ9J62nuE1PdMezVHSde//TMHKFCgQIECBQoUKFCgQIECBQoUKFCgQIECBQrUh0GlpP4UZNpLEFPIlFWQCtNBJbg6+NV9UKBAgQIFChQoUKBAgQIFChQoUKBAgQIFChSo3aGmH1zBKkAHknod0BQywXRQHdyxmPSeVai/+0GBAgUKFChQoECBAgUKFChQoECBAgUKFChQoDaF6gC6/ZoOKIEliA6qA7qaV0N1QB0YKFCgQIECBQoUKFCgQIECBQoUKFCgQIECBQrUrlD3kg4i9evgp0B1XQd/NknnusF3sB3U6vMENu2BAgUKFChQoECBAgUKFChQoECBAgUKFChQoEB9CtRq6gV18Cmp1wFMe1OgBFYBrsLVwV8NKFCgQIECBQoUKFCgQIECBQoUKFCgQIECBQrU7lD1og4k7SeQKeBZcrX/CEkw7/5x+DvwtO56oECBAgUKFChQoECBAgUKFChQoECBAgUKFChQu0JNAVZhOqjpj8MpYAfbQaVzdfBHk3TuFpKgakCBAgUKFChQoECBAgUKFChQoECBAgUKFChQoDaF+gF8d9lnmZmUZAAAAABJRU5ErkJggg==>> . @@ -20,6 +20,7 @@ build-type: Simple extra-source-files: README.md CHANGELOG.md+ CONTRIBUTING.md example_image.png test/Graphics/Avatars/helloAvatar.png cabal-version: >=1.10
src/Graphics/Avatars/Pixelated.hs view
@@ -18,6 +18,11 @@ -- you have scaled the Avatar to the size you want it to be it can then be -- saved to a file by passing it into `saveAvatar`. --+-- By default, the `saveAvatar` function saves the avatar as a png image file,+-- however you can also save avatars in other image formats by using+-- `saveAvatarWith`. It allows you to specify the function to use to convert+-- the avatar image into an image ByteString.+-- -- = Example -- The following is an example showing how to construct a function which will -- generate a 256x256px avatar from a given seed string, and save it at the@@ -38,8 +43,11 @@ Seed(..), createSeed, -- ** Avatar- Avatar(..), generateAvatar, scaleAvatar, saveAvatar, convertAvatarToImage,+ Avatar(..), generateAvatar, scaleAvatar, saveAvatar, saveAvatarWith, convertAvatarToImage, + -- *** Image Conversion+ ImageConversion, encodeToPng, encodeToGif, encodeToTiff,+ -- ** Color Color(..), getColorValue, colorFromSeed, @@ -51,9 +59,9 @@ ) 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 (writeFile)+import qualified Data.ByteString.Lazy as B (ByteString, writeFile) import Data.ByteString.Lazy.Internal (packChars) import Data.Digest.Pure.MD5 (md5) import Data.List.Split (chunksOf)@@ -78,17 +86,34 @@ ------------------------------------------------------------------------------- -- Avatars --- | A generated avatar.+-- | A generated avatar, comprised of a color and a grid representing the+-- visual pattern of the avatar image. Can be created from a seed using+-- `generateAvatar`.+--+-- Avatars are generated at a size of 8x8px, and can be scaled up to larger+-- image sizes by using the `scaleAvatar` function. data Avatar = Avatar { color :: Color , grid :: AvatarGrid } deriving (Eq) +-- | Generates a String containing the color and pattern of the avatar. instance Show Avatar where show a = (show . color) a ++ "\n" ++ ((show . grid) a) -- | Generates an avatar from the given seed.+--+-- >>> generateAvatar Seed {unSeed = "8b1a9953c4611296a827abf8c47804d7"}+-- Grey+-- ██ ██ ██+-- ██ ██+-- █ █+-- █ █ +-- ██ ██+-- ████████+-- █ ██ █+-- █ █ generateAvatar :: Seed -> Avatar generateAvatar seed = avatar where avatar = Avatar {@@ -99,13 +124,20 @@ aGrid = generateAvatarGrid seed -- | Scales the given Avatar by the given scaling factor.+--+-- For example, scaling an 8x8px avatar by a factor of 4 would transform it+-- into a 32x32px avatar. scaleAvatar :: Int -> Avatar -> Avatar scaleAvatar factor avatar = avatar { grid = AvatarGrid scaledGrid } where scaledGrid = ((scaleList factor) . (map (scaleList factor))) unscaledGrid unscaledGrid = unAvatarGrid $ grid avatar --- | Saves the given avatar to the given file path.+-- | Saves the given avatar as a png image file to the given file path. The+-- filepath should be the path and name of the image file to be created,+-- including the file extension. --+-- For saving an avatar in a non-png format, use `saveAvatarWith`.+-- -- @ -- makeAvatar :: Seed -> FilePath -> IO () -- makeAvatar seed path = do@@ -113,9 +145,24 @@ -- saveAvatar avatar path -- @ saveAvatar :: Avatar -> FilePath -> IO ()-saveAvatar avatar path = B.writeFile path image- where image = encodePng $ convertAvatarToImage avatar+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 `encodeToGif` and `encodeToTiff`.+--+-- @+-- saveTiffAvatar :: Seed -> FilePath -> IO ()+-- saveTiffAvatar seed path = do+-- let avatar = generateAvatar seed path+-- saveAvatarWith encodeTiff avatar path+-- @+saveAvatarWith :: ImageConversion -> Avatar -> FilePath -> IO ()+saveAvatarWith conversion avatar path = do+ let image = conversion $ convertAvatarToImage avatar+ B.writeFile path image+ -- | Converts the given Avatar into an Image. convertAvatarToImage :: Avatar -> Image PixelRGB8 convertAvatarToImage avatar = image@@ -125,26 +172,53 @@ 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 --- | A color for an avatar.+-- | A color of an avatar. The color of an avatar is the color that is applied+-- to the pattern of the avatar when it is converted into an image. data Color = Black | Blue | Green | Grey | Orange | Purple | Red | Yellow deriving (Eq, Show, Enum) -- | Converts the given color into a RGB pixel representation.+--+-- >>> getColorValue Orange+-- PixelRGB8 255 140 65 getColorValue :: Color -> PixelRGB8 getColorValue c- | c == Black = PixelRGB8 0 0 0- | c == Blue = PixelRGB8 0 0 200- | c == Green = PixelRGB8 0 200 0+ | c == Black = PixelRGB8 41 41 41+ | c == Blue = PixelRGB8 104 182 255+ | c == Green = PixelRGB8 114 220 131 | c == Grey = PixelRGB8 150 150 150 | c == Orange = PixelRGB8 255 140 65- | c == Purple = PixelRGB8 130 0 130- | c == Red = PixelRGB8 200 0 0- | otherwise = PixelRGB8 230 230 0+ | c == Purple = PixelRGB8 208 148 255+ | c == Red = PixelRGB8 255 87 87+ | otherwise = PixelRGB8 255 231 148 -- | Picks an avatar color using the given seed.+--+-- Each of the eight possible colors has roughly an equal chance of being+-- chosen with a random seed. -- -- >>> colorFromSeed $ Seed {unSeed = "8b1a9953c4611296a827abf8c47804d7"} -- Grey
test/Graphics/Avatars/PixelatedSpec.hs view
@@ -4,7 +4,9 @@ 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@@ -44,8 +46,23 @@ 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 @@ -73,21 +90,21 @@ it "returns a pixel representation of a color" $ do getColorValue Orange `shouldBe` PixelRGB8 255 140 65 it "can process Black" $ do- getColorValue Black `shouldBe` PixelRGB8 0 0 0+ getColorValue Black `shouldBe` PixelRGB8 41 41 41 it "can process Blue" $ do- getColorValue Blue `shouldBe` PixelRGB8 0 0 200+ getColorValue Blue `shouldBe` PixelRGB8 104 182 255 it "can process Green" $ do- getColorValue Green `shouldBe` PixelRGB8 0 200 0+ getColorValue Green `shouldBe` PixelRGB8 114 220 131 it "can process Grey" $ do getColorValue Grey `shouldBe` PixelRGB8 150 150 150 it "can process Orange" $ do getColorValue Orange `shouldBe` PixelRGB8 255 140 65 it "can process Purple" $ do- getColorValue Purple `shouldBe` PixelRGB8 130 0 130+ getColorValue Purple `shouldBe` PixelRGB8 208 148 255 it "can process Red" $ do- getColorValue Red `shouldBe` PixelRGB8 200 0 0+ getColorValue Red `shouldBe` PixelRGB8 255 87 87 it "can process Yellow" $ do- getColorValue Yellow `shouldBe` PixelRGB8 230 230 0+ getColorValue Yellow `shouldBe` PixelRGB8 255 231 148 ----------------------------------------------------------------------------- -- Avatar Grids@@ -145,10 +162,14 @@ , " █ █ " ] -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 {