C# 在C语言的pictureBox中显示字节数组#

C# 在C语言的pictureBox中显示字节数组#,c#,bitmap,picturebox,C#,Bitmap,Picturebox,我读了很多问题和答案,大多数人建议: byte[] byteArray; //(contains image data) MemoryStream stream = new MemoryStream(byteArray); Bitmap image = new Bitmap(stream); pictureBox.Image = image; 或者更直接地说: pictureBox.Image = Image.FromStream(stream); 我总是得到:“System.Drawing

我读了很多问题和答案,大多数人建议:

byte[] byteArray; //(contains image data)
MemoryStream stream = new MemoryStream(byteArray);
Bitmap image = new Bitmap(stream);
pictureBox.Image = image;
或者更直接地说:

pictureBox.Image = Image.FromStream(stream);
我总是得到:“System.Drawing.dll中发生了类型为'System.ArgumentException'的未处理异常

其他信息:参数无效。“

关于stream参数

即使在以下情况下:

byte[] byteArray = new byte[1];
byteArray[0] = 255;
我不明白为什么

编辑:

我从如下文件中获取数据:

//byteArray is defined as List<byte> byteArray = new List<byte>();
TextReader tr = new StreamReader(file);
string File = tr.ReadToEnd();
string[] bits = File.Split('\t');
List<string> image = new List<string>(bits);
height = int.Parse(bits[0]);
width  = int.Parse(bits[1]);
image.RemoveRange(0, 2);
image.RemoveAt(image.Count - 1);
foreach (string s in image)
{
  byteArray.Add(byte.Parse(s));
}
return byteArray //(i do .ToArray() in the MemoryStream call);
编辑#3:解决方案

Bitmap bmp = new Bitmap(width, height, PixelFormat.Format24bppRgb);
BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);
IntPtr ptr = bmpData.Scan0;
Marshal.Copy(byteArray, 0, ptr, height * width * 3);
bmp.UnlockBits(bmpData);
pictureBox.Image = bmp;
需要检查4字节对齐,因此加载函数现在为:

TextReader tr = new StreamReader(file);
string File = tr.ReadToEnd();
string[] bits = File.Split('\t');
List<string> image = new List<string>(bits);
height = int.Parse(bits[0]);
width  = int.Parse(bits[1]);
int falseBits = 0;
int oldWidth = width;
while (width % 4 != 0)
{
    width++;
    falseBits++;
}
int size = height * width * 3;
byte[] byteArray = new byte[size];
Parallel.For(0, size - 1, i => byteArray[i] = 255);
int index  = 0;
int lineIndex = 0;
image.RemoveRange(0, 2);
image.RemoveAt(image.Count - 1);
foreach (string s in image)
{
    byteArray [index]   = byte.Parse(s);
    byteArray [index + 1] = byteArray [index];
    byteArray [index + 2] = byteArray [index];
    index +=3;
    lineIndex++;
    if (lineIndex == oldWidth)
    {
        lineIndex = 0;
        index += 3*falseBits;
    }
}
return byteArray ;
TextReader tr=新的StreamReader(文件);
string File=tr.ReadToEnd();
字符串[]位=File.Split('\t');
列表图像=新列表(位);
高度=int.Parse(位[0]);
宽度=int.Parse(位[1]);
int-falseBits=0;
int oldWidth=宽度;
而(宽度%4!=0)
{
宽度++;
伪比特++;
}
整数大小=高度*宽度*3;
byte[]byteArray=新字节[大小];
对于(0,size-1,i=>byteArray[i]=255);
int指数=0;
int-lineIndex=0;
图像去除范围(0,2);
image.RemoveAt(image.Count-1);
foreach(图像中的字符串s)
{
byteArray[index]=字节.解析;
byteArray[索引+1]=byteArray[索引];
byteArray[索引+2]=byteArray[索引];
指数+=3;
lineIndex++;
如果(lineIndex==oldWidth)
{
lineIndex=0;
索引+=3*假位;
}
}
乘火车返回;

每个图像都需要描述字节数组的内容。此描述称为标题。如果现在要交换字节,则需要避免更改标头

这是我在使用这种ByteArray时的源代码示例

