3

我有一个服务器-客户端应用程序,我想从服务器获取屏幕截图,但是在线上
bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
我得到了这个异常: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);
        }
    }

为什么会发生这种情况,我将如何解决?

更新:当我使用ImageFormat.Jpeg而不是时它可以工作ImageFormat.Png,但我仍然需要 PNG 格式。

4

5 回答 5

1

你说:

我想从服务器获取屏幕截图

与 GDI+ 相关的错误表明运行此代码的上下文可能是服务上下文(例如 IIS),而不是桌面。那是对的吗?如果是这样,您希望在屏幕截图中返回什么?

作为记录,以下(最小)代码可以正常工作:

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

两者都bitmap包含ms预期的数据。因此,我认为您需要提供有关此代码在何处以及以何种方式运行的信息。

于 2012-05-14T03:28:18.907 回答
0

它以这种方式与我一起工作:

  • 当客户想要接收屏幕截图时,您需要在传输开始之前知道图像大小。
    调用GetScreenShotSize()以获取图像的大小。

  • 获得尺寸后,调用GetScreenShot()以接收图像数据。

我用过using (MemoryStream ms = new MemoryStream()),所以现在 PNG 格式正在工作。

    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;
        }
    }
于 2012-05-15T19:34:10.763 回答
0

对我来说,我使用的是Image.Save(Stream, ImageCodecInfo, EncoderParameters),显然这导致了臭名昭著的A generic error occurred in GDI+错误。

我试图用EncoderParameter100% 的质量保存 jpeg。这在“我的机器”(doh!)上完美运行,而不是在生产上。

当我Image.Save(Stream, ImageFormat)改为使用时,错误消失了!所以像个白痴一样,我继续使用后者,尽管它将它们保存为默认质量,我认为它只有 50%。

希望此信息对某人有所帮助。

于 2013-02-11T06:53:58.323 回答
0

我知道这是一篇旧帖子,但我也想添加此信息,以防像我这样的人将来遇到此问题。

我无法保存 .PNG 图像,因为 IIS 应用程序池帐户无权访问此密钥。

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

当您使用 png 图形时,这是必需的。

于 2013-05-02T14:00:12.583 回答
-2
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;
于 2015-03-17T21:23:54.867 回答