【问题标题】:Rendering to a single Bitmap object from multiple threads从多个线程渲染到单个 Bitmap 对象
【发布时间】:2010-10-13 12:49:40
【问题描述】:

我正在做的是将多个位图渲染到单个位图。可能有数百个图像,并且被渲染的位图可能超过 1000x1000 像素。

我希望通过使用多个线程来加速这个过程,但由于 Bitmap 对象不是线程安全的,它不能直接并发渲染。我的想法是将大位图拆分为每个 cpu 的部分,分别渲染它们,然后在最后将它们重新组合在一起。我还没有这样做,以防你们有更好的建议。

有什么想法吗?谢谢

【问题讨论】:

    标签: c# multithreading graphics bitmap rendering


    【解决方案1】:

    您可以让每个线程写入一个字节数组,然后当它们都完成后,使用单个线程从字节数组创建位图对象。如果所有其他处理都事先完成,那应该很快。

    【讨论】:

      【解决方案2】:

      Lee,如果您要使用 Image GDI+ 对象,您可能最终只需要完成所有工作两次。您在多个线程中生成的部分将需要在分而治之的方法结束时重新组合,这不会首先破坏划分的目的吗?

      只有在每个位图部分都执行相当复杂的操作时,才能解决此问题,这比简单地将图像子部分重绘到大位图上而不费力气要花费更多的处理时间。

      希望对您有所帮助。您打算进行什么样的图像渲染?

      【讨论】:

      • 是的,我认为在我发布之后,除了将 n 个位图绘制到一个大的位图之外,没有什么额外的事情发生,几乎所有的时间都花在了 DrawImage 方法中。需要一个新想法。
      【解决方案3】:

      我做了类似的事情,在我的情况下,我让每个线程锁定 x(取决于图像的大小和线程的数量)图像中的许多行位,并对这些位进行写入,以便没有线程与他们的写入重叠。

      【讨论】:

        【解决方案4】:

        您可以使用 LockBits 并处理图像的各个部分。

        有关如何完成此操作的示例,您可以查看 Paint.Net 源代码,尤其是 BackgroundEffectsRenderer(是的,这是单声道分支的链接,但 Paint.Net 主代码似乎仅可用在 zip 文件中)。

        【讨论】:

          【解决方案5】:

          一种方法是将所有小位图渲染到一个 ersatz 位图上,这将只是一个二维 int 数组(这实际上是一个 Bitmap )。将所有小位图组合到大数组中后,您可以一次性从大数组复制到相同尺寸的真实Bitmap

          我一直使用这种方法(不包括多线程方面)来处理 Windows Mobile 设备上的复杂图形,因为可用于创建“真实”GDI+ 位图的内存非常有限。

          您也可以按照最初的意图使用BitmapBitmap 不能保证是线程安全的,但我不确定这是否会成为问题,只要您可以确保没有两个线程会覆盖位图的同一部分。至少我会试一试。

          更新:我刚刚重新阅读了您的问题,我意识到您可能不会看到通过使这些操作的整体速度提高很多(如果有的话)螺纹。这是经典的九个女人一个月内不能生孩子的问题。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-11-27
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多