''' <summary>
''' Copies an Bytearray into an image and return it.
''' </summary>
''' <param name="ArrSrc">Source byte array of image which can be anything</param>
''' <param name="ImageSize">the image size of the image</param>
''' <param name="SourceArrayPixelFormat">Pixel format, like 24Bit or 32Bit</param>
''' <returns>System.Drawing.Image</returns>
''' <remarks>copyright, http://software.goldengel.ch, 2012</remarks>
Public Function ArrayToBitmapData(ByVal ArrSrc() As Byte, ByVal ImageSize As System.Drawing.Size, ByVal SourceArrayPixelFormat As System.Drawing.Imaging.PixelFormat) As System.Drawing.Bitmap
    'Kopiert ein ByteArray in ein Bitmap

    Dim m As Integer
    Dim bmTemp As System.Drawing.Bitmap = Nothing
    Dim S As System.Drawing.Size
    Dim MemorySize As Integer
    Dim ScanLine As Integer

    'Bild prüfen
    If ArrSrc Is Nothing Then Return bmTemp

    'Bildgrösse definieren
    'Bei unterschiedlichen Grössen, wird muss die kleinere Grösse verwendet werden
    S = ImageSize


    'Helfer für die Bildverarbeitung erzeugen
    Dim bts As System.Drawing.Imaging.BitmapData

    'Bitmap erzeugen um damit zu arbeiten
    bmTemp = New System.Drawing.Bitmap(S.Width, S.Height, SourceArrayPixelFormat)

    'Farbtiefe berechnen
    '24Bit und 32Bit Bilder werden unterstützt
    'Kann beliebig erweitert werden
    m = BytesInPixelFormat(SourceArrayPixelFormat)



    '*** Hauptroutine - Array --> Bitmap ***

    'Bilddaten in die Picturebox laden
    bts = bmTemp.LockBits(New System.Drawing.Rectangle(0, 0, S.Width, _
        S.Height), System.Drawing.Imaging.ImageLockMode.WriteOnly, SourceArrayPixelFormat)


    'Speicherplatz reservieren
    'MemorySize = S.Height * S.Width * m
    'Nur zur Kontrolle
    ScanLine = GetScanline(S, SourceArrayPixelFormat)

    MemorySize = S.Height * bts.Stride
    If ArrSrc.Length >= MemorySize Then
        'Bilddaten aus dem Array laden
        Global.System.Runtime.InteropServices.Marshal.Copy(ArrSrc, 0, bts.Scan0, MemorySize)
    End If
    bmTemp.UnlockBits(bts)

    'Erzeugtes Bitmap zurückgeben
    Return bmTemp

End Function



convert Bitmap image into byte array

