Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/307.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 捕获桌面,将其设置为256色并通过internet发送_C#_Screen Capture_Color Palette_256color - Fatal编程技术网

C# 捕获桌面,将其设置为256色并通过internet发送

C# 捕获桌面,将其设置为256色并通过internet发送,c#,screen-capture,color-palette,256color,C#,Screen Capture,Color Palette,256color,我在一个项目上工作,在这个项目中,我需要捕获桌面屏幕,并通过互联网将其发送给其他客户。要压缩图像,我想将其转换为256色图像。我有一个通用的256色调色板,我使用欧几里德距离来寻找最接近的颜色。问题是,我需要以每秒10-15帧的速度发送这些图像,而制作256色图像需要7秒。我想知道其他程序(如teamviewer或real VNC)是如何做到这一点的 for (int y=0;y<900;y++) //loop through the height for (int x=0;x&

我在一个项目上工作,在这个项目中,我需要捕获桌面屏幕,并通过互联网将其发送给其他客户。要压缩图像,我想将其转换为256色图像。我有一个通用的256色调色板,我使用欧几里德距离来寻找最接近的颜色。问题是,我需要以每秒10-15帧的速度发送这些图像,而制作256色图像需要7秒。我想知道其他程序(如teamviewer或real VNC)是如何做到这一点的

for (int y=0;y<900;y++) //loop through the height
     for (int x=0;x<1600;x++) //loop through the width
         for (int p=0;p<256;p++) //loop through palette colors
             {
                calculate Euclidean distance of each pixel for each color in pallette and 
                 find the nearest color
                 ** these nested loops take 7 seconds to complete
             }

