Which haskell library will let me save a 2D array/vector to a png/jpg/gif… file?

后端 未结 4 1134
走了就别回头了
走了就别回头了 2020-12-31 05:52

I am playing around with haskell, starting with simple plotting programs to wet my feet. I need a library that will let me save a 2D array/vector to an image file. I don\'t

相关标签:
4条回答
  • 2020-12-31 06:26

    The more recent JuicyPixels library let you save image to Jpg/Png/Tiff easily, you can use it in combination with Repa with the JuicyPixels-repa library.

    0 讨论(0)
  • 2020-12-31 06:32

    A new combination is:

    • repa; for n-dimensional arrays, plus
    • repa-devil, for image loading in dozens of formats.

    Repa is the only widely used array library that is automatically parallelized.

    An example, from the repa tutorial, using readImage and writeImage, to read an image, rotate it, and write it back out, in whatever format:

    import System.Environment
    import Data.Word
    import Data.Array.Repa hiding ((++))
    import Data.Array.Repa.IO.DevIL
    
    main = do
        [f] <- getArgs
        runIL $ do
            v   <- readImage f
            writeImage ("flip-"++f) (rot180 v)
    
    rot180 :: Array DIM3 Word8 -> Array DIM3 Word8
    rot180 g = backpermute e flop g
        where
            e@(Z :. x :. y :. _)   = extent g
    
            flop (Z :. i         :. j         :. k) =
                 (Z :. x - i - 1 :. y - j - 1 :. k)
    
    0 讨论(0)
  • 2020-12-31 06:42

    You might also want to check out Diagrams

    Example code for the dragon fractal:

    {- Heighway dragon.  See http://en.wikipedia.org/wiki/Dragon_curve. -}
    module Main where
    
    import Graphics.Rendering.Diagrams
    import Control.Monad.State
    import Data.Maybe
    
    dragonStr :: Int -> String
    dragonStr 0 = "FX"
    dragonStr n = concatMap rules $ dragonStr (n-1)
      where rules 'X' = "X+YF+"
            rules 'Y' = "-FX-Y"
            rules c = [c]
    
    strToPath :: String -> Path
    strToPath s = pathFromVectors . catMaybes $ evalState c (0,-1)
      where c        = mapM exec s
            exec 'F' = Just `fmap` get
            exec '-' = modify left >> return Nothing
            exec '+' = modify right >> return Nothing
            exec _   = return Nothing
            left (x,y)  = (-y,x)
            right (x,y) = (y,-x)
    
    dragon :: Int -> Diagram
    dragon = lc red . curved 0.8 . strToPath . dragonStr
    
    main = renderAs PNG "dragon.png" (Width 300) (dragon 12)
    
    0 讨论(0)
  • 2020-12-31 06:48

    I'd start with PGM library. This is a very simple uncompressed graymap format. Almost no additinal dependencies. You can convert PGM to other formats with ImageMagick or other tools.

    PGM supports generic IArray interface, and should work with most of the standard Haskell arrays. You can easily parallelize array computations with Control.Parallel.Strategies.

    PGM usage example:

    ghci> :m + Data.Array Graphics.Pgm 
    ghci> let a = accumArray (+) 0 ((0::Int,0::Int),(127,127)) [ ((i,i), 1.0::Double) | i <- [0..127] ]
    ghci> arrayToFile "t.pgm" (fmap round a)
    

    And this is the image:

    t.pgm

    Otherwise you may use Codec-Image-DevIL which can save unboxed arrays to many of the image formats. You'll need DevIL library too. And you'll need to convert all arrays to that particular type of them (UArray (Int, Int, Int) Word8).

    Finally, if you want bleeding edge, you may consider repa parallel arrays and corresponding repa-io library, which can write them to BMP images. Unfortunately, today repa is not yet buildable with the new GHC 7.0.2 and doesn't give performance advantages on old GHC 6.12.

    0 讨论(0)
提交回复
热议问题