【问题标题】:Capturing a region with SlimDX使用 SlimDX 捕获区域
【发布时间】:2017-03-22 17:51:41
【问题描述】:

所以我正在尝试使用 SlimDX 捕获一个区域。我的意思是我不想从[0,0] 捕获到[1920,1080]。 最好我想传递一个包含捕获所需信息的 Rectangle 对象。

我想用 SlimDX (DirectX) 来做这件事,因为如果我们看看像 CopyFromScreen 这样的替代品,它会大大缩短捕捉时间。

我需要捕获大约 30 个 100x100 像素的块,我认为使用 DirectX 可能是我最好的选择。所有起始坐标加上宽度/高度都存储在整数数组中。

我目前正在使用以下代码:

Rectangle rect = new Rectangle(chunk[0], chunk[1], chunk[2], chunk[3]); 
Bitmap temp = new Bitmap(rect.Width, rect.Height, PixelFormat.Format32bppArgb); 
Graphics g2 = Graphics.FromImage(temp); 
g2.CopyFromScreen(rect.Left, rect.Top, 0, 0, temp.Size, CopyPixelOperation.SourceCopy);

这段代码存在于一个遍历chunks 变量的foreach 循环中。但是,这需要大约 500 毫秒才能完成 30 次迭代。

【问题讨论】:

  • 是否可以重用位图和图形?无需在每次迭代时创建和丢弃它们。
  • 这是必需的,因为每次迭代的“坐标”都不同。还是你的意思是别的?
  • 我看到你提到它永远是 100x100 像素
  • 是的,但是这 30 个 100x100 的正方形是不同的。至少,程序期望它们是。这些方块代表屏幕的不同部分。
  • 复制所有小矩形的整个封闭边界矩形并随后在 CPU 端将其拆分可能会更快(这很容易并行化)。

标签: c# performance directx slimdx


【解决方案1】:

正如@Nico 指出的那样,复制一次然后拆分比许多小副本要快。这是一个例子

        var rects = Enumerable.Range(1, 30)
            .Select(x => new Rectangle(x, x, x + 100, x + 100));

        var bounds = Screen.PrimaryScreen.Bounds;
        Bitmap bigBmp = new Bitmap(bounds.Width, bounds.Height, PixelFormat.Format32bppArgb);
        Graphics g2 = Graphics.FromImage(bigBmp);
        g2.CopyFromScreen(bounds.X, bounds.Y, 0, 0, bounds.Size, CopyPixelOperation.SourceCopy);

        var bmps = rects.Select(rect =>
            {
                return bigBmp.Clone(rect, PixelFormat.Format32bppArgb);
            });

【讨论】:

  • 感谢您的示例。我还没有完全使用你的实现,但我确实做了克隆部分,所以非常感谢。我从 32 个块的约 500 毫秒到 32 个块的平均 25.7 毫秒!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-07
  • 2012-06-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-10
相关资源
最近更新 更多