Arrays 如何将(StorableArray(Int,Int)Word8)转换为lazy ByteString?
我试图加载一个PNG文件,获取未压缩的RGBA字节,然后将它们发送到gzip或zlib包 pngload包以(StorableArray(Int,Int)字8的形式返回图像数据,而压缩包采用lazy ByteStrings。因此,我试图构建一个(StorableArray(Int,Int)Word8->ByteString)函数 到目前为止,我已经尝试了以下方法:Arrays 如何将(StorableArray(Int,Int)Word8)转换为lazy ByteString?,arrays,haskell,bytestring,Arrays,Haskell,Bytestring,我试图加载一个PNG文件,获取未压缩的RGBA字节,然后将它们发送到gzip或zlib包 pngload包以(StorableArray(Int,Int)字8的形式返回图像数据,而压缩包采用lazy ByteStrings。因此,我试图构建一个(StorableArray(Int,Int)Word8->ByteString)函数 到目前为止,我已经尝试了以下方法: import qualified Codec.Image.PNG as PNG import Control.Monad (mapM
import qualified Codec.Image.PNG as PNG
import Control.Monad (mapM)
import Data.Array.Storable (withStorableArray)
import qualified Data.ByteString.Lazy as LB (ByteString, pack, take)
import Data.Word (Word8)
import Foreign (Ptr, peekByteOff)
main = do
-- Load PNG into "image"...
bytes <- withStorableArray
(PNG.imageData image)
(bytesFromPointer lengthOfImageData)
bytesFromPointer :: Int -> Ptr Word8 -> IO LB.ByteString
bytesFromPointer count pointer = LB.pack $
mapM (peekByteOff pointer) [0..(count-1)]
将合格的Codec.Image.PNG导入为PNG
导入控制.Monad(mapM)
导入Data.Array.Storable(使用StorableArray)
将符合条件的Data.ByteString.Lazy导入为LB(ByteString、pack、take)
导入数据。Word(Word8)
进口国外(Ptr、peekByteOff)
main=do
--将PNG加载到“图像”。。。
字节Ptr字8->IO LB.ByteString
bytesFromPointer count指针=LB.pack$
mapM(peekByteOff指针)[0..(计数-1]
这会导致堆栈内存不足,因此很明显我做了一些非常错误的事情。我可以用Ptr和ForeignPtr尝试更多的东西,但是其中有很多“不安全”的功能
任何帮助都将不胜感激;我相当困惑。一般来说,打包和解包对性能是个坏主意。如果您有一个Ptr,长度以字节为单位,则可以通过两种不同的方式生成strict bytestring:
import qualified Codec.Image.PNG as PNG
import Control.Monad
import Data.Array.Storable (withStorableArray)
import Codec.Compression.GZip
import qualified Data.ByteString.Lazy as L
import qualified Data.ByteString.Unsafe as S
import Data.Word
import Foreign
-- Pack a Ptr Word8 as a strict bytestring, then box it to a lazy one, very
-- efficiently
bytesFromPointer :: Int -> Ptr Word8 -> IO L.ByteString
bytesFromPointer n ptr = do
s <- S.unsafePackCStringLen (castPtr ptr, n)
return $! L.fromChunks [s]
-- Dummies, since they were not provided
image = undefined
lengthOfImageData = 10^3
-- Load a PNG, and compress it, writing it back to disk
main = do
bytes <- withStorableArray
(PNG.imageData image)
(bytesFromPointer lengthOfImageData)
L.writeFile "foo" . compress $ bytes
将合格的Codec.Image.PNG导入为PNG
进口管制
导入Data.Array.Storable(使用StorableArray)
导入Codec.Compression.GZip
将限定的Data.ByteString.Lazy作为L导入
将限定数据.ByteString.S导入为S
导入数据.Word
进口国外
--将一个PTRWord8打包为一个严格的bytestring,然后将其打包为一个懒惰的,非常
--有效地
bytesFromPointer::Int->Ptr Word8->IO L.ByteString
bytesFromPointer n ptr=do
s您的“bytesFromPointer”的问题在于,您从pngload中获取压缩表示形式,即StorableArray,并且希望通过中间列表将其转换为另一个压缩表示形式,即ByteString。有时懒惰意味着中间列表不会在内存中构建,但这里的情况并非如此
“mapM”是初犯。如果展开mapM(peekByteOff指针)[0..(计数-1)]
el0 <- peekByteOff pointer 0
el1 <- peekByteOff pointer 1
el2 <- peekByteOff pointer 2
...
eln <- peekByteOff pointer (count-1)
return [el0,el1,el2,...eln]
el0