Подтвердить что ты не робот

Какая библиотека haskell позволит мне сохранить 2D-массив/вектор в файле png/jpg/gif...?

Я играю с haskell, начиная с простых программ построения, чтобы намочить ноги. Мне нужна библиотека, которая позволит мне сохранить 2D-массив/вектор в файл изображения. Я не хочу писать список цветов. Я хочу использовать контейнеры, предназначенные для вычисления массива/вектора, такие как вычисления и могут (почти, почти) автоматически распараллеливаться.

EDIT Возможность сохранять цветные изображения является обязательной.

4b9b3361

Ответ 1

Я бы начал с PGM библиотеки. Это очень простой несжатый формат graymap. Почти никаких дополнительных зависимостей. Вы можете конвертировать PGM в другие форматы с помощью ImageMagick или других инструментов.

PGM поддерживает общий интерфейс IArray и должен работать с большинством стандартных массивов Haskell. Вы можете легко распараллелить вычисления массивов с помощью Control.Parallel.Strategies.

Пример использования PGM:

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)

И это изображение:

t.pgm

В противном случае вы можете использовать Codec-Image-DevIL, который может сохранять распакованные массивы во многие форматы изображений. Вам понадобится DevIL библиотека. И вам нужно будет преобразовать все массивы в их тип (UArray (Int, Int, Int) Word8).

Наконец, если вам нужен край кровотечения, вы можете рассмотреть параллельные массивы repa и соответствующую библиотеку repa-io, которые могут записывать их в изображения BMP. К сожалению, сегодня repa еще не создан с новым GHC 7.0.2 и не дает преимуществ производительности на старом GHC 6.12.

Ответ 2

Новая комбинация:

  • repa; для n-мерных массивов плюс
  • repa-devil, для загрузки изображений в десятках форматов.

Repa - единственная широко используемая библиотека массивов, которая автоматически распараллеливается.

Например, из repa tutorial, используя readImage и writeImage, чтобы прочитать изображение, повернуть его и записать его обратно в любом формате:

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
        [email protected](Z :. x :. y :. _)   = extent g

        flop (Z :. i         :. j         :. k) =
             (Z :. x - i - 1 :. y - j - 1 :. k)

Ответ 3

Более новая библиотека JuicyPixels позволяет вам легко сохранять изображение в Jpg/Png/Tiff, вы можете использовать его в комбинации с Repa с библиотекой JuicyPixels-repa.

Ответ 4

Вы также можете проверить Diagrams

Пример кода для фрактала дракона:

{- 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)