F#从内存流创建位图时抛出异常

3
我正在获取数据。
System.ArgumentException: 'Parameter is not valid.' 

由于某些原因。

我正在解决的问题:

let image = Bitmap.FromStream stream

这就是我的所能提供的。

let ChangeBitmapColors (bitmap : Bitmap) =
Console.WriteLine bitmap.Size

let width = bitmap.Width
let height = bitmap.Height

let rectangle = new Rectangle(0, 0, width, height)

let bitmapData = bitmap.LockBits(rectangle, Imaging.ImageLockMode.ReadOnly, bitmap.PixelFormat)
let length = bitmapData.Stride * height
let bitmapArray : byte[] = Array.zeroCreate length

Marshal.Copy(bitmapData.Scan0, bitmapArray, 0, length)

bitmap.UnlockBits bitmapData

//todo something with bitmapArray

use stream = new MemoryStream(bitmapArray)                                           

let image = Bitmap.FromStream stream

stream.Dispose |> ignore

image

有什么想法我在这里做错了吗?提前感谢。

@ildjarn,嗨,最初有bitmap.PixelFormat,我在故障排除时尝试使用特定的像素格式,但仍然遇到了相同的异常。 - d.dizhevsky
顺便问一下,你看到这个了吗?https://dev59.com/o1XTa4cB1Zd3GeqPyyjF - FoggyFinder
2
好的,下一个尝试 - let image = new Bitmap(width, height, bitmapData.Stride, bitmap.PixelFormat,Marshal.UnsafeAddrOfPinnedArrayElement(bitmapArray, 0)) - FoggyFinder
2
@d.dizhevskiy,我真的建议你加入F# Slack。最近开放了#ru-general频道(如果你更喜欢俄语)。 - FoggyFinder
2
小事一桩,但是……当使用use stream时,我不认为有必要显式调用stream.Dispose - Bent Tranberg
显示剩余2条评论
1个回答

3

我不知道为什么你的代码不起作用(我测试了它并得到了相同的结果)。

另一个选项(对我有效)是使用Marshal.UnsafeAddrOfPinnedArrayElement

let image = new Bitmap(width, height, bitmapData.Stride, bitmap.PixelFormat,Marshal.UnsafeAddrOfPinnedArrayElement(bi‌​tmapArray, 0))

编辑

感谢@ildjarn的解释:

流媒体无法工作,因为它只是原始像素数据,没有图像头,所以无法知道简单的事情,如图像尺寸和调色板类型。流媒体方法是可行的,但您还需要将图像头保存到流中,而不仅仅是扫描线。


生成的位图显示正常。 - Bent Tranberg
无论如何,我想知道为什么在那种情况下流不起作用:( - d.dizhevsky
3
由于流中没有图像头,所以无法知道简单的东西,例如图像尺寸和调色板类型。因此,该流无法工作,因为它只是原始像素数据。流方法是可行的,但您需要将图像头保存到流中,而不仅仅是扫描线。 - ildjarn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接