module Data.QRCodes.Image (
bsToImg
, objToImg
, bsToImgSec
, objToImgSec
, bsToImgSec'
, objToImgSec'
) where
import Data.Word (Word8)
import Codec.Picture.Types as T
import Prelude as P
import qualified Data.Vector.Storable as V
import qualified Data.ByteString as BS
import Data.ByteString.Lazy (toStrict)
import Data.QRCode
import Data.Aeson
import Data.QRCodes.Utils
import Data.QRCodes.Signature
import Crypto.PubKey.RSA
bsToImgSec :: BS.ByteString -> FilePath -> IO (T.Image Word8)
bsToImgSec string keyfile = bsToImg =<< (((fmap preserveUpper) . (flip mkSigFile keyfile)) string)
bsToImgSec' :: BS.ByteString -> (PublicKey, PrivateKey) -> IO (T.Image Word8)
bsToImgSec' string key = bsToImg =<< (((fmap preserveUpper) . (flip mkSig key)) string)
objToImgSec :: (ToJSON a) => a -> FilePath -> IO (T.Image Word8)
objToImgSec obj = bsToImgSec (toStrict $ encode obj)
objToImgSec' :: (ToJSON a) => a -> (PublicKey, PrivateKey) -> IO (T.Image Word8)
objToImgSec' obj = bsToImgSec' (toStrict $ encode obj)
bsToImg :: BS.ByteString -> IO (T.Image Word8)
bsToImg input = do
smallMatrix <- toMatrix <$> encodeByteString input Nothing QR_ECLEVEL_H QR_MODE_EIGHT False
let qrMatrix = fattenList 8 $ map (fattenList 8) smallMatrix
pure $ encodePng qrMatrix
objToImg :: (ToJSON a) => a -> IO (T.Image Word8)
objToImg obj = let input = toStrict $ encode obj in bsToImg input
encodePng :: [[Word8]] -> T.Image Word8
encodePng matrix = Image dim dim vector
where dim = P.length matrix
vector = V.map ((*255) . swapWord) $ V.fromList $ P.concat matrix
fattenList :: Int -> [a] -> [a]
fattenList i l = P.concat $ P.foldr ((:) . (P.replicate i)) [] l