2012-04-02 2 views
4

C#에서의 PictureBox에서 바이트 배열을 표시, 대부분의 제안내가 질문과 답변을 많이 읽어

pictureBox.Image = Image.FromStream(stream); 

난 항상 얻을 : "처리되지 않은 예외 형식의 'System.ArgumentException'System.Drawing.dll에서 발생했습니다.

추가 정보 : 매개 변수가 유효하지 않습니다. "

에 대해서는 스트림 매개 변수와 관련됩니다. 심지어 경우에

:

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

디버거에서, 내가 즉 BYTEARRAY 괜찮 볼 등 어디서나 = 2244

를 값을 계산

EDIT # 2 : 샘플 데이터 파일

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. 
,536,913 (제 1 바이트 [0] 높이 번째 바이트 [1], 나머지는 RGB 데이터 폭이다) 63,210

수정 # 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 ; 
+0

bytearray의 이미지 형식은 무엇입니까? 그리고 마지막 예제는 절대로 작동하지 않을 것이다. 1 바이트 이미지를 생각할 수 없다. :) – scartag

+0

바이트 [] 데이터가 잘 형성되지 않았다. – leppie

+0

마지막 예제는 데이터가 잘 형성되어 있다는 것을 알았을 때도 스트림이 작동하지 않는다고 말하는 것입니다. 내가 가지고있는 데이터의 예를 편집하고 쓰겠습니다 – Smash

답변

2

모든 이미지는 내용이 바이트 배열이 무엇인지에 대한 설명이 필요합니다. 이 설명을 헤더라고합니다. 이제 바이트를 교환하려면 헤더를 변경하지 않아야합니다. 게시물 상단에 원래의 제안에 따라 같은이 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 
1

와 함께 작업하는 동안 내 소스 코드의 샘플입니다

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

,이 작업에 문제가 없었어요 .

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; 
} 

자, 이것이 안전하고 정확한지 여부는 알 수 없지만 작동하는 것 같습니다.

+0

예, 내 데이터가 출처가 아니라는 점을 제외하고는하고 싶습니다. 텍스트 파일과 스트림이 작동하지 않습니다 ... – Smash

+0

아마도 ReadToEnd가 반환하는 것으로 생각하는 것을 반환하지 않을 수 있습니까? 그것을 버퍼에서 읽으려고 했습니까? – Jesse

관련 문제