如何在 Haskell 中使用 Gloss 和 JuicyPixels 绘制图像?

How to draw an image with Gloss and JuicyPixels in Haskell?

我尝试用 Gloss 绘制图像。但是,它仅支持开箱即用的位图,因此我最终也使用了 JuicyPixels 来加载其他图像格式。我最终得到的是:

import Data.Function
import Graphics.Gloss
import Codec.Picture
import qualified Data.ByteString.Lazy as BytesL


window :: Display
window = InWindow "Mona Lisa" (500, 500) (10, 10)

image :: FilePath -> IO (Maybe Picture)
image path = do
  img <- readImage path -- load with JuicyPixels
  pure $ case img of
    Left    _ -> Nothing
    Right img -> do
      let (w, h) = (dynamicMap imageWidth img, dynamicMap imageHeight img)
      let bitmap = convertRGBA8 img & encodeBitmap & BytesL.toStrict -- to bytes
      let format = BitmapFormat BottomToTop PxRGBA
      Just $ bitmapOfByteString w h format bitmap  False -- to Gloss bitmap

main :: IO ()
main = do
  Just img <- image "resources/mona_lisa.png"
  display window white img

但是,这不知何故弄乱了 RGB 通道。所以我得到了前者

将位图从 JuicyPixels 传递到 Gloss 的正确方法是什么?

所以,简单的答案是简单地使用现有的库 gloss juicy

但是,如果您不需要额外的依赖项,您可以直接使用这个实现(从提到的库中复制粘贴):

-- | O(N) conversion from 'PixelRGBA8' image to gloss 'Picture', where N is the number of pixels.
fromImageRGBA8 :: Image PixelRGBA8 -> Picture
fromImageRGBA8 (Image { imageWidth = w, imageHeight = h, imageData = id }) =
  bitmapOfForeignPtr w h  (BitmapFormat TopToBottom PxRGBA) ptr True
  where (ptr, _, _) = unsafeToForeignPtr id