for(int y=0;y编辑2:我删除了我的旧帖子,完全是因为它不相关!你说的256色,我以为是256位——而你说的是256字节!我想通过把你原来的坐标(
900 x 900
)放进我的计算器,并乘以256表示颜色。结果是
2073600
位,约为
2.5 MB
。压缩后,这可能达到约
1 MB
——而位颜色相等(除以8)将
300kb
base,压缩后的图像会小得多。解决方案很简单-拍摄这样的图像确实需要这么长的时间。你所说的大多数应用程序,如teamviewer,根据计算机性能,FPS较低,图像质量较低。因此,对不起-但解决方案是用你这样的电脑,你不可能在你要求的时间内完成这件事


编辑3:汉斯在你的问题下的评论中做了计算-我们说的是
22GB
。对于普通电脑来说,这不是一项正常的工作。这不是不可能的,但从2015年开始,家用电脑在一秒钟内处理这么多数据是不常见的。

编辑2:我删除了我的旧电脑发帖完全是因为它不相关!256色,我以为你指的是256位,而你指的是256字节!我想通过把你原来的坐标(
900 x 900
)放进我的计算器,并乘以256表示颜色。结果是
2073600
位,约为
2.5 MB
。压缩后,这可能达到约
1 MB
——而位颜色相等(除以8)将
300kb
base,压缩后的图像会小得多。解决方案很简单-拍摄这样的图像确实需要这么长的时间。你所说的大多数应用程序,如teamviewer,根据计算机性能,FPS较低,图像质量较低。因此,对不起-但解决方案是用你这样的电脑,你不可能在你要求的时间内完成这件事


编辑3:汉斯在你的问题下的评论中做了计算-我们说的是
22GB
。对于普通电脑来说,这不是一项正常的工作。这不是不可能的,但从2015年开始,家用电脑在一秒钟内处理这么多数据是不常见的。

编辑2:我删除了我的旧电脑发帖完全是因为它不相关!256色,我以为你指的是256位,而你指的是256字节!我想通过把你原来的坐标(
900 x 900
)放进我的计算器,并乘以256表示颜色。结果是
2073600
位,约为
2.5 MB
。压缩后,这可能达到约
1 MB
——而位颜色相等(除以8)将
300kb
base,压缩后的图像会小得多。解决方案很简单-拍摄这样的图像确实需要这么长的时间。你所说的大多数应用程序,如teamviewer,根据计算机性能,FPS较低,图像质量较低。因此,对不起-但解决方案是用你这样的电脑,你不可能在你要求的时间内完成这件事


编辑3:汉斯在你的问题下的评论中做了计算-我们说的是
22GB
。对于普通电脑来说,这不是一项正常的工作。这不是不可能的,但从2015年开始,家用电脑在一秒钟内处理这么多数据是不常见的。

编辑2:我删除了我的旧电脑发帖完全是因为它不相关!256色,我以为你指的是256位,而你指的是256字节!我想通过把你原来的坐标(
900 x 900
)放进我的计算器,并乘以256表示颜色。结果是
2073600
位,约为
2.5 MB
。压缩后,这可能达到约
1 MB
——而位颜色相等(除以8)将
300kb
base,压缩后的图像会小得多。解决方案很简单-拍摄这样的图像确实需要这么长的时间。你所说的大多数应用程序,如teamviewer,根据计算机性能,FPS较低,图像质量较低。因此,对不起-但解决方案是用你这样的电脑,你不可能在你要求的时间内完成这件事


编辑3:汉斯在你的问题下的评论中做了计算-我们说的是
22GB
。对于一台普通的计算机来说,这不是一项正常的工作。这不是不可能的,但从2015年开始,家用电脑在一秒钟内处理那么多数据的情况就不常见了。

好的。经过几天与m的斗争后我终于找到了一个解决方案。现在我能够以10~14fps的速度发送整个桌面图像,以20~30fps的速度发送桌面的变化区域

在代码中,我使用的类捕获屏幕和屏幕的变化。然后我将图像裁剪为10个小片段。之后,我使用八叉树颜色量化器将小片段制作成256色。感谢@Dai为我指明了方向。在颜色减少后,我对每个片段进行了转换
    int all_count = 0;
    Bitmap _desktop = null;

    Bitmap _merged_bitmap = new Bitmap(1600, 900);

    int _height_part_ = 0;
    int _total_rows = 10;
    Bitmap[] crops = null;
    Bitmap[] _new_crops = null;
    Stopwatch sw = new Stopwatch();

    int _desktop_height = 0;
    int _desktop_width = 0;

    ImageManipulation.OctreeQuantizer _q ;
    RLC.RemoteDesktop.ScreenCapture cap = new RLC.RemoteDesktop.ScreenCapture();



   private void CaptureAndSend()
    {
        sw.Restart();

        //cap = new RLC.RemoteDesktop.ScreenCapture();

        int _left = -1, _top = -1; //Changed regions
        _desktop = cap.Screen(out _left, out _top); //Capture desktop or changed region of it

        if (_desktop == null) return; //if nothing has changed since last capture skip everything

        _desktop_height = _desktop.Height;
        _desktop_width = _desktop.Width;

        // If very small part has changed since last capture skip everything
        if (_desktop_height < 10 || _desktop_width < 10) return; 

        TotalRows(_total_rows); // Calculate the total number of rows 

        crops = new Bitmap[_total_rows]; // Cropped pieces of image
        _new_crops = new Bitmap[_total_rows];

        for (int i = 0; i < _total_rows - 1; i++) //Take whole image and split it into smaller images
            crops[i] = CropRow(i);
        crops[_total_rows - 1] = CropLastRow(_total_rows - 1);


        Parallel.For(0, _total_rows, i =>
        {
            ImageManipulation.OctreeQuantizer _q = new ImageManipulation.OctreeQuantizer(255, 4); // Initialize Octree
            _new_crops[i] = _q.Quantize(crops[i]);

            using (MemoryStream ms=new MemoryStream())
            { 
                _new_crops[i].Save(ms, ImageFormat.Png);
                //Install-Package LZ4.net
                //Compress each part and send them over network
                byte[] data = Lz4Net.Lz4.CompressBytes(ms.ToArray(), Lz4Net.Lz4Mode.HighCompression);

                all_count += data.Length; //Just to check the final size of image
            }                  
        });



        Console.WriteLine(String.Format("{0:0.0} FPS , {1} seconds , size {2} kb", 1.0 / sw.Elapsed.TotalSeconds, sw.Elapsed.TotalSeconds.ToString(), all_count / 1024));
        all_count = 0;

    }
    private void TotalRows(int parts)
    {
        _height_part_ = _desktop_height / parts;
    }
    private Bitmap CropRow(int row)
    {
        return Crop(_desktop, new Rectangle(0, row * _height_part_, _desktop_width, _height_part_));
    }
    private Bitmap CropLastRow(int row)
    {
        return Crop(_desktop, new Rectangle(0, row * _height_part_, _desktop_width, _desktop_height - (row * _height_part_)));
    }
 [DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
    private unsafe static extern int memcpy(byte* dest, byte* src, long count);

    private unsafe Bitmap Crop(Bitmap srcImg, Rectangle rectangle)
    {
        if ((srcImg.Width == rectangle.Width) && (srcImg.Height == rectangle.Height))
            return srcImg;

        var srcImgBitmapData = srcImg.LockBits(new Rectangle(0, 0, srcImg.Width, srcImg.Height), ImageLockMode.ReadOnly, srcImg.PixelFormat);
        var bpp = srcImgBitmapData.Stride / srcImgBitmapData.Width; // 3 or 4
        var srcPtr = (byte*)srcImgBitmapData.Scan0.ToPointer() + rectangle.Y * srcImgBitmapData.Stride + rectangle.X * bpp;
        var srcStride = srcImgBitmapData.Stride;

        var dstImg = new Bitmap(rectangle.Width, rectangle.Height, srcImg.PixelFormat);
        var dstImgBitmapData = dstImg.LockBits(new Rectangle(0, 0, dstImg.Width, dstImg.Height), ImageLockMode.WriteOnly, dstImg.PixelFormat);
        var dstPtr = (byte*)dstImgBitmapData.Scan0.ToPointer();
        var dstStride = dstImgBitmapData.Stride;

        for (int y = 0; y < rectangle.Height; y++)
        {
            memcpy(dstPtr, srcPtr, dstStride);
            srcPtr += srcStride;
            dstPtr += dstStride;
        }

        srcImg.UnlockBits(srcImgBitmapData);
        dstImg.UnlockBits(dstImgBitmapData);
        return dstImg;
    }