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

Image Haskell,如何在JuicyPixels中使用readPixel和writePixel?,image,haskell,image-processing,pixel,Image,Haskell,Image Processing,Pixel,在文章中,我发现了一些使用MutableImage和readPixel和writePixel函数的例子,但我认为这太复杂了,我的意思是,没有ST Monad我能做到吗 假设我有这个 eDynamicImage <- readImage eImage <- convertRGBA8 <$> eDynamicImage 在哪里 如果有人需要它,就这样。谢谢@Carsten的建议 一个MutableImage是一个可以进行变异(就地更改)Image默认情况下是不可变的。不过,

在文章中,我发现了一些使用
MutableImage
readPixel
writePixel
函数的例子,但我认为这太复杂了,我的意思是,没有
ST Monad
我能做到吗

假设我有这个

eDynamicImage <- readImage
eImage <- convertRGBA8 <$> eDynamicImage
在哪里


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

一个
MutableImage
是一个可以进行变异(就地更改)Image默认情况下是不可变的。不过,您需要某种monad来支持这一点(请参阅文档-有一些包括
ST
IO

要获得一幅可变的
图像
,您可以使用-然后您可以使用和(获取/设置)像素-之后您可以再次获取一幅不可变的
图像

如果您想知道如何旋转图像,可以检查以下各项:

rotateLeft90::像素a=>图像a->图像a
旋转90度img@Image {..} =
generateImage gen图像高度图像宽度
哪里
gen x y=像素img(图像宽度-1-y)x
如您所见,它不使用可变图像,而是从旧像素生成新图像(使用而不是
readPixel


以防万一-这是使用扩展从
图像a
-参数中提取所有字段(这就是
图像{..}
所做的-
图像高度
图像宽度
从那里拉出来)

您能给出一个以非任意角度旋转的示例吗(图像方向可能无法切换,例如,白色背景而不是空像素)?我尝试使用我提到的文章中的示例进行重写,但在执行
\\Data\\Vector\\Generic.hs:248((!):索引越界(26680002668000)
。我尝试使用此公式
让coordX=rounding$(cos(toRad n)*从积分x)-(sin(toRad n)*从积分y)
让coordY=四舍五入$(sin(toRad n)*从积分x)+(cos(toRad n)*从积分y)
取整
就是
Double->Int
。我也试过这样做:
让newX | coordX>=imageWidth | | coordX=imageHeight | | coordY你的意思是使用任意角度旋转?如果看不到你所有的代码,这有点难说,但如果我读对了,你是围绕原点旋转的,所以你会产生”“不"坐标…第二个注释也有点奇怪,因为当然每个数字都是>=或者哦,对不起,我是说任意的。我把那些
newX
newY
放进
writePixel
函数中,没有改变示例中的任何其他内容…是的,但是如果我把代码弄对了
newX=0
newY=0
s-您只需更改一个像素-您还应该了解如何计算旋转坐标-您的公式似乎在原点附近-这很好-我认为您需要中心-在这种情况下,首先使用(-width/2,-height/2)进行平移,然后使用公式旋转,然后向后平移(width/2,height/2)-也可以裁剪超出范围的像素(坐标<0 |>=宽度/高度)-但在我看来,这是另一个与原始问题无关的问题
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)