'Neue Funktion 27.2.2008
'Mit korrekter Dimensionierung mittels bts.Stride und Umrechnung auf das Pixelformat
''' <summary>
''' Get an Array of the data of any image. 
''' Bitmap header execluded.
''' </summary>
''' <param name="bmSrc">Source image</param>
''' <param name="NeededDestinationPixelFormat">Pixelformat, like 24Bit or 32Bit</param>
''' <returns>Image content</returns>
''' <remarks>copyright http://software.goldengel.ch, 2012</remarks>
Public Function BitmapDataToArray(ByVal bmSrc As System.Drawing.Bitmap, ByVal NeededDestinationPixelFormat As System.Drawing.Imaging.PixelFormat, ByRef DstStride As Integer) As Byte()
    'Kopiert ein Bild in ein Bytearray

    Dim m As Integer
    Dim A() As Byte = Nothing
    Dim S As System.Drawing.Size
    Dim MemorySize As Integer
    Dim bmTemp As System.Drawing.Bitmap = Nothing

    'Bild prüfen
    If bmSrc Is Nothing Then Return A

    'Bildgrösse definieren
    'Bei unterschiedlichen Grössen, wird muss die kleinere Grösse verwendet werden
    S = bmSrc.Size


    'Helfer für die Bildverarbeitung erzeugen
    Dim bts As System.Drawing.Imaging.BitmapData

    'Farbtiefe berechnen
    '24Bit und 32Bit Bilder werden unterstützt
    'Kann beliebig erweitert werden
    m = BytesInPixelFormat(NeededDestinationPixelFormat)


    '*** Hauptroutine - Bitmap --> Array ***
    'Bilddaten aus der Picturebox laden
    If NeededDestinationPixelFormat <> bmSrc.PixelFormat Then
        'Bitmap erzeugen um damit zu arbeiten
        bmTemp = New System.Drawing.Bitmap(S.Width, S.Height, NeededDestinationPixelFormat)

        Using gr As System.Drawing.Graphics = System.Drawing.Graphics.FromImage(bmTemp)
            gr.DrawImage(bmSrc, 0, 0)
        End Using
        'ImgSrc.Dispose()'Achtung, würde das Original mit zerstören
        bmSrc = bmTemp
    End If

    bts = bmSrc.LockBits(New System.Drawing.Rectangle(0, 0, S.Width, _
        S.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, NeededDestinationPixelFormat)

    'Speicherplatz reservieren
    MemorySize = S.Height * bts.Stride
    ReDim A(MemorySize - 1) '28.2.2010. wichtige Änderung. 1 Byte zuviel wurde reserviert. Das konnte bei Wiederholung von Graphics.Drawing zu einem Fehler kommen

    'Bitmapdaten in das Array kopieren
    Global.System.Runtime.InteropServices.Marshal.Copy(bts.Scan0, A, 0, A.Length)
    bmSrc.UnlockBits(bts)

    DstStride = bts.Stride

    If bmTemp IsNot Nothing Then bmTemp = Nothing

    Return A

End Function
“”
''将字节数组复制到图像中并返回它。
''' 
''图像的源字节数组,可以是任何内容
''图像的图像大小
''像素格式,如24位或32位
''系统、绘图、图像
“版权,http://software.goldengel.ch, 2012
公共函数ArrayToBitmapData(ByVal ArrSrc()作为字节,ByVal ImageSize作为System.Drawing.Size,ByVal SourceArrayPixelFormat作为System.Drawing.Imaging.PixelFormat)作为System.Drawing.Bitmap
“ein位图中的Kopiert ein ByteArray
将m作为整数
Dim bmTemp As System.Drawing.Bitmap=无
尺寸S为系统图纸尺寸
Dim MemorySize为整数
将扫描线设置为整数
《图片报》
如果ArrSrc为空,则返回bmTemp
“Bildgrösse definieren
“我的孩子们,我的孩子们,我的孩子们,我的孩子们,我的孩子们,我的孩子们,我的孩子们,我的孩子们,我的孩子们,我的孩子们,我的孩子们,我的孩子们,我的孩子们。”
S=图像大小
“我的朋友们都很高兴
Dim bts作为System.Drawing.Imaging.BitmapData
“这是我的梦想
bmTemp=新的System.Drawing.Bitmap(S.Width、S.Height、SourceArrayPixelFormat)
“法布蒂夫·贝雷克宁
'24位和32位的比尔德·沃登(werden unterstützt)'
“卡恩·贝利比格·埃尔维特·沃登
m=字节输入像素格式(SourceArrayPixelFormat)
'***HauptRoute-数组-->位图***
“装满图片的盒子里的毕尔达腾
bts=bmTemp锁位(新系统图纸矩形(0,0,S.宽度_
S.Height),System.Drawing.Imaging.ImageLockMode.WriteOnly,SourceArrayPixelFormat)
斯派克普拉茨水库
'MemorySize=S.高度*S.宽度*m
“努尔·祖尔·康特罗尔
扫描线=GetScanline(S,SourceArrayPixelFormat)
记忆大小=S.高度*bts.步幅
如果ArrSrc.Length>=MemorySize,则
“Bildadaen aus dem阵列满载
Global.System.Runtime.InteropServices.Marshal.Copy(ArrSrc,0,bts.Scan0,MemorySize)
如果结束
bmTemp.解锁位(bts)
“Erzeugtes zurückgeben
返回bmTemp
端函数
将位图图像转换为字节数组
‘新基金会’27.2.2008
“Mit korrekter Dimensionierung mittels bts.Stride and Umrechnung auf das Pixel格式
''' 
''获取任何图像的数据数组。
''位图标头已被删除。
''' 
''源图像
''像素格式,如24位或32位
''图像内容
“版权”http://software.goldengel.ch, 2012
公共函数BitmapDataToArray(ByVal bmSrc作为System.Drawing.Bitmap,ByVal NeededDestinationPixelFormat作为System.Drawing.Imaging.PixelFormat,ByRef DstStrand作为整数)作为字节()
“Kopiert ein Bild在ein Bytearray
将m作为整数
将A()变暗为Byte=Nothing
尺寸S为系统图纸尺寸
Dim MemorySize为整数
Dim bmTemp As System.Drawing.Bitmap=无
《图片报》
如果bmSrc为Nothing,则返回一个
“Bildgrösse definieren
“我的孩子们,我的孩子们,我的孩子们,我的孩子们,我的孩子们,我的孩子们,我的孩子们,我的孩子们,我的孩子们,我的孩子们,我的孩子们,我的孩子们,我的孩子们。”
S=bmSrc.尺寸
“我的朋友们都很高兴
Dim bts作为System.Drawing.Imaging.BitmapData
“法布蒂夫·贝雷克宁
'24位和32位的比尔德·沃登(werden unterstützt)'
“卡恩·贝利比格·埃尔维特·沃登
m=字节输入像素格式(需要估计像素格式)
'***HauptRoute-位图-->数组***
“装满图片盒的比尔达滕”
如果需要DestinationPixelFormat bmSrc.PixelFormat,则
“这是我的梦想
bmTemp=新系统.绘图.位图(S.Width,S.Height,NeededDestinationPixelFormat)
将gr用作System.Drawing.Graphics=System.Drawing.Graphics.FromImage(bmTemp)
gr.DrawImage(bmSrc,0,0)
终端使用
'ImgSrc.Dispose()'Achtung,würde das原始mit zerstören
bmSrc=bmTemp
如果结束
bts=bmSrc.LockBits(新系统图纸矩形(0,0,S.宽度_
S.Height)、System.Drawing.Imaging.ImageLockMode.ReadOnly、NeededDestinationPixelFormat)
斯派克普拉茨水库
记忆大小=S.高度*bts.步幅
ReDim A(MemorySize-1)于2010年2月28日发布。威奇提格·安德隆。1字节zuviel wurde reserviert。这是一个图形绘制工具
'das数组中的Bitmapdaten kopieren
Global.System.Runtime.InteropServices.Marshal.Copy(bts.Scan0,A,0,A.Length)
bmSrc.解锁位(bts)
DstStride=bts.Stride
如果bmTemp不是空,那么bmTemp=空
归还
端函数
遵循您的
''' <summary>
''' Copies an Bytearray into an image and return it.
''' </summary>
''' <param name="ArrSrc">Source byte array of image which can be anything</param>
''' <param name="ImageSize">the image size of the image</param>
''' <param name="SourceArrayPixelFormat">Pixel format, like 24Bit or 32Bit</param>
''' <returns>System.Drawing.Image</returns>
''' <remarks>copyright, http://software.goldengel.ch, 2012</remarks>
Public Function ArrayToBitmapData(ByVal ArrSrc() As Byte, ByVal ImageSize As System.Drawing.Size, ByVal SourceArrayPixelFormat As System.Drawing.Imaging.PixelFormat) As System.Drawing.Bitmap
    'Kopiert ein ByteArray in ein Bitmap

    Dim m As Integer
    Dim bmTemp As System.Drawing.Bitmap = Nothing
    Dim S As System.Drawing.Size
    Dim MemorySize As Integer
    Dim ScanLine As Integer

    'Bild prüfen
    If ArrSrc Is Nothing Then Return bmTemp

    'Bildgrösse definieren
    'Bei unterschiedlichen Grössen, wird muss die kleinere Grösse verwendet werden
    S = ImageSize


    'Helfer für die Bildverarbeitung erzeugen
    Dim bts As System.Drawing.Imaging.BitmapData

    'Bitmap erzeugen um damit zu arbeiten
    bmTemp = New System.Drawing.Bitmap(S.Width, S.Height, SourceArrayPixelFormat)

    'Farbtiefe berechnen
    '24Bit und 32Bit Bilder werden unterstützt
    'Kann beliebig erweitert werden
    m = BytesInPixelFormat(SourceArrayPixelFormat)



    '*** Hauptroutine - Array --> Bitmap ***

    'Bilddaten in die Picturebox laden
    bts = bmTemp.LockBits(New System.Drawing.Rectangle(0, 0, S.Width, _
        S.Height), System.Drawing.Imaging.ImageLockMode.WriteOnly, SourceArrayPixelFormat)


    'Speicherplatz reservieren
    'MemorySize = S.Height * S.Width * m
    'Nur zur Kontrolle
    ScanLine = GetScanline(S, SourceArrayPixelFormat)

    MemorySize = S.Height * bts.Stride
    If ArrSrc.Length >= MemorySize Then
        'Bilddaten aus dem Array laden
        Global.System.Runtime.InteropServices.Marshal.Copy(ArrSrc, 0, bts.Scan0, MemorySize)
    End If
    bmTemp.UnlockBits(bts)

    'Erzeugtes Bitmap zurückgeben
    Return bmTemp

End Function



convert Bitmap image into byte array

'Neue Funktion 27.2.2008
'Mit korrekter Dimensionierung mittels bts.Stride und Umrechnung auf das Pixelformat
''' <summary>
''' Get an Array of the data of any image. 
''' Bitmap header execluded.
''' </summary>
''' <param name="bmSrc">Source image</param>
''' <param name="NeededDestinationPixelFormat">Pixelformat, like 24Bit or 32Bit</param>
''' <returns>Image content</returns>
''' <remarks>copyright http://software.goldengel.ch, 2012</remarks>
Public Function BitmapDataToArray(ByVal bmSrc As System.Drawing.Bitmap, ByVal NeededDestinationPixelFormat As System.Drawing.Imaging.PixelFormat, ByRef DstStride As Integer) As Byte()
    'Kopiert ein Bild in ein Bytearray

    Dim m As Integer
    Dim A() As Byte = Nothing
    Dim S As System.Drawing.Size
    Dim MemorySize As Integer
    Dim bmTemp As System.Drawing.Bitmap = Nothing

    'Bild prüfen
    If bmSrc Is Nothing Then Return A

    'Bildgrösse definieren
    'Bei unterschiedlichen Grössen, wird muss die kleinere Grösse verwendet werden
    S = bmSrc.Size


    'Helfer für die Bildverarbeitung erzeugen
    Dim bts As System.Drawing.Imaging.BitmapData

    'Farbtiefe berechnen
    '24Bit und 32Bit Bilder werden unterstützt
    'Kann beliebig erweitert werden
    m = BytesInPixelFormat(NeededDestinationPixelFormat)


    '*** Hauptroutine - Bitmap --> Array ***
    'Bilddaten aus der Picturebox laden
    If NeededDestinationPixelFormat <> bmSrc.PixelFormat Then
        'Bitmap erzeugen um damit zu arbeiten
        bmTemp = New System.Drawing.Bitmap(S.Width, S.Height, NeededDestinationPixelFormat)

        Using gr As System.Drawing.Graphics = System.Drawing.Graphics.FromImage(bmTemp)
            gr.DrawImage(bmSrc, 0, 0)
        End Using
        'ImgSrc.Dispose()'Achtung, würde das Original mit zerstören
        bmSrc = bmTemp
    End If

    bts = bmSrc.LockBits(New System.Drawing.Rectangle(0, 0, S.Width, _
        S.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, NeededDestinationPixelFormat)

    'Speicherplatz reservieren
    MemorySize = S.Height * bts.Stride
    ReDim A(MemorySize - 1) '28.2.2010. wichtige Änderung. 1 Byte zuviel wurde reserviert. Das konnte bei Wiederholung von Graphics.Drawing zu einem Fehler kommen

    'Bitmapdaten in das Array kopieren
    Global.System.Runtime.InteropServices.Marshal.Copy(bts.Scan0, A, 0, A.Length)
    bmSrc.UnlockBits(bts)

    DstStride = bts.Stride

    If bmTemp IsNot Nothing Then bmTemp = Nothing

    Return A

End Function
pictureBox.Image = GetImage();

public Image GetImage()
{
    Image image;
    using (FileStream fs = File.OpenRead(@"C:\picture.jpg"))
    {
        long length = fs.Length;

        byte[] bytes = new byte[length];

        for (int pos = 0; pos < length; )
            pos += fs.Read(bytes, pos, (int)length - pos);

        fs.Position = 0;

        using (MemoryStream ms = new MemoryStream(bytes))
            image = Image.FromStream(ms);
    }

    return image;
}