如何将图像转换为颜色矩阵



我正在玩Graphics.GD,我想将图像读取到Color值的矩阵中,有点像这样:

rectFromImage :: Image -> IO [[Color]]
rectFromImage img = do
    size <- imageSize img
    return [[getPixel (x,y) img | x <- [1 .. fst size]] | y <- [1 .. snd size]]

显然,这不起作用,因为getPixel返回IO Color,而不是Color:

Couldn't match type `IO Color' with `Foreign.C.Types.CInt'
Expected type: Color
  Actual type: IO Color
In the return type of a call of `getPixel'
In the expression: getPixel (x, y) img
In the expression: [getPixel (x, y) img | x <- [1 .. fst size]]

如何在getPixel调用的返回中"摆脱IO"?

sequence是您正在寻找的神奇函数。sequence获取IO操作列表,并使其成为IO值列表。打字签名术语:

sequence :: Monad m => [m a] -> m [a]

或者,更具体地说,在您的情况下:

sequence :: [IO a] -> IO [a]

所以你可以做,例如:

do
  putStrLn "Enter three lines of input:"
  irritatedUser <- sequence [getLine, getLine, getLine]
  putStrLn (irritatedUser !! 2)

并且用户写入的最后一行将被打印回。

无论如何,在你的情况下,这意味着你想做

rectFromImage img = do
  size <- imageSize img
  sequence [sequence [getPixel (x,y) img | x <- [1 .. fst size]] | y <- [1 .. snd size]]

我偷偷打了两个sequence电话,从你的[[IO Color]]转到[IO [Color]],然后转到IO [[Color]]

一般来说,你永远不会"摆脱"IO,你只是向上传播它。

最新更新