C#尽可能快地通过套接字发送图像

问题描述 投票:1回答:1

我试图尽可能快地发送插件上的图像试图压缩...比较图像...它仍然工作得很慢...顺便说一下我试图在压缩之前和之后保存图像和大小相同.... 1或2 kb les ...

看看客户端代码:

    Bitmap pre;
    private void Form2_Load(object sender, EventArgs e)
    {
        pre = GetDesktopImage();

        prev = Compress(ImageToByte(pre)).Length;
        theThread = new Thread(new ThreadStart(startSend));

        theThread.Start();
    }

    Bitmap curr;
    byte[] compressed;

    private void startSend()
    {
        sck = client.Client;
        s = new NetworkStream(sck);

        while (true)
        {
            curr = GetDesktopImage();

            compressed = Compress(ImageToByte(curr));

            if (Math.Abs(compressed.Length - prev) > 500)
            {
                bFormat.Serialize(s, compressed);

                prev = compressed.Length;
                count++;
            }
        }
    }  

压缩方法:

byte[] Compress(byte[] b)
    {
        using (MemoryStream ms = new MemoryStream())
        {
            using (GZipStream z = new GZipStream(ms, CompressionMode.Compress, true))
                z.Write(b, 0, b.Length);
            return ms.ToArray();
        }
    }

    byte[] ImageToByte(Image img)
    {
        ImageConverter converter = new ImageConverter();
        return (byte[])converter.ConvertTo(img, typeof(byte[]));
    }

这是服务器端:

        while (true)
        {
            try
            {
                bFormat = new BinaryFormatter();

                inBytes = bFormat.Deserialize(stream) as byte[];
                inImage = ByteToImage(Decompress(inBytes));

                theImage.Image = (Image)inImage;
                count++;
                label1.Invoke(new Action(() => label1.Text = count.ToString()));

            }
            catch { }
        }

顺便说一句我见过一些使用过socket.send的人并没有把图像保存到流中......你们可以解释一下这个区别吗?并建议我的代码有什么问题,如何改进我的算法?

c# image sockets stream
1个回答
1
投票

你的问题实际上是将“太宽泛”作为一个接近的理由来推动极限。通过网络发送图像数据的一般问题是一个非常广泛的研究领域,具有大量不同的技术,特定的应用/用户场景确定哪种技术实际上是最佳的。

也就是说,根据瓶颈的位置,您可以对所需的代码进行一次非常明显的更改,并且可以加快速度。

具体来说,您使用ImageConverter.ConvertTo()Bitmap对象转换为byte[],然后使用GzipStream压缩该字节数组。问题是ConvertTo()已经在压缩数据;它返回的byte[]包含表示为PNG格式的原始位图,这是一种相当不错的无损压缩算法。

因此,不仅压缩它几乎不会实现任何东西,它会花费你很多CPU来做任何事情。不要那样做。只需按原样发送byte[]数据,而无需通过GzipStream运行。

现在,所有这一切......

正如我所提到的,这种变化是否真的有助于这一切取决于其他因素,包括位图的大小,以及您使用的网络速度有多快。如果你已经在你的问题中发布的效率低下的代码已经使网络饱和,那么加速代码就没有用了。

用于处理网络带宽作为瓶颈的技术包括(但不限于):

  1. 使用有损压缩(例如JPEG,MPEG等),因此简单地丢弃发送成本太高的信息。
  2. 使用差分压缩技术(例如MPEG,MP4,Quicktime等),其利用了当处理运动图像视频时,从一帧到下一帧的大多数像素未改变或至少非常相似的事实。
  3. 发送渲染命令而不是位图数据。这通常用于VNC或Microsoft的远程桌面/终端服务器API之类的东西,并利用屏幕绘制通常使用相对简单的绘图命令(填充/轮廓矩形,绘制文本)影响大量像素的事实,绘制小位图等)。

在许多情况下,这些技术以不同方式组合以实现最大性能。

如果你想使用这些技术,你需要做的不仅仅是在Stack Overflow上提问。提供有关这些技术的广泛文档和教程远远超出了本网站的范围。您需要自己研究它们,或者甚至更好地使用现有的实现来实现您的目标。

© www.soinside.com 2019 - 2024. All rights reserved.