Image.Save exception “A generic error occurred in GDI+.” when saving to MemoryStream

江枫思渺然 提交于 2019-12-23 17:55:44

问题


I have a server-client application, i want to get a Screen Shot from server,but on the line
bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
i get this exception : A generic error occurred in GDI+.

    private Socket ScreenSocket;
    private MemoryStream ms;
    public void ConnectScreenShot(IPEndPoint ep)
    {
        if (ScreenSocket != null)
        {
            ScreenSocket.Dispose();
            ScreenSocket = null;
        }
        if (ms != null)
        {
            ms.Dispose();
            ms = null;
        }
        ScreenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        ScreenSocket.Connect(ep);
        ms = new MemoryStream();
        Rectangle bounds = Screen.GetBounds(Point.Empty);
        using (Bitmap bitmap = new Bitmap(bounds.Width, bounds.Height))
        {
            using (Graphics g = Graphics.FromImage(bitmap))
            {
                g.CopyFromScreen(Point.Empty, Point.Empty, bitmap.Size);
            }
            bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
        }
    }

Why is that happening and how would i fix it?

Update: It works when i use ImageFormat.Jpeg Instead of ImageFormat.Png, but i still need a PNG format.


回答1:


You say:

i want to get a Screen Shot from server

And the error being GDI+ related suggests that the context under which this code is being run is perhaps a service context (such as IIS), and not a desktop. Is that correct? If so, what do you expect to return in a screenshot?

For the record, the following (minimal) code works fine:

    var ms = new MemoryStream();
    Rectangle bounds = Screen.GetBounds(Point.Empty);
    using (Bitmap bitmap = new Bitmap(bounds.Width, bounds.Height))
    {
        using (Graphics g = Graphics.FromImage(bitmap))
        {
            g.CopyFromScreen(Point.Empty, Point.Empty, bitmap.Size);
        }
        bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
    }

Both bitmap and ms contain the data expected. As such, I think you need to provide information on where and in what this code is running.




回答2:


For me I was using the Image.Save(Stream, ImageCodecInfo, EncoderParameters) and apparently this was causing the infamous A generic error occurred in GDI+ error.

I was trying to use EncoderParameter to save the jpegs in 100% quality. This was working perfectly on "my machine" (doh!) and not on production.

When I used the Image.Save(Stream, ImageFormat) instead, the error disappeared! So like an idiot I continued to use the latter although it saves them in default quality which I assume is just 50%.

Hope this info helps someone.




回答3:


I know this is an old post, but I wanted to add this information as well, in case someone like me runs across this issue in the future..

I wasn't able to save .PNG images and it because the IIS App Pool Account didn't have access to this, key.

HKEY_CLASSES_ROOT\CLSID{FAE3D380-FEA4-4623-8C75-C6B61110B681}

Which is required when you use png graphics.




回答4:


it worked with me this way :

  • When a client wants to a receive a screenshot, you need to know image size before transferring starts.
    Call GetScreenShotSize() to get the size of the image.

  • Once you get the size, call GetScreenShot() to receive image data.

i used using (MemoryStream ms = new MemoryStream()) so now PNG format is working.

    private Image img = null;
    public long GetScreenShotSize()
    {
        Rectangle bounds = Screen.GetBounds(Point.Empty);
        using (Bitmap bmp = new Bitmap(bounds.Width, bounds.Height))
        {
            using (Graphics g = Graphics.FromImage(bmp))
            {
                g.CopyFromScreen(Point.Empty, Point.Empty, bounds.Size);
            }
            using (MemoryStream ms = new MemoryStream())
            {
                bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
                img = Image.FromStream(ms);
                return ms.Length;
            }
        }
    }
    public void GetScreenShot(IPEndPoint ep)
    {
        using (Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
        {
            socket.Connect(ep);
            using (MemoryStream ms = new MemoryStream())
            {
                img.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
                socket.Send(ms.ToArray(), SocketFlags.None);
            }
            img.Dispose();
            img = null;
        }
    }



回答5:


abrirConexion();
cmd = new SqlCommand(" INSERT INTO [SICRE_BI].[Credito_CCSS].[bi_img](Descripcion,img) VALUES (@nom_img,@img)",cn);                                
cmd.Parameters.Add("@Descripcion", SqlDbType.NChar);
cmd.Parameters.Add("@img", SqlDbType.Image);

cmd.Parameters["@Descripcion"].Value = descripcion;

System.IO.MemoryStream ms = new System.IO.MemoryStream();

pbImagen.Image.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);//Aqui se me cae.Aqui se me cae.Aqui .

cmd.Parameters["@img"].Value = ms.GetBuffer();    //ms.GetBuffer();

cmd.ExecuteNonQuery();
return true;


来源:https://stackoverflow.com/questions/10576998/image-save-exception-a-generic-error-occurred-in-gdi-when-saving-to-memoryst

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!