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)