c#套接字优化数据发送

时间:2015-08-10 20:53:24

标签: c# sockets compression screenshot

我正在创建一个屏幕共享应用程序,它捕获屏幕并将其分成小块,并与memcmp进行比较,而不是仅发送差异。 但是,有时它可以达到200~300kb!当然,它实际上使传输速度非常慢,所以我想听听如何优化我的程序的有效性。

这实际上是图像扫描码:

    private int _imageQuality;
    private byte[] _encodeBuffer;
    private Bitmap _decodedBitmap;
    private PixelFormat _encodedFormat;
    private int _encodedWidth;
    private int _encodedHeight;
    private readonly object _imageProcessLock = new object();
    private JpgCompression _jpgCompression;
     public unsafe void CodeImage(IntPtr scan0, Rectangle scanArea, Size imageSize, PixelFormat format,
        Stream outStream)
    {
        lock (_imageProcessLock)
        {
            byte* pScan0 = (byte*)scan0.ToInt32();



            int stride = 0;
            int rawLength = 0;
            int pixelSize = 4;


           // MessageBox.Show(pixelSize.ToString());
            stride = imageSize.Width * pixelSize;
            rawLength = stride * imageSize.Height;

            if (_encodeBuffer == null)
            {
                this._encodedFormat = format;
                this._encodedWidth = imageSize.Width;
                this._encodedHeight = imageSize.Height;
                this._encodeBuffer = new byte[rawLength];

                fixed (byte* ptr = _encodeBuffer)
                {
                    byte[] temp = null;
                    using (Bitmap tmpBmp = new Bitmap(imageSize.Width, imageSize.Height, stride, format, scan0))
                    {

                        temp = _jpgCompression.Compress(tmpBmp);
                    }

                    outStream.Write(BitConverter.GetBytes(temp.Length), 0, 4);
                //    MessageBox.Show(temp.Length.ToString());
                    outStream.Write(temp, 0, temp.Length);
                    NativeMethods.memcpy(new IntPtr(ptr), scan0, (uint)rawLength);
                }
                return;
            }


            long oldPos = outStream.Position;
            outStream.Write(new byte[4], 0, 4);
            long totalDataLength = 0;

            List<Rectangle> blocks = new List<Rectangle>();

            Size s = new Size(scanArea.Width, CheckBlock.Height);
            Size lastSize = new Size(scanArea.Width % CheckBlock.Width, scanArea.Height % CheckBlock.Height);

            int lasty = scanArea.Height - lastSize.Height;
            int lastx = scanArea.Width - lastSize.Width;

            Rectangle cBlock = new Rectangle();
            List<Rectangle> finalUpdates = new List<Rectangle>();

            s = new Size(scanArea.Width, s.Height);

            fixed (byte* encBuffer = _encodeBuffer)
            {
                var index = 0;

                for (int y = scanArea.Y; y != scanArea.Height; y += s.Height)
                {
                    if (y == lasty)
                    {
                        s = new Size(scanArea.Width, lastSize.Height);
                    }

                    cBlock = new Rectangle(scanArea.X, y, scanArea.Width, s.Height);

                    int offset = (y * stride) + (scanArea.X * pixelSize);

                    if (NativeMethods.memcmp(encBuffer + offset, pScan0 + offset, (uint)stride) != 0)
                    {
                        index = blocks.Count - 1;

                        if (blocks.Count != 0 && (blocks[index].Y + blocks[index].Height) == cBlock.Y)
                        {
                            cBlock = new Rectangle(blocks[index].X, blocks[index].Y, blocks[index].Width,
                                blocks[index].Height + cBlock.Height);
                            blocks[index] = cBlock;
                        }
                        else
                        {
                            blocks.Add(cBlock);
                        }
                    }
                }

                for (int i = 0; i < blocks.Count; i++)
                {
                    s = new Size(CheckBlock.Width, blocks[i].Height);

                    for (int x = scanArea.X; x != scanArea.Width; x += s.Width)
                    {
                        if (x == lastx)
                        {
                            s = new Size(lastSize.Width, blocks[i].Height);
                        }

                        cBlock = new Rectangle(x, blocks[i].Y, s.Width, blocks[i].Height);
                        bool foundChanges = false;
                        uint blockStride = (uint)(pixelSize * cBlock.Width);

                        for (int j = 0; j < cBlock.Height; j++)
                        {
                            int blockOffset = (stride * (cBlock.Y + j)) + (pixelSize * cBlock.X);

                            if (NativeMethods.memcmp(encBuffer + blockOffset, pScan0 + blockOffset, blockStride) != 0)
                            {
                                foundChanges = true;
                            }

                            NativeMethods.memcpy(encBuffer + blockOffset, pScan0 + blockOffset, blockStride);
                            //copy-changes
                        }

                        if (foundChanges)
                        {
                            index = finalUpdates.Count - 1;

                            if (finalUpdates.Count > 0 &&
                                (finalUpdates[index].X + finalUpdates[index].Width) == cBlock.X)
                            {
                                Rectangle rect = finalUpdates[index];
                                int newWidth = cBlock.Width + rect.Width;
                                cBlock = new Rectangle(rect.X, rect.Y, newWidth, rect.Height);
                                finalUpdates[index] = cBlock;
                            }
                            else
                            {
                                finalUpdates.Add(cBlock);
                            }
                        }
                    }
                }
            }

            for (int i = 0; i < finalUpdates.Count; i++)
            {
                Rectangle rect = finalUpdates[i];
                int blockStride = pixelSize * rect.Width;

                Bitmap tmpBmp = null;
                BitmapData tmpData = null;
                long length;

                try
                {
                    tmpBmp = new Bitmap(rect.Width, rect.Height, format);
                    tmpData = tmpBmp.LockBits(new Rectangle(0, 0, tmpBmp.Width, tmpBmp.Height),
                        ImageLockMode.ReadWrite, tmpBmp.PixelFormat);

                    for (int j = 0, offset = 0; j < rect.Height; j++)
                    {
                        int blockOffset = (stride * (rect.Y + j)) + (pixelSize * rect.X);
                        NativeMethods.memcpy((byte*)tmpData.Scan0.ToPointer() + offset, pScan0 + blockOffset, (uint)blockStride);
                        //copy-changes
                        offset += blockStride;
                    }

                    outStream.Write(BitConverter.GetBytes(rect.X), 0, 4);
                    outStream.Write(BitConverter.GetBytes(rect.Y), 0, 4);
                    outStream.Write(BitConverter.GetBytes(rect.Width), 0, 4);
                    outStream.Write(BitConverter.GetBytes(rect.Height), 0,4);
                    outStream.Write(new byte[4], 0, 4);

                    length = outStream.Length;
                    long old = outStream.Position;

                    _jpgCompression.Compress(tmpBmp, ref outStream);

                    length = outStream.Position - length;

                    outStream.Position = old - 4;
                    outStream.Write(BitConverter.GetBytes(length), 0, 4);
                    outStream.Position += length;
                }
                finally
                {
                    tmpBmp.UnlockBits(tmpData);
                    tmpBmp.Dispose();
                }

                totalDataLength += length + (4 * 5);
            }

            outStream.Position = oldPos;
            outStream.Write(BitConverter.GetBytes(totalDataLength), 0, 4);
        }
    }

我试过gzip,lz4,这些都可以压缩1kb最大......它没有真正帮助.. 我将不胜感激任何帮助!非常感谢你。

0 个答案:

没有答案