GDI +调用Image.Save时发生了一般错误

时间:2017-07-20 05:42:43

标签: c# winforms callback marshalling

图像实际上是从我的本机DLL(作为Byte *)泵出的字节数组。

我将其转换为如下图像。

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

注意:“图像”位于全局范围内。 “ptr”是一个IntPtr(本地范围)。

我正在尝试从BackgroundWorker方法保存此图像。当我这样做时,我得到“GDI +中发生了一般错误”的异常。

我错过了什么?

修改

我正在尝试将图像保存为

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

另外,我在创建图像后尝试保存图像。该文件已成功保存。我也可以显示。但我无法从工人那里拯救。

编辑2: 全局:

BackgroundWorker Worker;
Image img = null; 

回调如下,

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

修改后的代码:

全局:

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

回调如下,

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

编辑4:工作代码

请找到修改后的代码。

在回电中,

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

和工人一起,

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

1 个答案:

答案 0 :(得分:-1)

谢谢@Vasek。正如评论中所建议的那样,我必须创建一个本地缓冲区并将其传递给worker。

请在编辑的问题中找到工作代码。