1

I am using repa-devil to read and write images. Now I need to programmatically create images. However, the Image constructors (such as RGB) in Data.Array.Repa.IO.DevIL all require foreign memory buffer arrays. Do I have to go off and learn how to work with that foreign pointer stuff (which sounds scary)? Or can I convert an unboxed array to the type I need?

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
4

2 回答 2

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构造函数。

于 2013-02-26T18:37:10.463 回答
1

我想你真的需要写一些与随机图像不同的东西。如果您可以构造纯索引函数,则有更有效的方法将数组加载到内存中,通过Delayed 数组:

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')
于 2013-02-27T20:15:46.687 回答