如何在JuicyPixels中使用readPixel和writePixel,Haskell



在本文中,我发现了一些将MutableImagereadPixelwritePixel函数一起使用的示例,但我认为这太复杂了,我的意思是,没有ST Monad我能做到吗?

假设我有这个

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

所以我可以像negative <$> eImage一样将基于pixelMap的滤波器应用于图像,但我如何处理像素及其坐标呢?有人能解释一下什么是Mutable Image吗?我如何从DynamicImageImage得到这个?

有没有干净的代码可以使用这个函数旋转图像?

UPD2.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的建议!

MutableImage是一个可以变异(就地更改(的Image,默认情况下是不可变的。不过,您需要某种允许这样做的monad(请参阅文档——有一些包括STIO(。

要获得MutableImage,可以使用thawImage,然后使用readPixelwritePixel处理(获取/设置(像素,然后再次使用freezeImage以获得不可变的Image

如果你想知道如何旋转图像,你可以查看rotateLeft:的source code

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从中提取(

相关内容

  • 没有找到相关文章

最新更新