From 0a115a51a316be6c36b8d59e9b9431978385a88a Mon Sep 17 00:00:00 2001 From: Stefan Dresselhaus Date: Thu, 3 Dec 2015 23:45:05 +0100 Subject: [PATCH 1/6] styled code a bit. --- src/Main.hs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Main.hs b/src/Main.hs index 402abd5..fed4a33 100644 --- a/src/Main.hs +++ b/src/Main.hs @@ -14,8 +14,8 @@ import System.IO (stdin) data Options = Options { srcFile :: String - , width :: Int - , height :: Int + , width :: Int + , height :: Int } options :: Parser Options @@ -55,12 +55,12 @@ conv (fp@(PixelRGB8 fr fg fb),PixelRGB8 br bg bb) = printf "\x1b[48;2;%d;%d;%dm\ where lumi :: Word8 -> Char lumi x - | x > 225 = '@' - | x > 180 = 'O' - | x > 150 = 'X' - | x > 50 = 'o' - | x > 25 = 'x' - | x > 10 = '.' + | x > 225 = '@' + | x > 180 = 'O' + | x > 150 = 'X' + | x > 50 = 'o' + | x > 25 = 'x' + | x > 10 = '.' | otherwise = ' ' img2ascii :: ((PixelRGB8,PixelRGB8) -> String) -> (Image PixelRGB8,Image PixelRGB8) -> [[String]] From d8509a45e19dac4aba8a688444bad4388742dcfc Mon Sep 17 00:00:00 2001 From: Stefan Dresselhaus Date: Sun, 6 Dec 2015 01:48:59 +0100 Subject: [PATCH 2/6] added flag for 256-color support for older terminals and screen --- rose_256.img | 40 ++++++++++++++++++++++++++++++++++++++++ src/Main.hs | 26 +++++++++++++++++++++++--- 2 files changed, 63 insertions(+), 3 deletions(-) create mode 100644 rose_256.img diff --git a/rose_256.img b/rose_256.img new file mode 100644 index 0000000..1c073d3 --- /dev/null +++ b/rose_256.img @@ -0,0 +1,40 @@ +                                                                                                     +                                                                                                     +                                                                                                     +                                                                                                     +                                                                                                     +                                                                                                     +                                                               ooo.                                  +                                                           oo oooooo                                 +                                  oox                   ooooooooooooo                                +                                 xxoooooooo.   oooooooooooooooooooooooo                              +                                 ooooooooooooooooooooooooooooooooooooooo .                           +                                 oooooooooooooooooxoooooooooooooooooooooooo                          +                                oooooooooooooooooooooooooooooooooooooooooooooooooo                   +                               oooooooooooooxxoooooooooxxoooooxooooooooooooooooox.                   +                               ooooooooooooooooooooxxxoooooooooxoooooooooooooooxx                    +                              ooooooooooooxoooxxxxxooxxxxxoooooooooxooooooooooxx                     +                            .ooooooooooooxxoooxxxooxooxxxooooooxooooooooooooooxx                     +                          oooooooooooooooooooxoooxxooxxxooxooooooooooxoooooooxxx                     +                  .xooooooooooooooooooooooooooooooooooooooooooooooooxxooooooooxx                     +                    xxxxooooooooooooooooooooooooooooooxxxxoooxoooooo.xooooooooox                     +                     xxxooooooooooooooooooooooxooooxxxxoooooxoooooox xoooooooooo                     +                      xxxxoooooooooooooooooooooooooooooooxooooooox.  ooooooxxoo                      +                      .xooooooooooooooooooooooooooxoooxoooooooooxxxxoooooxxx.                        +                       xxxxxooooooxooooooxx.oooooooxooooooooxxxxxxooooooxxxx                         +                       xxxoxxxoooooxxoooooooxxxxxxxooox.xxxxooooooooooxxxxx                          +                       xxxxxxxxxxoooxxxxxxxxoooooooooooooooooooxxoooxxxxx.                           +                       xx..xxxxxxxxoxxxooooooooooooooooooooxxx..oooxxx..                             +                            xxxxxxxxxx.xxxxxxxxxxx...xxxx......xoxxx..                               +                            xxxxx.xxxxxx.........        ......xxx..                                 +                            ooooooooxxxxxx.........     .xx......                                    +                            oooooooooooxxx...        .........                                       +                           ooooooooooooooooooxx.......x....x..                                       +                          oooooooooooooooooooooooooxx.......                                         +                         ooxxxxxxxxxxxxxoooooooooooooo....                                           +                            x...xxxxxxxxxxxxxxoooooxxxx.                                             +                                 ...........xxxxooxxx.                                               +                                               .xox                                                  +                                                                                                     +                                                                                                     +                                                                                                     diff --git a/src/Main.hs b/src/Main.hs index fed4a33..918b70a 100644 --- a/src/Main.hs +++ b/src/Main.hs @@ -16,13 +16,15 @@ data Options = Options { srcFile :: String , width :: Int , height :: Int + , trueColor :: Bool } options :: Parser Options options = Options <$> argument str (metavar "SRC" <> help "source file (or - for stdin)") <*> argument auto (metavar "WIDTH" <> help "resulting width") - <*> argument auto (metavar "HEIGH" <> help "resulting height") + <*> argument auto (metavar "HEIGHT" <> help "resulting height") + <*> flag True False (long "256-colors" <> short 'c' <> help "only use 256-color-mode for old terminals") opthelp :: ParserInfo Options opthelp = info (helper <*> options) @@ -35,7 +37,7 @@ main :: IO () main = execParser opthelp >>= run run :: Options -> IO () -run (Options src w h) = do +run (Options src w h c) = do src' <- if src == "-" then B.getContents else B.readFile src case decodeImage src' of Left err -> putStrLn err @@ -43,7 +45,7 @@ run (Options src w h) = do case extractDynImage img >>= pixelize w h of Nothing -> return () Just (f,b) -> - let str = img2ascii conv (f,b) + let str = if c then img2ascii conv (f,b) else img2ascii conv256 (f,b) in mapM_ (\x -> putStr x >> putStrLn "\x1b[0m") (concat <$> str) chunksof :: Int -> [a] -> [[a]] @@ -63,6 +65,24 @@ conv (fp@(PixelRGB8 fr fg fb),PixelRGB8 br bg bb) = printf "\x1b[48;2;%d;%d;%dm\ | x > 10 = '.' | otherwise = ' ' +conv256 :: (PixelRGB8,PixelRGB8) -> String +conv256 (fp@(PixelRGB8 fr fg fb),PixelRGB8 br bg bb) = printf "\x1b[48;5;%dm\x1b[38;5;%dm%c" bcolor fcolor (lumi.computeLuma $ fp) + where + -- converts [0..255] -> [0..5] + s = (`div` 51) + -- conversion: 6x6x6 rgb-cube so color is red * 36 + green * 6 + blue + 16 offset with red/green/blue in [0..5] + bcolor = s br * 36 + s bg * 6 + s bb + 16 + fcolor = s fr * 36 + s fg * 6 + s fb + 16 + lumi :: Word8 -> Char + lumi x + | x > 225 = '@' + | x > 180 = 'O' + | x > 150 = 'X' + | x > 50 = 'o' + | x > 25 = 'x' + | x > 10 = '.' + | otherwise = ' ' + img2ascii :: ((PixelRGB8,PixelRGB8) -> String) -> (Image PixelRGB8,Image PixelRGB8) -> [[String]] img2ascii c (fg@(Image w h _),bg@(Image w' h' _)) = (fmap.fmap) (c.(uncurry (pixelAt fg) &&& uncurry (pixelAt bg))) [[(x,y) | x <- [0..w-1]] | y <- [0..h-1]] From 46ef59dde1806393bdcb511b2c9e909e2ba9e5ee Mon Sep 17 00:00:00 2001 From: Stefan Dresselhaus Date: Sun, 6 Dec 2015 01:55:16 +0100 Subject: [PATCH 3/6] switched from flag to switch in optparser --- src/Main.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Main.hs b/src/Main.hs index 918b70a..03c517b 100644 --- a/src/Main.hs +++ b/src/Main.hs @@ -24,7 +24,7 @@ options = Options <$> argument str (metavar "SRC" <> help "source file (or - for stdin)") <*> argument auto (metavar "WIDTH" <> help "resulting width") <*> argument auto (metavar "HEIGHT" <> help "resulting height") - <*> flag True False (long "256-colors" <> short 'c' <> help "only use 256-color-mode for old terminals") + <*> switch (long "256-colors" <> short 'c' <> help "only use 256-color-mode for old terminals") opthelp :: ParserInfo Options opthelp = info (helper <*> options) From da4f4352429646018d5e2f3efeb4485f11d7136a Mon Sep 17 00:00:00 2001 From: Stefan Dresselhaus Date: Sun, 6 Dec 2015 02:00:01 +0100 Subject: [PATCH 4/6] improved readme --- README.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0851e89..c35f8a8 100644 --- a/README.md +++ b/README.md @@ -3,9 +3,13 @@ Image to ASCII-Converter # build instructions -execute `stack build`. Result is then in your `.stack-work/dist/$system/$cabal/build/img2ascii/` folder. Replace `$system` and `$cabal` according to your installation. +Execute `stack build`. Result is then in your `.stack-work/dist/$system/$cabal/build/img2ascii/` folder. Replace `$system` and `$cabal` according to your installation. -Trhee example images in the resolution of 225x65, 225x65 and 100x40 are included. To view them just type `cat image1.img` in a suitable (aka TrueColor) terminal. +Alternatively you can install the program with `stack install` to `~/.local/img2ascii` or for all users (if `stack install` is invoked as root). + +Three true-color example images in the resolution of 225x65, 225x65 and 100x40 are included. To view them just type `cat image1.img` in a suitable (aka TrueColor) terminal. + +One 256-color example is also included. Type `cat rose_256.img` to view that. # example From d574d49f274691dc35ea96c1209046d69d3ea264 Mon Sep 17 00:00:00 2001 From: Stefan Dresselhaus Date: Mon, 7 Dec 2015 16:35:04 +0100 Subject: [PATCH 5/6] fixed foldl1-bug on empty list --- src/Main.hs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/Main.hs b/src/Main.hs index 03c517b..b68635e 100644 --- a/src/Main.hs +++ b/src/Main.hs @@ -4,7 +4,7 @@ import Codec.Picture import Codec.Picture.Types import Data.Maybe (fromJust) import Data.Word (Word8) -import Data.List (transpose) +import Data.List as L (transpose,foldl') import Text.Printf (printf) import Control.Arrow ((&&&)) import Options.Applicative @@ -97,16 +97,17 @@ pixelize tw th im@(Image iw ih id) = windowh = fromIntegral ih / fromIntegral th folder :: ((PixelRGB8, Int, Int) -> (PixelRGB8, Int, Int) -> (PixelRGB8, Int, Int)) -> Double -> Double -> Image PixelRGB8 -> Int -> Int -> (Image PixelRGB8, PixelRGB8) -folder f ww wh im@(Image iw ih id) x y = (im,(\(a,_,_) -> a) $ foldl1 f +folder f ww wh im@(Image iw ih id) x y = (im,(\(a,_,_) -> a) $ L.foldl' f (pixelAt im x' y',0,0) [ (pixelAt im (x'+dx) (y'+dy),dx,dy) - | dx <- [-(floor $ ww / 2)..(floor $ ww*0.5)] - , dy <- [-(floor $ ww / 2)..(floor $ ww*0.5)] + | dx <- [-dw..dw] + , dy <- [-dw..dw] , x'+dx > 0 && x'+dx < iw , y'+dy > 0 && y'+dy < ih ]) where - x' = floor $ fromIntegral x *ww - y' = floor $ fromIntegral y *wh + dw = floor $ ww + x' = floor $ fromIntegral x * ww + y' = floor $ fromIntegral y * wh filterfun :: (PixelRGB8,Int,Int) -> (PixelRGB8, Int, Int) -> (PixelRGB8,Int,Int) filterfun (x@(PixelRGB8 r g b),_,_) (y@(PixelRGB8 r' g' b'),_,_) = if computeLuma x > computeLuma y then (x,0,0) else (y,0,0) From a4380981f2297137779b9e0a78a8db1eaa8592db Mon Sep 17 00:00:00 2001 From: Stefan Dresselhaus Date: Wed, 16 Dec 2015 00:35:12 +0100 Subject: [PATCH 6/6] changed meaning of 256-color flag to match the description --- src/Main.hs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Main.hs b/src/Main.hs index b68635e..68fec21 100644 --- a/src/Main.hs +++ b/src/Main.hs @@ -37,7 +37,7 @@ main :: IO () main = execParser opthelp >>= run run :: Options -> IO () -run (Options src w h c) = do +run (Options src w h redcol) = do src' <- if src == "-" then B.getContents else B.readFile src case decodeImage src' of Left err -> putStrLn err @@ -45,7 +45,7 @@ run (Options src w h c) = do case extractDynImage img >>= pixelize w h of Nothing -> return () Just (f,b) -> - let str = if c then img2ascii conv (f,b) else img2ascii conv256 (f,b) + let str = if redcol then img2ascii conv256 (f,b) else img2ascii conv (f,b) in mapM_ (\x -> putStr x >> putStrLn "\x1b[0m") (concat <$> str) chunksof :: Int -> [a] -> [[a]]