2017-07-20 1 views
-1

Das Bild ist tatsächlich ein Byte-Array aus meiner nativen DLL gepumpt (als Byte *).Generischer Fehler in GDI + Calling Image.Save

Ich konvertiere es in ein Bild wie folgt.

Img = new Bitmap(g_Width, g_Height, g_Width * 3, PixelFormat.Format24bppRgb, ptr); 

Hinweis: Das "Bild" befindet sich im globalen Gültigkeitsbereich. "ptr" ist ein IntPtr (lokaler Bereich).

Ich versuche, dieses Bild von der BackgroundWorker-Methode zu speichern. Wenn ich dies tue, erhalte ich die Ausnahme "Ein generischer Fehler ist in GDI + aufgetreten".

Was fehlt mir?

Edit:

Ich versuche, das Bild wie

Img.Save("test.bmp", ImageFormat.Bmp); 

Auch zu sparen, habe ich versucht, das Bild zu speichern, sobald ich das Bild zu erstellen. Die Datei wurde erfolgreich gespeichert. Ich kann auch anzeigen. Aber ich kann nicht vom Arbeiter sparen.

Edit 2: Globals:

BackgroundWorker Worker; 
Image img = null; 

Der Rückruf wird wie folgt

private unsafe void GrabFrame(Byte* InputBuff, ref Int32 lBufferLen) 
{ 
    Img = new Bitmap(g_Width, g_Height, g_Width * 3, 
     PixelFormat.Format24bppRgb, (IntPtr)InputBuff); 


    //Img.Save("test.bmp", ImageFormat.Bmp); // This works fine. 

    Worker = new BackgroundWorker(); 
    Worker.DoWork += new DoWorkEventHandler(Worker_DoWork);        
    Worker.RunWorkerAsync(); 
} 

void Worker_DoWork(object sender, DoWorkEventArgs e) 
{ 
    try 
    { 
     Img.Save("test.bmp", ImageFormat.Bmp); //This is were i get the exception 
    } 
    catch (Exception ex) 
    { 
     Trace.WriteLine("Exception at Worker_DoWork: " + ex.Message); 
    } 
} 

Modified Code:

Globals:

BackgroundWorker Worker; 
Image img = null; 
Byte[] g_Buffer; 
Intptr ptr; 

Der Rückruf wird wie folgt

private unsafe void GrabFrame(Byte* InputBuff, ref Int32 lBufferLen) 
{ 
    Img = new Bitmap(g_Width, g_Height, g_Width * 3, 
     PixelFormat.Format24bppRgb, (IntPtr)InputBuff); 


    g_Buffer = new byte[lBufferLen]; 
    Marshal.Copy((IntPtr)InputBuff, g_Buffer, 0, lBufferLen); 

    //Img.Save("test.bmp", ImageFormat.Bmp); // This works fine. 

    Worker = new BackgroundWorker(); 
    Worker.DoWork += new DoWorkEventHandler(Worker_DoWork);        
    Worker.RunWorkerAsync(); 
} 

void Worker_DoWork(object sender, DoWorkEventArgs e) 
{ 
    try 
    { 
     ptr = Marshal.AllocHGlobal(g_Buffer.Length); 
     Marshal.Copy(g_Buffer, 0, ptr, g_Buffer.Length); 

     Img = new Bitmap(g_Width, g_Height, g_Width * 3, PixelFormat.Format24bppRgb, ptr); 

     Img.Save("test.bmp", ImageFormat.Bmp); //still issue persists 

     // Call unmanaged code 
     Marshal.FreeHGlobal(ptr); 
    } 
    catch (Exception ex) 
    { 
     Trace.WriteLine("Exception at Worker_DoWork: " + ex.Message); 
    } 
} 

bearbeiten 4: Arbeits-Code

finden Sie den geänderten Code,

In Rückruf

Byte[] Buffer = new Byte[lBufferLen]; 
Marshal.Copy((IntPtr)InputBuff, Buffer, 0, lBufferLen); 

Worker = new BackgroundWorker(); 
Worker.DoWork += (obj, e) => Worker_DoWork(obj, e, Buffer); 
Worker.RunWorkerAsync(); 

. Und der Arbeiter,

void Worker_DoWork(object sender, DoWorkEventArgs e, Byte[] Buffer) 
{ 
    try 
    { 
     Image Img = null; 
     IntPtr ptr = Marshal.AllocHGlobal(Buffer.Length); 

     Marshal.Copy(Buffer, 0, ptr, Buffer.Length); 

     if (ptr != IntPtr.Zero) 
     { 
      Img = new Bitmap(g_Width, g_Height, g_Width * 3, PixelFormat.Format24bppRgb, ptr); 
     } 

     Img.Save("test.bmp", ImageFormat.Bmp); 

     Marshal.FreeHGlobal(ptr); 
    } 
    catch (Exception ex) 
    { 
     Trace.WriteLine("Exception at Worker_DoWork: " + ex.Message); 
    } 
} 
+2

Es fehlt der Befehl zum Speichern, einschließlich des Pfads. Außerdem: Funktioniert das Bild, dh können Sie es zB in einer PictureBox anzeigen? – TaW

+0

@sam Bitte geben Sie den vollständigen Code einschließlich Worker und Bild-Retreival an. – vasek

+1

@sam 'GrabFrame' ist ein Rückruf aus einer nicht verwalteten Umgebung? Wenn dies der Fall ist, ist es offensichtlich, dass Ihr asynchroner Mitarbeiter Daten nicht speichern kann, da sie wahrscheinlich bereits veröffentlicht wurden. Sie müssen Daten in 'GrabFrame' in z. verwaltete 'byte []' und dann speichern Sie es in Worker. – vasek

Antwort

-1

Vielen Dank @Vasek. Wie im Kommentar vorgeschlagen, musste ich einen lokalen Puffer erstellen und an den Arbeiter übergeben.

Sie finden den Arbeitscode in der bearbeiteten Frage.

Verwandte Themen