Какая библиотека haskell позволит мне сохранить 2D-массив/вектор в файле png/jpg/gif...?
Я играю с haskell, начиная с простых программ построения, чтобы намочить ноги. Мне нужна библиотека, которая позволит мне сохранить 2D-массив/вектор в файл изображения. Я не хочу писать список цветов. Я хочу использовать контейнеры, предназначенные для вычисления массива/вектора, такие как вычисления и могут (почти, почти) автоматически распараллеливаться.
EDIT Возможность сохранять цветные изображения является обязательной.
Ответы
Ответ 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)