Merge branch 'master' of github.com:Drezil/img2ascii

This commit is contained in:
Nicole Dresselhaus 2016-01-06 23:08:56 +01:00
commit 728c26449a
3 changed files with 84 additions and 19 deletions

View File

@ -3,9 +3,13 @@ Image to ASCII-Converter
# build instructions # 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 # example

40
rose_256.img Normal file
View File

@ -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                                                 
                                                                                                    
                                                                                                    
                                                                                                    

View File

@ -4,7 +4,7 @@ import Codec.Picture
import Codec.Picture.Types import Codec.Picture.Types
import Data.Maybe (fromJust) import Data.Maybe (fromJust)
import Data.Word (Word8) import Data.Word (Word8)
import Data.List (transpose) import Data.List as L (transpose,foldl')
import Text.Printf (printf) import Text.Printf (printf)
import Control.Arrow ((&&&)) import Control.Arrow ((&&&))
import Options.Applicative import Options.Applicative
@ -16,13 +16,15 @@ data Options = Options
{ srcFile :: String { srcFile :: String
, width :: Int , width :: Int
, height :: Int , height :: Int
, trueColor :: Bool
} }
options :: Parser Options options :: Parser Options
options = Options options = Options
<$> argument str (metavar "SRC" <> help "source file (or - for stdin)") <$> argument str (metavar "SRC" <> help "source file (or - for stdin)")
<*> argument auto (metavar "WIDTH" <> help "resulting width") <*> argument auto (metavar "WIDTH" <> help "resulting width")
<*> argument auto (metavar "HEIGH" <> help "resulting height") <*> argument auto (metavar "HEIGHT" <> help "resulting height")
<*> switch (long "256-colors" <> short 'c' <> help "only use 256-color-mode for old terminals")
opthelp :: ParserInfo Options opthelp :: ParserInfo Options
opthelp = info (helper <*> options) opthelp = info (helper <*> options)
@ -35,7 +37,7 @@ main :: IO ()
main = execParser opthelp >>= run main = execParser opthelp >>= run
run :: Options -> IO () run :: Options -> IO ()
run (Options src w h) = do run (Options src w h redcol) = do
src' <- if src == "-" then B.getContents else B.readFile src src' <- if src == "-" then B.getContents else B.readFile src
case decodeImage src' of case decodeImage src' of
Left err -> putStrLn err Left err -> putStrLn err
@ -43,7 +45,7 @@ run (Options src w h) = do
case extractDynImage img >>= pixelize w h of case extractDynImage img >>= pixelize w h of
Nothing -> return () Nothing -> return ()
Just (f,b) -> Just (f,b) ->
let str = img2ascii conv (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) in mapM_ (\x -> putStr x >> putStrLn "\x1b[0m") (concat <$> str)
chunksof :: Int -> [a] -> [[a]] 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 = '.' | x > 10 = '.'
| otherwise = ' ' | 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 :: ((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]] 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]]
@ -77,16 +97,17 @@ pixelize tw th im@(Image iw ih id) =
windowh = fromIntegral ih / fromIntegral th 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 :: ((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) [ (pixelAt im (x'+dx) (y'+dy),dx,dy)
| dx <- [-(floor $ ww / 2)..(floor $ ww*0.5)] | dx <- [-dw..dw]
, dy <- [-(floor $ ww / 2)..(floor $ ww*0.5)] , dy <- [-dw..dw]
, x'+dx > 0 && x'+dx < iw , x'+dx > 0 && x'+dx < iw
, y'+dy > 0 && y'+dy < ih , y'+dy > 0 && y'+dy < ih
]) ])
where where
x' = floor $ fromIntegral x *ww dw = floor $ ww
y' = floor $ fromIntegral y *wh x' = floor $ fromIntegral x * ww
y' = floor $ fromIntegral y * wh
filterfun :: (PixelRGB8,Int,Int) -> (PixelRGB8, Int, Int) -> (PixelRGB8,Int,Int) 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) filterfun (x@(PixelRGB8 r g b),_,_) (y@(PixelRGB8 r' g' b'),_,_) = if computeLuma x > computeLuma y then (x,0,0) else (y,0,0)