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);
}
}
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
@sam Bitte geben Sie den vollständigen Code einschließlich Worker und Bild-Retreival an. – vasek
@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