如何将字节数组转换为Bitmap实例(.NET)?

前端之家收集整理的这篇文章主要介绍了如何将字节数组转换为Bitmap实例(.NET)?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我在VB.NET中使用相机(在这种情况下是单色).相机的API位于C中,制造商提供封装.像这些情况一样,图像作为字节数组返回.在我特定的情况下,它是每像素8位,所以没有什么花哨的打包可以撤消.

我很惊讶,.NET对这种类型的事情几乎没有什么支持.在线搜索我发现了各种主题,但是在许多情况下,人们都有一个与图像数据相对应的字节数组(即将图像文件读入一个字节数组,然后将.NET解释为一个文件)与标题和一切).

在这种情况下,我需要将原始像素值的数组转换为特别是可以在屏幕上显示内容.

似乎没有任何内置的方式来做到这一点,因为.NET中内置的8bpp格式被编入索引(需要一个调色板),但它似乎不支持调色板的设置.再次,这真的让我感到惊讶. This是我发现的最有希望的话题.

所以我发现这样做的唯一方法是创建一个Bitmap,然后逐个像素复制像素值.在我的情况下,使用SetPixel时,8位MPixel镜像在最快的i7上花费了几秒钟.

我发现使用SetPixel的替代方法是LockBits,它允许您访问构成图像的(非托管)字节数组.这似乎是浪费的,因为我必须在.NET中操作数组,然后将其复制回非管理空间.我已经复制了原始图像数据一次(因此原始图像可以重复使用或被剩下的内容丢弃),所以尽管显着快于使用SetPixel这似乎仍然是浪费的.

这是我有的VB代码

Public Function GetBitmap(ByRef TheBitmap As System.Drawing.Bitmap) As Integer
    Dim ImageData() As Byte
    Dim TheWidth,TheHeight As Integer
    'I've omitted the code here (too specific for this question) which allocates
    'ImageData and then uses Array.Copy to store a copy of the pixel values
    'in it. It also assigns the proper values to TheWidth and TheHeight.

    TheBitmap = New System.Drawing.Bitmap(TheWidth,TheHeight,System.Drawing.Imaging.PixelFormat.Format24bppRgb)
    Dim TheData As System.Drawing.Imaging.BitmapData = TheBitmap.LockBits(
        New System.Drawing.Rectangle(0,TheWidth,TheHeight),Drawing.Imaging.ImageLockMode.ReadWrite,TheBitmap.PixelFormat)
    Dim Image24(Math.Abs(TheData.Stride) * TheHeight) As Byte
    'Then we have two choices: to do it in parallel or not. I tried both; the sequential version is commented out below.
    System.Threading.Tasks.Parallel.For(0,ImageData.Length,Sub(i)
                                                                 Image24(i * 3 + 0) = ImageData(i)
                                                                 Image24(i * 3 + 1) = ImageData(i)
                                                                 Image24(i * 3 + 2) = ImageData(i)
                                                             End Sub)
    'Dim i As Integer
    'For i = 0 To ImageData.Length - 1
    '    Image24(i * 3 + 0) = ImageData(i)
    '    Image24(i * 3 + 1) = ImageData(i)
    '    Image24(i * 3 + 2) = ImageData(i)
    'Next
    System.Runtime.InteropServices.Marshal.Copy(Image24,TheData.Scan0,Image24.Length)
    TheBitmap.UnlockBits(TheData)

    'The above based on
    'http://msdn.microsoft.com/en-us/library/system.drawing.imaging.bitmapdata.aspx

    Return 1

End Function

对于8个MP​​ixel映像,顺序版本从创建TheBitmap到(并包括)对TheBitmap.UnlockBits()的调用消耗大约220毫秒.并行版本更不一致,但范围在60到80毫秒之间.考虑到我正在从四台摄像机同时采集到大量时间的磁盘,这非常令人失望. API附带C中的示例代码,可以以全帧速率(17 fps)同时从所有四个摄像机显示.当然,它不会处理Bitmap,因为GDI访问原始像素值的数组.

总而言之,我必须遍历管理/非管理的屏障,因为没有直接的方法获取一组像素值,并将其“填充”到Bitmap实例中.在这种情况下,我还将像素值复制到24bpp位图中,因为我无法“设置”索引图像中的调色板,因此8bpp不是可行的显示格式.

有没有更好的方法

创建一个 valid bitmap header,并将其预先插入到字节数组中.您只需手动创建56-128字节的数据.

二,create a stream from a byte array.

接下来,create an image or bitmap class by using Image.FromStream()/Bitmap.FromStream()

我不会想像在.Net中有任何原始的成像功能.有一个图像需要的信息,它将是一个非常漫长的参数列表,用于接受原始字节并创建一个想象的方法(它是一个位图,jpeg,gif,png等,以及每个的所有附加数据那些需要创建一个有效的图像)这是没有道理的.

猜你在找的VB相关文章