2012-05-14 45 views
3

时,我有一个服务器 - 客户端应用程序,我想从服务器获取一个屏幕截图,但上线
bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
我得到这个异常:A generic error occurred in GDI+.Image.Save异常“GDI +中发生了一般性错误”。保存到的MemoryStream

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格式。

+0

不确定这是否有帮助。但是,你能不能在你的'CopyFromScreen'后面传回Graphics对象?或者你的方法必须是无效的?或者实际上也许只是你的Bitmap对象。 – meanbunny

+0

@meanbunny我不知道如果我有你的观点,但CopyFromScreen不是我的方法,它的Graphics.CopyFromScreen方法! –

+0

正确的我想我的观点是你打算如何将你的位图传回给你的客户,如果这是你的意图。无论这里是一个可以帮助你的帖子。 http://forums.asp.net/t/1766006.aspx/1 – meanbunny

回答

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

两个bitmapms包含预期的数据。因此,我认为您需要提供有关此代码在何处以及在何处运行的信息。

+0

这是一个WCF服务,我可以得到一个ScreenShot并发送它,如果我将该行更改为'bitmap.Save(ms,System.Drawing.Imaging.ImageFormat.Jpeg);'但是当ImageFormat是Png我得到该错误。 –

+0

尝试移动“使用”块中的所有内容。似乎有关于过早关闭流的问题。最终,这取决于你想用'ms'做什么。这种孤立的代码总是很困难。 – yamen

0

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

我试图使用EncoderParameter以100%的质量保存jpegs。这是完美的“我的机器”(doh!),而不是生产。

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

希望此信息有助于某人。

0

我知道这是旧的文章,但我想添加此信息为好,万一有人像我碰到这个问题在未来的运行..

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

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

当您使用PNG图形这是必需的。

-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; 
+1

你能翻译你的评论和函数名吗? –

+1

虽然这个答案可能是正确和有用的,但是如果你包含一些解释并解释它如何帮助解决这个问题,那么这是首选。如果存在导致其停止工作并且用户需要了解其曾经工作的变化(可能不相关),这在未来变得特别有用。 –

+0

@PaulTomkiel'// Aqui se me cae.Aqui se me cae.Aqui''意思是'//这里失败了,它失败了。这里有' –

相关问题