创建要与repa-devil一起使用的图像

时间:2013-02-26 17:45:00

标签: haskell repa

我正在使用repa-devil来读取和写入图像。现在我需要以编程方式创建图像。但是,Image中的RGB构造函数(例如Data.Array.Repa.IO.DevIL)都需要外部内存缓冲区数组。我是否必须去学习如何使用那些外来指针(听起来很可怕)?或者我可以将未装箱的阵列转换为我需要的类型吗?

emptyImage :: RandomGen r => (Int, Int) -> Rand r Image
emptyImage (w,h) = do
  xs <- getRandomRs (0, 255)
  let ps = take (w*h*3) xs :: [Word8]
  let arr = fromListUnboxed (Z :. w :. h :. (3::Int)) ps :: Array U DIM3 Word8
  let arr2 = ???how can I convert arr??? :: Array F DIM3 Word8
  return $ RGB arr2

2 个答案:

答案 0 :(得分:1)

最简单的方法是使用更通用的fromList函数。 这样,你可以做到

...
let arr = fromList (Z :. w :. h :. (3 :: Int)) ps :: Array F DIM3 Word8
return $ RGB arr

可以在fromList

中找到Data.Array.Repa.Eval功能
fromList :: (Shape sh, Target r e) => sh -> [e] -> Array r sh eSource

通常,您可以确保在展示时产生所需的表示 使用computeP函数的数组。所以,你可以做类似的事情 以下(如果您不介意额外复制)

let arr = fromListUnboxed (Z :. w :. h :. (3::Int)) ps :: Array U DIM3 Word8
arr2 <- computeP arr
return $ RGB arr2

类型注释是不必要的,因为编译器知道它需要什么类型 能够使用RGB构造函数。

答案 1 :(得分:1)

我想你真的需要写一些与随机图像不同的东西。如果你可以构造纯索引函数,那么通过D elayed array将数组加载到内存中的方法有很多:

let delayed = fromFunction (Z :. w :. h :. (3::Int))
                           (\(Z :. x :. y :. comp) -> myComp)
foreignArr <- computeP delayed

使用yarr库和yarr-image-io包 - 端口repa-devil,它看起来像:

let delayed =
        fromFunction (h, w)
                     (\(y, x) -> return $ VecList [myRed, myGreen, myBlue])
foreignArr <- dComputeP delayed

但是,如果你确实想要一个随机图像,yarr允许以相对较快的速度加载有状态计算的数组:

import Data.Yarr
import Data.Yarr.Shape as S
import qualified Data.Yarr.Utils.FixedVector as V
import Data.Yarr.IO.Image

emptyImage :: StdGen -> Dim2 -> IO (Image, StdGen)
emptyImage gen sh@(h, w) = do
    arr <- new sh
    let writeRandColor gen i _ = do
            let (rgb, gen') = runRand (V.replicateM random) gen
            linearWrite arr i rgb
            return gen'
    gen' <- S.foldl writeRandColor (return gen) (const ()) 0 (size sh)
    touchArray arr
    return (RGB arr, gen')