通过套接字流 C# 在 PictureBox 上获取 messy/croped

Getting messy/croped on PictureBox by Socket Streaming C#

我正在尝试使用套接字从另一台设备获取 printScreen。

我的发送设备(windowsce 6.0)代码是

using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Data;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;

namespace ServerComputer
{
    class Program
    {
        static Socket sendsocket;

        enum RasterOperation : uint { SRC_COPY = 0x00CC0020 }

        [DllImport("coredll.dll")]
        static extern int BitBlt(IntPtr hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hdcSrc, int nXSrc, int nYSrc, RasterOperation rasterOperation);

        [DllImport("coredll.dll")]
        private static extern IntPtr GetDC(IntPtr hwnd);

        [DllImport("coredll.dll")]
        private static extern int ReleaseDC(IntPtr hwnd, IntPtr hdc);

        public static void Main(string[] args)
        {
            Console.Out.WriteLine("Gildo Lindo Fon");
            try
            {
                sendsocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                //The instantiation of socket, IP for 192.168.1.106, 10001 for Port 
                IPEndPoint ipendpiont = new IPEndPoint(IPAddress.Parse("192.168.0.24"), 81);
                sendsocket.Connect(ipendpiont);
                //Establishment of end point
                Console.Out.WriteLine("starting thread");
                Thread th = new Thread(sendImageThread);
                //th.IsBackground = true;
                th.Start();
            }
            catch (Exception ee)
            {
                Console.Out.WriteLine(ee.Message);
                return;
            }
        }
        private static Bitmap GetScreen()
        {
            Rectangle bounds = Screen.PrimaryScreen.Bounds;
            IntPtr hdc = GetDC(IntPtr.Zero);
            Bitmap bitmap = new Bitmap(bounds.Width, bounds.Height, PixelFormat.Format16bppRgb565);
            using (Graphics graphics = Graphics.FromImage(bitmap))
            {
                IntPtr dstHdc = graphics.GetHdc();
                BitBlt(dstHdc, 0, 0, bounds.Width, bounds.Height, hdc, 0, 0,RasterOperation.SRC_COPY);
                graphics.ReleaseHdc(dstHdc);
            }

            ReleaseDC(IntPtr.Zero, hdc);

            return bitmap;
        }

        private static void sendImageThread()
        {
            Console.Out.WriteLine("SENDING");
            while (true)
            {
                try
                {
                    MemoryStream ms = new MemoryStream();
                    Bitmap bitmapScreen = GetScreen();
                    bitmapScreen.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);   //Here I use the BMP format
                    bitmapScreen.Save(".\printimg.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
                    byte[] b = ms.ToArray();
                    sendsocket.Send(b);
                    ms.Close();
                }
                catch (Exception ee)
                {
                    Console.Out.WriteLine(ee.Message);
                    break;
                }
                Thread.Sleep(1000);
            }
        }
    }
}

我的收件人代码是这样的:

using System.Net;
using System.Net.Sockets;


namespace httpScreenClient;

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    Socket hostSocket = null!;
    Thread thread = null!;
    string localIP = string.Empty;
    string computrHostName = string.Empty;
    int dataSize = 0;
    byte[] imageBytes = new byte[800 * 650 * 16*10]; //Picture of great 16 bpp RGB 565

    private void mainForm_Load(object sender, EventArgs e)
    {
        computrHostName = Dns.GetHostName();
        IPHostEntry hostname = Dns.GetHostEntry(Dns.GetHostName());
        foreach (IPAddress ip in hostname.AddressList)
        {
            if (ip.AddressFamily.ToString() == "InterNetwork")
            {
                localIP = ip.ToString();
            }
        }
        this.Text = this.Text + " | " + localIP;
    }

    private void liveScreen_Click(object sender, EventArgs e)
    {
        connectSocket();
    }

    private void connectSocket()
    {
        Socket receiveSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        IPEndPoint hostIpEndPoint = new IPEndPoint(IPAddress.Parse("192.168.0.24"), 81);
        //Connection node
        receiveSocket.Bind(hostIpEndPoint);
        receiveSocket.Listen(10);
        //MessageBox.Show("start");
        hostSocket = receiveSocket.Accept();
        thread = new Thread(new ThreadStart(trreadimage))
        {
            IsBackground = true
        };
        thread.Start();
    }
    private void trreadimage()
    {
        while (true) {
            string imageName = "stremScreen.JPG";
            try
            {
                dataSize = hostSocket.Receive(imageBytes);
                if (dataSize > 0)
                {
                    MemoryStream ms = new MemoryStream(imageBytes);
                    Image img = Image.FromStream(ms);
                    img.Save(imageName, System.Drawing.Imaging.ImageFormat.Jpeg);
                    videoBox.Image = img;
                    ms.Close();
                }

            }
            catch (Exception ee)
            {
                //messagebox.show("foi aqui - " + ee.message);
                break;
            }
            Thread.Sleep(1500);
        }
        trreadimage();
    }
}

我检查了发送方保存的丝网印刷,没问题,但是我在接收方得到的东西很乱,因为有一些错误的裁剪......

收到流图像:

你们对可能发生的事情有什么建议吗?实际上我在接收方也遇到了 Image.FromStream() 错误 (https://social.msdn.microsoft.com/Forums/en-US/820fe38b-3fb6-4490-9608-10c4133e4a50/imagefromstreamms-parameter-is-not-valid?forum=aspdotnetwebpages),这就是为什么我将代码的 catch {} 部分留空的原因......我没有解决这个问题错误。

经过一些尝试,我通过在发送前压缩字节数组得到了解决方案

private static byte[] Compress(byte[] data)
        {
            MemoryStream output = new MemoryStream();
            using (DeflateStream dstream = new DeflateStream(output, CompressionMode.Compress))
            {
                dstream.Write(data, 0, data.Length);
            }
            return output.ToArray();
        }

并在另一端解压:

private static byte[] Decompress(byte[] data)
{
    MemoryStream input = new MemoryStream(data);
    MemoryStream output = new MemoryStream();
    using (DeflateStream dstream = new DeflateStream(input, CompressionMode.Decompress))
    {
        dstream.CopyTo(output);
    }
    return output.ToArray();
}