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

両方ともbitmapms期待されるデータが含まれています。そのため、このコードが実行されている場所と内容に関する情報を提供する必要があると思います。

于 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+

私はEncoderParameterjpegを100%の品質で保存するために使用しようとしていました。これは、本番環境ではなく、「私のマシン」(doh!)で完全に機能していました。

代わりに使用するImage.Save(Stream, ImageFormat)と、エラーが消えました!だから私は馬鹿のように後者を使い続けましたが、それは私が仮定するデフォルトの品質でそれらをわずか50%節約します。

この情報が誰かに役立つことを願っています。

于 2013-02-11T06:53:58.323 に答える
0

これは古い投稿ですが、将来この問題が発生した場合に備えて、この情報も追加したいと思います。

IISアプリプールアカウントがこのキーにアクセスできなかったため、.PNG画像を保存できませんでした。

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 に答える