C#尽可能快地通过套接字发送图像 [英] C# send images over socket as fast as possible

查看:76
本文介绍了C#尽可能快地通过套接字发送图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试通过套接字尝试尽可能快地发送图像,以进行压缩...比较图像...仍然工作得很慢... 顺便说一句,我尝试保存压缩前后的图像,并且大小相同.... 1或2 kb的文件...

I'm trying to send as fast as possible images over socket tried to compress... compare the images... it's still working pretty slow... btw I tried to save the image before and after the compression and size was the same.... 1 or 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并没有保存图像以供流传输的人....你们能解释一下区别吗?并建议我代码中有什么问题以及如何改进算法?

btw I've seen some people who used socket.send and didn't save the image to stream.... may u guys explain the difference? and suggest me what wrong in my code and how can I improve my algorithm?

推荐答案

您的问题实际上是在限制过于广泛"方面的局限性.通过网络发送图像数据的普遍问题是研究非常广泛的领域,它具有大量不同的技术,具体的应用程序/用户场景确定哪种技术实际上是最佳的.

Your question is really pushing the limits in terms of "too broad" as a close reason. The general problem of sending image data over a network is a very broad area of research, with a large number of different techniques, the specific application/user-scenario determining which technique is actually best.

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

That said, there is one very obvious change you can make to you code that is needed, and which might speed it up, depending on where the bottleneck is.

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

Specifically, you are using ImageConverter.ConvertTo() to convert the Bitmap object to a byte[], and then you are using GzipStream to compress that array of bytes. The problem with this is that ConvertTo() is already compressing the data; the byte[] it returns contains the original bitmap represented as PNG format, which is a fairly good, lossless compression algorithm for images.

因此,再次压缩它实际上什么也没做,而且要花费很多CPU来做任何事情.不要那样做只需按原样发送byte[]数据即可,而无需通过GzipStream运行.

So not only does compressing it again accomplish practically nothing, it costs you a lot of CPU to do that nothing. Don't do that. Just send the byte[] data as-is, without running it through GzipStream.


现在,所有所说的…


Now, all that said…

正如我提到的那样,这种改变是否真的能起到很大的帮助取决于其他因素,包括位图的大小以及所使用的网络的速度.即使您在问题中张贴的代码效率低下,如果您已经使网络饱和,那么加快代码的速度将无济于事.

As I mentioned, whether that change will really help all that much depends on other things, including how large the bitmaps are, and how fast the network you are using is. If you are already saturating the network even with the inefficient code you posted in your question, then speeding that code up isn't going to help.

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

Techniques that are used to deal with network bandwidth as a bottleneck include (but are not limited to):

  1. 使用有损压缩(例如JPEG,MPEG等),因此可以简单地丢弃发送成本太高的信息.
  2. 使用差分压缩技术(例如MPEG,MP4,Quicktime等),该技术利用了以下事实:处理运动图像视频时,从一帧到下一帧的大多数像素不变或至少是非常相似.
  3. 发送渲染命令而不是位图数据.这通常用于VNC或Microsoft的Remote Desktop/Terminal Server API之类的东西,并利用以下事实:使用相对简单的绘制命令(填充/概述矩形,绘制文本),屏幕上绘制通常会影响大量像素. ,绘制小位图等.

在许多情况下,这些技术以不同的方式组合在一起以实现最佳性能.

In many cases, these techniques are combined in varying ways to achieve maximum performance.

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

If you want to use these kinds of techniques, you need to do a bit more than just asking a question on Stack Overflow. It is well beyond the scope of this site to provide broad documentation and tutorials on those techniques. You'll need to research them yourself, or even better just use existing implementations to achieve your goals.

这篇关于C#尽可能快地通过套接字发送图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