从多个线程渲染到单个 Bitmap 对象
我所做的是将多个位图渲染为单个位图。 可能有数百张图像,并且渲染的位图可能超过 1000x1000 像素。
我希望通过使用多个线程来加速此过程,但由于 Bitmap 对象不是线程安全的,因此无法直接同时渲染。 我的想法是将大位图分成每个CPU的部分,分别渲染它们,然后最后将它们重新连接在一起。 我还没有这样做,以防你们有更好的建议。
有任何想法吗? 谢谢
What im doing is rendering a number of bitmaps to a single bitmap. There could be hundreds of images and the bitmap being rendered to could be over 1000x1000 pixels.
Im hoping to speed up this process by using multiple threads but since the Bitmap object is not thread-safe it cant be rendered to directly concurrently. What im thinking is to split the large bitmap into sections per cpu, render them separately then join them back together at the end. I haven't done this yet incase you guys/girls have any better suggestions.
Any ideas? Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您可以使用 LockBits 并处理图像的各个部分。
有关如何完成此操作的示例,您可以查看 Paint.Net 源代码,尤其是 BackgroundEffectsRenderer (是的,这是到 mono 分支的链接,但 Paint.Net 主代码似乎仅在 zip 文件中可用)。
You could use LockBits and work on individual sections of the image.
For an example of how this is done you can look at the Paint.Net source code, especially the BackgroundEffectsRenderer (yes that is a link to the mono branch, but the Paint.Net main code seems to be only available in zip files).
Lee,如果您要使用 Image GDI+ 对象,您可能最终会将所有工作都做两次。 在多个线程中生成的部分需要在分而治之的方法结束时重新组装,这是否会破坏最初的划分目的?
只有当您在每个位图部分中执行相当复杂的操作时,这个问题才可能得到解决,这比简单地将图像子部分重新绘制到大位图上而不遇到所有麻烦要花费更多的处理时间。
希望有帮助。 您计划进行什么样的图像渲染?
Lee, if you're going to use the Image GDI+ object, you may just end up doing all the work twice. The sections that you generate in multiple threads will need to be reassembled at the end of your divide and conquer approach and wouldn't that defeat the purpose of dividing in the first place?
This issue might only be overcome if you're doing something rather complex in each of the bitmap sections that would be much more processing time than simply redrawing the image subparts onto the large bitmap without going to all that trouble.
Hope that helps. What kind of image rendering are you planning out?
您可以让每个线程写入字节数组,然后当它们全部完成时,使用单个线程从字节数组创建位图对象。 如果所有其他处理都已事先完成,那么速度应该相当快。
You could have each thread write to a byte array, then when they are all finished, use a single thread to create a bitmap object from the byte arrays. If all other processing has been done before hand, that should be pretty quick.
我做了类似的事情,在我的例子中,我有每个线程锁定x(取决于图像的大小和线程的数量)图像中的许多行位,并对这些位进行写入,这样就没有线程重叠了他们的写入。
I've done something similar and in my case I had each thread lock x (depended on the size of the image and the number of threads) many rows of bits in the image, and do their writing to those bits such that no threads ever overlapped their writes.
一种方法是将所有小位图渲染到一个 ersatz 位图上,该位图只是一个二维
int
数组(这有点像一个Bitmap无论如何,确实是这样)。 将所有小位图组合到大数组中后,您可以将大数组一次性复制到相同尺寸的真实
Bitmap
中。我一直使用这种方法(不包括多线程方面)来处理 Windows Mobile 设备上的复杂图形,因为可用于创建“真实”GDI+ 位图的内存受到严重限制。
您也可以按照最初的意图使用位图。 位图不保证是线程安全的,但只要您能确保没有两个线程覆盖位图的同一部分,我不确定这会是一个问题。 至少我会尝试一下。
更新:我刚刚重新阅读了您的问题,我意识到,通过使这些操作成为多线程,您可能不会看到这些操作的整体速度有多大(如果有的话)改进。 这是典型的“九个女人一个月内生不出孩子”的问题。
One approach would be to render all the small bitmaps onto an ersatz bitmap, which would just be a two-dimensional
int
array (which is kind of all aBitmap
really is anyway). Once all the small bitmaps are combined in the big array, you do a one-time copy from the big array into a realBitmap
of the same dimensions.I use this approach (not including the multi-threaded aspect) all the time for complex graphics on Windows Mobile devices, since the memory available for creating "real" GDI+ Bitmaps is severely limited.
You could also just use a
Bitmap
as you originally intended.Bitmap
is not guaranteed to be thread-safe, but I'm not sure that would be a problem as long as you could assure that no two threads are ever overwriting the same portion of the bitmap. I'd give it a try, at least.Update: I just re-read your question, and I realized that you're probably not going to see much (if any) improvement in the overall speed of these operations by making them multi-threaded. It's the classic nine-women-can't-make-a-baby-in-one-month problem.