我有PNG文件,而the Gloss library有Bitmap
的{{1}}构造函数。由于文件类型,我无法使用Picture
,因此我正在搜索如何加载PNG文件,将其转换为BMP,并将其提供给loadBMP :: FilePath -> IO Picture
,bitmapOfBMP :: BMP -> Picture
或{ {1}}。
使用JuicyPixels进行测试
bitmapOfForeignPtr :: Int -> Int -> ForeignPtr Word8 -> Bool -> Picture
一切都成功,但图像完全不同。
答案 0 :(得分:3)
这就是我制作JuicyPixel-repa的原因。您将图像作为Repa数组读入并将其转换为gloss-osm中的Picture
转换为repaToPicture :: Bool -> Array F.F DIM3 Word8 -> (Int, Int, Picture)
repaToPicture b arr =
let fptr = F.toForeignPtr arr
bs = BI.fromForeignPtr fptr 0 len
in (col, row, bitmapOfByteString row col bs b)
where
len = row * col * depth
(Z :. row :. col :. depth) = extent arr
:
DynamicImage
或者,您可以直接使用JuicyPixels,大约使用imgData
类型,并从包含的Image
获取基础{{1}}。
答案 1 :(得分:1)
即使我没有单独回答,但多亏了托马斯的回答,我会在这里发帖而不是问题。
提醒一下,目标是将BMP文件转换为Gloss'图片,因此我编写了一个名为bmpToPic
的函数。我把它放在一个模块中,因为它使用了另外两个函数,并且需要很多导入。
此外,托马斯回答的repaToPicture
在这里略有不同。
module PngToPic
(pngToPic)
where
import Data.ByteString as B
import Data.Word
import Codec.Picture.Png
import Codec.Picture.Repa
import qualified Data.ByteString.Internal as BI
import Data.Array.Repa ((:.)(..), Z, Z(..), extent, DIM3, Array)
import qualified Data.Array.Repa as R
import qualified Data.Array.Repa.Repr.ForeignPtr as F
import Graphics.Gloss.Data.Picture
pngToPic :: ByteString -> Picture
pngToPic png
= let
Right img -- unsafe
= decodePng png
repa
= imgData (convertImage img :: Img RGBA)
in repaToPicture True repa
repaToPicture :: Bool -> Array F.F DIM3 Word8 -> Picture
repaToPicture b arr
= bitmapOfByteString row col bs b
where
bs
= BI.fromForeignPtr fptr 0 (R.size sh)
fptr
= F.toForeignPtr arr'
sh@(Z :. col :. row :. depth)
= extent arr'
arr'
= flipVert arr
flipVert :: Array F.F DIM3 Word8 -> Array F.F DIM3 Word8
flipVert g
= R.computeS $ R.backpermute e flop g
where
e@(Z :. x :. y :. _)
= extent g
flop (Z :. i :. j :. k)
= Z :. x - i - 1 :. j :. k
你这样使用它:
import Data.ByteString as B
import Graphics.Gloss.Interface.Pure.Game
import PngToPic
main = do
png <- B.readFile "someImage.png"
game $ pngToPic png
game pic
= play
(InWindow "Test" (700, 500) (10, 10))
white
30
pic
id
(const id)
(const id)
,图像将显示在窗口中间。
答案 2 :(得分:0)
对于任何在2017年磕磕绊绊的人来说,这已经变得非常容易了!我花了一段时间才弄明白,因为上面的示例代码似乎不再起作用。这是我将PNG读入图片的功能:
import Codec.Picture.Repa (readImageRGBA, toByteString, reverseColorChannel)
import Graphics.Gloss
readPng :: FilePath -> Int -> Int -> IO Picture
readPng path w h = do
(Right img) <- readImageRGBA path
let bs = toByteString $ reverseColorChannel img
return $ bitmapOfByteString w h (BitmapFormat TopToBottom PxRGBA) bs True