image - 如何在 JuicyPixels、Haskell 中使用 readPixel 和 writePixel?
问题描述
在这篇文章中,我找到了一些使用MutableImage
withreadPixel
和writePixel
函数的例子,但我认为它太复杂了,我的意思是,我可以不用ST Monad
吗?
假设我有这个
eDynamicImage <- readImage
eImage <- convertRGBA8 <$> eDynamicImage
所以我可以pixelMap
像这样将基于过滤器应用于该图像negative <$> eImage
,但是如何使用像素及其坐标?有人可以解释一下我是什么Mutable Image
,我怎么能从DynamicImage
or得到这个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 的建议!
解决方案
AnMutableImage
是您可以改变(就地更改)Image
的 - 默认情况下是不可变的。您将需要某种允许这样做的 monad(请参阅文档 - 有一些包括ST
and IO
)。
要获得一个MutableImage
你可以使用的 - 然后你可以使用和thawImage
工作(获取/设置)像素- 之后你可以再次取回一个不可变的readPixel
writePixel
freezeImage
Image
如果您想知道如何旋转图像,您可以查看以下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 {..}
- imageHeight
,imageWidth
从那里提取的)
推荐阅读
- python - 使用 Python 从 json 响应中迭代特定值
- flutter - 添加额外的字体样式,无效值单斜体
- javascript - UnhandledPromiseRejectionWarning 未处理的承诺拒绝
- hive - “ExpiredTokenRemover 在 Python 连接到 Dataproc 中的 Hive 期间收到 java.lang.InterruptedException:睡眠中断”
- android - 不删除存在多模式的 AVD 的问题
- lstm - ValueError:无法将输入数组从形状(126,5)广播到形状(126,1)
- python - 如何在 python 中获取 Google 之类的 url 摘录
- python - scipy.integrate.ode 放弃集成
- c# - 如何在.net core Api中逐块下载大文件
- wordpress - Wordpress - 需要搜索栏编码/插件