首页 > 解决方案 > 如何在 JuicyPixels、Haskell 中使用 readPixel 和 writePixel?

问题描述

这篇文章中,我找到了一些使用MutableImagewithreadPixelwritePixel函数的例子,但我认为它太复杂了,我的意思是,我可以不用ST Monad吗?

假设我有这个

eDynamicImage <- readImage
eImage <- convertRGBA8 <$> eDynamicImage

所以我可以pixelMap像这样将基于过滤器应用于该图像negative <$> eImage,但是如何使用像素及其坐标?有人可以解释一下我是什么Mutable Image,我怎么能从DynamicImageor得到这个Image

是否有任何干净的代码可以使用此功能旋转图像?

UPD 2.0:我使用内置的 JuicyPixelsgenerateImage函数制作了完全正常的旋转功能:

rotate :: Double -> Image PixelRGBA8 -> Image PixelRGBA8
rotate n img@Image {..} = generateImage rotater newW newH
  where rotater x y = if srcX x y < imageWidth && srcX x y >= 0 && srcY x y < imageHeight && srcY x y >= 0
                       then pixelAt img (srcX x y) (srcY x y)
                       else PixelRGBA8 255 255 255 255
        srcX x y = getX center + rounding (fromIntegral (x - getX newCenter) * cos' + fromIntegral (y - getY newCenter) * sin')
        srcY x y = getY center + rounding (fromIntegral (y - getY newCenter) * cos' - fromIntegral (x - getX newCenter) * sin')
        center = (imageWidth `div` 2, imageHeight `div` 2)
        newCenter = (newW `div` 2, newH `div` 2)
        newW = rounding $ abs (fromIntegral imageHeight * sin') + abs (fromIntegral imageWidth * cos')
        newH = rounding $ abs (fromIntegral imageHeight * cos') + abs (fromIntegral imageWidth * sin')
        sin' = sin $ toRad n
        cos' = cos $ toRad n

在哪里

rounding a = floor (a + 0.5)
getX = fst 
getY = snd
toRad deg = deg * (pi/180)

如果有人需要,就是这样。感谢@Carsten 的建议!

标签: imagehaskellimage-processingpixel

解决方案


AnMutableImage是您可以改变(就地更改)Image的 - 默认情况下是不可变的。您将需要某种允许这样做的 monad(请参阅文档 - 有一些包括STand IO)。

要获得一个MutableImage你可以使用的 - 然后你可以使用和thawImage工作(获取/设置)像素- 之后你可以再次取回一个不可变的readPixelwritePixelfreezeImageImage

如果您想知道如何旋转图像,您可以查看以下source code内容rotateLeft

rotateLeft90 :: Pixel a => Image a -> Image a
rotateLeft90 img@Image {..} =
  generateImage gen imageHeight imageWidth
  where
    gen x y = pixelAt img (imageWidth - 1 - y) x

如您所见,它不使用可变图像,而是从旧像素生成新图像(使用pixelAt代替readPixel

以防万一 - 这是使用记录通配符扩展从Image a- 参数中提取所有字段(这就是Image {..}- imageHeightimageWidth从那里提取的)


推荐阅读