Создание изображений для использования с repa-devil
Я использую 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 ответа
Самый простой способ будет использовать более общие 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
конструктор.
Я полагаю, на самом деле вам нужно написать что-то отличное от случайного изображения. Если вы можете построить чистую функцию индексации, есть НАМНОГО более эффективный способ загрузки массива в память посредством D
выложенный массив:
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')