Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/image/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell中的PNG到BMP(用于光泽)_Haskell_Png_Bmp_Gloss - Fatal编程技术网

Haskell中的PNG到BMP(用于光泽)

Haskell中的PNG到BMP(用于光泽),haskell,png,bmp,gloss,Haskell,Png,Bmp,Gloss,我有PNG文件,并且有一个位图构造函数,用于图片。由于文件类型的原因,我无法使用loadBMP::FilePath->IO Picture,因此我正在搜索如何加载PNG文件,将其转换为BMP,并将其馈送到bitmapOfBMP::BMP->Picture,bitmapOfForeignPtr::Int->Int->ForeignPtr Word8->Bool->Picture或bitmapOfByteString::Int->Int->ByteString->Bool->Picture 使用J

我有PNG文件,并且有一个
位图
构造函数,用于
图片
。由于文件类型的原因,我无法使用
loadBMP::FilePath->IO Picture
,因此我正在搜索如何加载PNG文件,将其转换为BMP,并将其馈送到
bitmapOfBMP::BMP->Picture
bitmapOfForeignPtr::Int->Int->ForeignPtr Word8->Bool->Picture
bitmapOfByteString::Int->Int->ByteString->Bool->Picture


使用JuicyPixels进行测试

import Data.ByteString as B
import System.IO as A

import Codec.Picture.Png
import Graphics.Gloss.Interface.Pure.Game


main = do
    png <- B.readFile "samus.png"
    let img = decodePng png
    case img of
        Left x -> A.putStrLn x
        Right x -> do
            let bmp = encodeDynamicPng x
            case bmp of
                Left x -> A.putStrLn x
                Right x -> do
                    let pic = bitmapOfByteString 29 52 x True
                    game pic

game pic
    =  play
        (InWindow "Test" (700, 500) (10, 10))
        white
        30
        pic
        draw
        (const id)
        (const id)

draw bmp
    = bmp
将Data.ByteString作为B导入
将System.IO作为
导入Codec.Picture.Png
导入Graphics.Gloss.Interface.Pure.Game
main=do
png A.putStrLn x
右x->do
设bmp=encodeDynamicPng x
bmp案例
左x->A.putStrLn x
右x->do
设pic=bitmapOfByteString 29 52 x True
游戏图片
游戏图片
=玩
(窗口“测试”(700500)(10,10))
白色
30
照片
画
(const id)
(const id)
绘制bmp
=bmp

一切都成功了,但图像一点都不一样。

这就是我制作JuicyPixel repa的原因。您以Repa数组的形式读入图像,并将其转换为
图片

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

或者,您可以直接使用JuicyPixels,在
DynamicImage
类型上加上大小写,从包含的
图像中获取底层
imgData

,尽管我没有单独给出答案,但多亏了Thomas的答案,我将把它贴在这里,而不是在问题内部

作为提醒,我们的目标是将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)
将Data.ByteString作为B导入
导入Graphics.Gloss.Interface.Pure.Game
进口气视
main=do

png对于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
导入Codec.Picture.Repa(readImageRGBA、toByteString、reverseColorChannel)
导入图形。光泽
readPng::FilePath->Int->Int->IO图片
readPng路径w h=do

(右img)谢谢,我尝试了第二种解决方案。我没有使用
imgData
,因为我不知道如何使用它,而是通过testring
转换为BMP
,它不显示我的图像,而是扩展了蓝色和粉色像素。我在问题中添加了代码。我成功地使用了您的
重新主题图片
。我把密码放在问题里了。
Bool
参数用于什么?为什么它返回
(Int,Int,Picture)
而不是
Picture
?生成的
Picture
是“错误的”,所以我这样做了:
let(w,h,pic)=repatpicture-True-repa;位图u u.bmp u=位图中的pic w h bmp True
。现在,图像显示了,但它逆时针旋转了180度。对不起,我一直很忙,但如果你到那时还需要的话,我会尽力在这个周末帮你。布尔值确定OpenGL系统是否缓存图片。至于轮换,请使用repa。谢谢您的帮助!该教程非常有用:它对我破解代码并使其正常工作进行了充分的解释,并提供了一个随时可用的函数。我在表示方面遇到了一些麻烦,但是
计算
成功了。另外,我说图像旋转了180度,但事实上它是垂直翻转的,所以我只是将
y-j-1
改为
j
,效果很好。另外,作为一个风格点,请注意
\\\\\->id
const id
相同。值得一提的是,我已经为此编写了。很好,它看起来更完整;我试试你的包裹!对于大多数严肃的光泽项目来说,这绝对是必须的。感谢您的帮助和赞扬。我想制作一个更通用的函数,比如fileFormatToGlossPicture,因为它很简单,涵盖了所有的情况,并将其制作成一个包。这是否适用于Graphics.Gloss.Interface.Pure.Game中的Play?我在这里尝试过,但得到的结果是“无法将预期类型
Picture'与实际类型
Int->Int->IO Picture'匹配”。也许我做错了什么。。。有没有办法将IO图片转换成图片?@alitalvez这是一种
IO
类型,因为它需要从文件系统读取。在haskell中,您不能仅在纯函数中将
IO图片
转换为
图片
,因为它与文件系统交互。因此,我为您提供的选项是在初始化游戏之前运行此代码(如
图片)