2013-02-26 25 views
1

我正在使用repa-devil來讀取和寫入圖像。現在我需要以編程方式創建圖像。但是,Data.Array.Repa.IO.DevIL中的Image構造函數(如RGB)都需要外部內存緩衝區陣列。我必須走出去學習如何使用這些外國指針(聽起來很可怕)嗎?或者我可以將一個拆箱數組轉換爲我需要的類型?創建圖像以使用repa-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 

回答

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

我想你真的需要寫一些不同於隨機圖像的東西。如果你可以構造純索引功能,還有更有效的方式來加載陣列到內存中,通過D elayed陣列的方式:

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 [email protected](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')