2012-04-02 6 views
4

ich eine Menge von Fragen und Antworten lesen, die meisten vorschlagen:Zeigen Sie ein Byte-Array in einer PictureBox in C#

byte[] byteArray; //(contains image data) 
MemoryStream stream = new MemoryStream(byteArray); 
Bitmap image = new Bitmap(stream); 
pictureBox.Image = image; 

oder mehr direkt:

pictureBox.Image = Image.FromStream(stream); 

ich immer: "Eine nicht behandelte Ausnahme vom Typ 'System.ArgumentException' in System.Drawing.dll aufgetreten

Zusätzliche Informationen: Parameter ist nicht gültig. "

in Bezug auf den Stream-Parameter.

Selbst in dem Fall, dass:

byte[] byteArray = new byte[1]; 
byteArray[0] = 255; 

ich kann nicht herausfinden, warum.

EDIT:

ich die Daten aus einer Datei wie folgt erhalten:

//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); 

Im Debugger, ich sehe also, dass der byteArray in Ordnung ist, count = 2244, überall Werte usw.

EDIT # 2: Beispieldatendatei (erstes Byte [0] ist in der Höhe, zweiter Byte [1] Breite ist, ist Rest RGB-Daten)

47 15 12 55 25 52 55 25 52 55 25 52 55 25 52 55 
25 52 55 25 52 55 25 52 55 25 52 55 25 52 55 25 
52 55 25 52 55 25 52 55 25 52 55 25 52 55 25 52 
55 25 52 55 25 52 55 25 52 55 25 52 55 25 52 55 
25 52 51 24 82 49 24 82 49 24 92 50 25 12 50 24 
92 48 24 92 50 24 82 50 25 02 50 24 92 50 25 02 
51 25 12 50 24 92 49 25 02 50 25 02 49 25 12 49 
25 02 49 25 02 47 25 12 47 25 22 50 24 82 47 24 
82 50 24 72 50 24 82 49 24 82 50 24 72 50 24 82 
50 24 72 49 24 82 49 25 22 52 24 92 50 24 82 50 
24 72 47 25 00 etc. 

EDIT # 3: LÖSUNG

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; 

Need 4 Byte-Ausrichtung zu überprüfen, so Ladefunktion ist jetzt:

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 ; 
+0

Welches Format hat das Bild im Bytearray? und das letzte Beispiel wird nie funktionieren ... kann nicht an ein Ein-Byte-Bild denken :) – scartag

+0

Die Daten von Byte [] sind dann nicht wohlgeformt. – leppie

+0

Das letzte Beispiel ist nur zu sagen, dass der Stream nicht funktioniert, auch wenn ich weiß, dass die Daten gut geformt sind, wie leppie es setzte, ich werde bearbeiten und ein Beispiel für die Daten schreiben, die ich habe – Smash

Antwort

2

Jedes Bild braucht eine Beschreibung dessen, was der Inhalt des Byte-Array ist. Diese Beschreibung wird Header genannt. Wenn Sie nun die Bytes austauschen möchten, müssen Sie den Header nicht ändern.

http://en.wikipedia.org/wiki/BMP_file_format

, dass eine Probe meiner Sourcecode ist, während sie mit einer solchen ByteArray Arbeits

''' <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 
1

Nach Ihrem ursprünglichen Vorschlag an der Spitze Ihrer Post, ich hatte kein Problem mit diesem Arbeits .

Nun, ob das sicher/korrekt ist weiß ich nicht, aber es scheint zu funktionieren.

+0

ja, das ist so ziemlich das was ich machen will, außer dass meine Daten stammen eine Textdatei und der Stream funktioniert nicht ... – Smash

+0

Vielleicht gibt ReadToEnd nicht zurück, was Sie denken, dass es zurückgibt? Haben Sie versucht, es in einen Puffer einzulesen? – Jesse

Verwandte Themen