保存到MemoryStream时,Image.Saveexception“GDI +中发生了一般错误。”

我有一个服务器 – 客户端应用程序,我想从服务器获得一个屏幕截图,但在线
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格式。

你说:

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

并且与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都包含预期的数据。 因此,我认为您需要提供有关此代码运行的位置和内容的信息。

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

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

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

希望这些信息有助于某人。

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

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

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

使用png图形时需要哪个。

它以这种方式与我合作:

  • 当客户想要接收屏幕截图时,您需要在传输开始之前知道图像大小。
    调用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; } } 
 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;