| Copyright | © 2016 Mark Karpov |
|---|---|
| License | BSD 3 clause |
| Maintainer | Mark Karpov <markkarpov@openmailbox.org> |
| Stability | experimental |
| Portability | portable |
| Safe Haskell | None |
| Language | Haskell2010 |
Graphics.Identicon
Contents
Description
Core types and definitions for flexible generation of identicons. Please see the Graphics.Identicon.Primitive module for collection of building blocks to code layers of your identicon.
A basic complete example looks like this:
import Codec.Picture
import Data.ByteString (ByteString)
import Data.Proxy
import Data.Word (Word8)
import Graphics.Identicon
import Graphics.Identicon.Primitive
myImageType :: Proxy (Identicon 4 :+ Consumer 4)
myImageType = Proxy
myImpl = Identicon :+ a
where
a :: Word8 -> Word8 -> Word8 -> Word8 -> Layer
a r g b n = rsym $ onGrid 6 6 n $
circle $ gradientLR (edge . mid) black (PixelRGB8 r g b)
myGenerator :: Int -> Int -> ByteString -> Maybe (Image PixelRGB8)
myGenerator = renderIdenticon myImageType myImpl
myGenerator takes desired width, height, and hash that should have at
least 4 bytes in it and returns an identicon corresponding to that hash
or Nothing if the hash has less than 4 bytes in it or width or height
don't make sense. The identicon has randomly placed circle with gradient
filling changing (horizontally) from black to some color and back to
black. The circle is mirrored 4 times, and every repetition is rotated by
90°. This identicon consumes 4 bytes and has one layer.
- data Identicon n = Identicon
- data Consumer n
- data a :+ b = a :+ b
- newtype Layer = Layer {}
- type family BytesAvailable a :: Nat where ...
- type family BytesConsumed a :: Nat where ...
- type family Implementation a where ...
- type family ToLayer (n :: Nat) :: k where ...
- class Renderable a where
- class ApplyBytes a where
- renderIdenticon :: forall a. (Renderable a, KnownNat (BytesAvailable a), BytesAvailable a ~ BytesConsumed a) => Proxy a -> Implementation a -> Int -> Int -> ByteString -> Maybe (Image PixelRGB8)
Basic types
Identicon is a type that represents an identicon consisting of zero
layers. The type is parametrized over the phantom type n which is a
natural number on type level that represents the number of bytes that
should be provided to generate this type of identicon. Bytes typically
come from some sort of hash that has fixed size.
Constructors
| Identicon |
Instances
| Renderable (Identicon n) Source # | |
Consumer is a type that represents an entity that consumes bytes that
are available for identicon generation. It's parametrized over the
phantom type n which is a natural number on type level that represents
the number of bytes that this entity consumes. At this moment, a
Consumer always adds one Layer to identicon when attached to it. The
number of bytes, specified as type parameter of Identicon type must be
completely consumed by a collection of consumers attached to it. To
attach a consumer to Identicon, you use the :+ type operator, see
below.
Instances
| (Renderable a, ApplyBytes (ToLayer * n)) => Renderable ((:+) a (Consumer n)) Source # | |
The :+ type operator is used to attach Consumers to Identicon,
thus adding layers to it and exhausting bytes that are available for
identicon generation. An example of identicon that can be generated from
16 byte hash is shown below:
type Icon = Identicon 16 :+ Consumer 5 :+ Consumer 5 :+ Consumer 6
The identicon above has three layers.
Constructors
| a :+ b infixl 8 |
Instances
| (Renderable a, ApplyBytes (ToLayer * n)) => Renderable ((:+) a (Consumer n)) Source # | |
Layer is the basic building block of an identicon. It's a function
that takes the following arguments (in order):
- Width of identicon
- Height of identicon
- Position on X axis
- Position on Y axis
…and returns a PixelRGB8 value. In this library, an identicon is
generated as “superposition” of several Layers.
Instances
type family BytesAvailable a :: Nat where ... Source #
The BytesAvailable type function calculates how many bytes available
for consumption in a given identicon.
Equations
| BytesAvailable (Identicon n) = n | |
| BytesAvailable (x :+ y) = BytesAvailable x |
type family BytesConsumed a :: Nat where ... Source #
The BytesConsumed type function calculates how many bytes is consumed
in a given identicon.
Equations
| BytesConsumed (Identicon n) = 0 | |
| BytesConsumed (Consumer n) = n | |
| BytesConsumed (x :+ y) = BytesConsumed x + BytesConsumed y |
type family Implementation a where ... Source #
The Implementation type function returns type of the code which can
implement the given identicon.
Equations
| Implementation (Identicon n) = Identicon n | |
| Implementation (a :+ Consumer n) = Implementation a :+ ToLayer n |
type family ToLayer (n :: Nat) :: k where ... Source #
The ToLayer type function calculates type that layer-producing
function should have to consume given number of bytes n.
Identicon rendering
class Renderable a where Source #
Identicons that can be rendered as an image implement this class.
Minimal complete definition
Methods
render :: Proxy a -> Implementation a -> Int -> Int -> ByteString -> (ByteString, Int -> Int -> PixelRGB8) Source #
Instances
| Renderable (Identicon n) Source # | |
| (Renderable a, ApplyBytes (ToLayer * n)) => Renderable ((:+) a (Consumer n)) Source # | |
class ApplyBytes a where Source #
Consume bytes from strict ByteString and apply them to a function
that takes Word8 until it produces a Layer.
Minimal complete definition
Methods
applyBytes :: a -> ByteString -> (ByteString, Layer) Source #
Instances
| ApplyBytes Layer Source # | |
| ApplyBytes f => ApplyBytes (Word8 -> f) Source # | |
Arguments
| :: (Renderable a, KnownNat (BytesAvailable a), BytesAvailable a ~ BytesConsumed a) | |
| => Proxy a | Type that defines an identicon |
| -> Implementation a | Implementation that generates layers |
| -> Int | Width in pixels |
| -> Int | Height in pixels |
| -> ByteString | Collection of bytes to use, should be long enough |
| -> Maybe (Image PixelRGB8) | Rendered identicon, or |
Render an identicon. The function returns Nothing if given
ByteString is too short or when width or height is lesser than 1.