module Main where
import Control.Exception
import Codec.Picture
import qualified Data.ByteString.Lazy.Char8 as BS
import Options.Applicative
import Codec.Picture.Blurhash
import Codec.Picture.Blurhash.Internal.Encode
import Codec.Picture.Blurhash.Internal.Decode
main :: IO ()
main = execParser cliParser >>= execCommand
execCommand :: Command -> IO ()
execCommand (Encode input config) = encodeFromCommand input config >>= BS.putStrLn
execCommand (Decode blurhash config output) = decodeFromCommand blurhash config output
execCommand (Blur input inConfig outConfig output) = do
blurhash <- encodeFromCommand input inConfig
decodeFromCommand blurhash outConfig output
encodeFromCommand :: FilePath -> EncodeConfig -> IO BS.ByteString
encodeFromCommand fp config = do
imgE <- readImage fp
img <- either throwStr pure imgE
either (throwStr . show) pure $ encodeDynamicWithConfig config img
decodeFromCommand :: BS.ByteString -> DecodeConfig -> FilePath -> IO ()
decodeFromCommand blurhash config output = do
img <- either (throwStr . show) pure $ decodeRGB8WithConfig config blurhash
writePng output img
cliParser :: ParserInfo Command
cliParser =
info
(commandParser <**> helper)
(fullDesc <> progDesc "Simple CLI for using blurhash-hs library")
commandParser :: Parser Command
commandParser =
subparser (command "encode" (info encodeParser (progDesc "")) <>
command "decode" (info decodeParser (progDesc "")) <>
command "blur" (info blurParser (progDesc "")))
encodeParser :: Parser Command
encodeParser = Encode <$> inputPathParser <*> encodingConfigParser
decodeParser :: Parser Command
decodeParser = Decode <$> blurhashParser <*> decodingConfigParser <*> outputPathParser
blurParser :: Parser Command
blurParser =
Blur <$>
inputPathParser <*>
encodingConfigParser <*>
decodingConfigParser <*>
outputPathParser
outputPathParser :: Parser FilePath
outputPathParser = strOption (long "output-path" <> value "blurred.png" <> showDefault)
inputPathParser :: Parser FilePath
inputPathParser = strOption (long "input-path")
blurhashParser :: Parser BS.ByteString
blurhashParser = strOption (long "blurhash")
encodingConfigParser :: Parser EncodeConfig
encodingConfigParser =
EncodeConfig <$>
option auto (long "componentsX" <> value (componentsX encodeConfigDefault) <> showDefault) <*>
option auto (long "componentsY" <> value (componentsY encodeConfigDefault) <> showDefault)
decodingConfigParser :: Parser DecodeConfig
decodingConfigParser =
DecodeConfig <$>
option auto (long "punch" <> value (punch decodeConfigDefault) <> showDefault) <*>
option auto (long "width" <> value (outputWidth decodeConfigDefault) <> showDefault) <*>
option auto (long "height" <> value (outputWidth decodeConfigDefault) <> showDefault)
data Command
= Encode FilePath EncodeConfig
| Decode BS.ByteString DecodeConfig FilePath
| Blur FilePath EncodeConfig DecodeConfig FilePath
throwStr :: String -> IO a
throwStr = throwIO . StrException
data StrException = StrException String deriving Show
instance Exception StrException