Создание изображений для использования с 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')
Другие вопросы по тегам