Rendering to a single Bitmap object from multiple threads - c#

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

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, 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.

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.

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 a Bitmap 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 real Bitmap 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.

Related

Optimal way to set pixel data?

I'm working on a "falling sand" style of game.
I've tried many ways of drawing the sand to the screen, however, each way seems to produce some problem in one form or another.
List of things I've worked through:
Drawing each pixel individually, one at a time from a pixel sized texture. Problem: Slowed down after about 100,000 pixels were changing per update.
Drawing each pixel to one big texture2d, drawing the texture2d, then clearing the data. Problems: using texture.SetPixel() is very slow, and even with disposing the old texture, it would cause a small memory leak (about 30kb per second, which added up quick), even after calling dispose on the object. I simply could not figure out how to stop it. Overall, however, this has been the best method (so far). If there is a way to stop that leak, I'd like to hear it.
Using Lockbits from bitmap. This worked wonderfully from the bitmaps perspective, but unfortunately, I still had to convert the bitmap back to a texture2d, which would cause the frame rate to drop to less than one. So, this has the potential to work very well, if I can find a way to draw the bitmap in xna without converting it (or something).
Setting each pixel into a texture2d with set pixel, by replacing the 'old' position of pixels with transparent pixels, then setting the new position with the proper color. This doubled the number of pixel sets necessary to finish the job, and was much much slower than using number 2.
So, my question is, any better ideas? Or ideas on how to fix styles 2 or 3?
My immediate thought is that you are stalling the GPU pipeline. The GPU can have a pipeline that lags several frames behind the commands that you are issuing.
So if you issue a command to set data on a texture, and the GPU is currently using that texture to render an old frame, it must finish all of its rendering before it can accept the new texture data. So it waits, killing your performance.
The workaround for this might be to use several textures in a double- (or even triple- or quad-) buffer arrangement. Don't attempt to write to a texture that you have just used for rendering.
Also - you can write to textures from a thread other than your rendering thread. This might come in handy, particularly for clearing textures.
As you seem to have discovered, it's actually quicker to SetData in large chunks, rather than issue many, small SetData calls. Determining the ideal size for a "chunk" differs between GPUs - but it is a fair bit bigger than a single pixel.
Also, creating a texture is much slower than reusing one, in raw performance terms (if you ignore the pipeline effect I just described); so reuse that texture.
It's worth mentioning that a "pixel sprite" requires sending maybe 30 times as much data per-pixel to the GPU than a texture.
See also this answer, which has a few more details and some in-depth links if you want to go deeper.

C# - Multithreaded Processing of a single Image (Webcam Frames)

I have made a programm which is able to capture webcam frames and display them after running different per pixel algorithms - for example making the image gray scale.
At the moment I am using the FastBitmap class (can't find the link atm) which uses pointers to set and get a pixel within a bitmap.
However, I wanted to make my programm multithreaded so that multiple threads are working on the same image. For that I split the image into several sections via its BitmapData (one section per thread) and let the different threads work on their given section BitmapData. In the end a "manager" waits until all threads are done (join) and hands in the resulting image.
That's the theory, but in real this isn't working for me.
When I run this programm I get some strange errors, telling me that I have to release the LHC before reusing it, that I am accessing illegal memory, external exceptions etc. ... Everytime another and I can't understand why but I think the BitmapData sections are the main problem but I don't want to use the slower Mashal copy!
So my questions are the following:
Is it possible to have sectioned multithreaded image processing in C# with unsafe pointer methods?
If yes - how?
As for image processing libraries:
I don't need filters or some default image processing algorithms but I need my own "per pixel" algorithm - I even thought about adding a pixel shader to my program. xD
As my programm is based around the converting of frames of a webcam I need the fastest algorithm possible.
I've read all forum posts and tutorials etc. which I could just find and still have no idea how to do this with unsafe code correctly until I've made this account to finally ask this question here.
Robbepop
Of course it is possible :)
Take a look at:
https://github.com/dajuric/accord-net-extensions
This library contains exactly want you want:
parallel processor which is used to execute parallel operations on an image (e.g. color conversion) and yes those functions which operate on an image are unsafe (use pointers):
NuGet packages ready.

Save multiple images to disk rapidly in C#

I have a program in C# which saves a large number of images to disk after processing them
. This seems to be taking quite a bit of time due to the fact that so many images need to be saved.
Now, I was wondering: is there any way to speed up saving images in C#? At the moment, I'm using the standard bmp.Save(filename) approach.
If it helps, part of the image generation process involves using lockbits to access and modify the pixel values more rapidly, so perhaps when I do this, the images could be saved to disk at the same time? Apologies if this idea is daft, but I'm still somewhat new to C#.
You could certainly start a new thread for each image save. That would reduce the time taken a bit, the disk would then become the bottle neck though.
One other option would be to save the images to a temporary buffer list and then return control to the program. Then have a thread to write each one to disk in the background. Of course, that would only give the appearance of this happening quickly. It could possibly serve your needs though.
I am sure that .NET has implemented some sort of Asynchronous I/O to do this for you. I know Windows has so it makes sense that it would be in .NET.
This may be helpful.
http://msdn.microsoft.com/en-us/library/kztecsys(v=vs.71).aspx

Should a function that periodically returns bitmaps re-use them?

I have a function that returns a bitmap meant to be used as background in a panel, and occasionally I'd have to call it to create a new background based on parameters.
(Since there are two drawing functions for this panel (the background doesn't need to be changed as often as the foreground) it's not a matter of just drawing on the Paint event.)
So my question is: Is there a (more than symbolic) performance gain if I get the old background buffer as a paramenter and draw on it instead of creating a new bitmap every time the function is called?
Yes you gain quite a bit I would imagine.
For one, your memory constraints would be better bounded. If you're constantly creating Bitmaps, what's preventing your the client code from holding onto them and running you out of memory?
Allocation is usually one of the most expensive things in any large system. Reuse is definitely a good thing to have for objects that are expensive to create. You'll see less hiccups from Garbage Collection as well.
EDIT you can also consider maintaining your own pool of Bitmaps and not requiring the caller to pass in an existing one. Make sure you document that you own the Bitmaps and that the caller should treat them as read-only (can you wrap it in some immutable object?). That way you can create/dispose on your own time and not need anything from the client.
Yes, recreating a bitmap in code that runs while painting is usually far too expensive and slows down the painting too much. Keeping a copy of the bitmap solves the speed problem, at the expensive of needing more memory.
Note that the standard Control.BackgroundImage property is available for this, consider using it. You just need to add the code that updates that property (and calls Invalidate) when the conditions change that require a different background image. Drawing is automatic.
Secondary efficiency considerations are pre-scaling the bitmap to exactly fit the control's ClientSize, avoids having to rescale the bitmap at painting time. Big savings there, especially when the bitmap is large. But requires overriding the OnResize method so you can re-generate the scaled bitmap. When that slows down the painting too much while resizing the form then you need to wire the form's ResizeEnd event.
And creating the bitmap in the Format32bppPArgb pixel format, it draws about 10 times faster on most video adapters compared to any other format.

for heavy graphics apps in c# which will be more efficient double buffering or Buffered Graphics?

hello i have a heavy graphics application where i have to draw the graphics in 2-10 seconds every time this time varies depending upon the source application which is sending data to my application via UDP;
i have some static graphics there is no change in them some are semi dynamic that means some time they are updated and normally remains unchanged and all other graphics are dynamic there are about 8000 approx objects that are dynamic
i am working in c# and learn the two techniques given in title which one will be more efficient in this case help required
thanx in advance;
How large are your objects?
One probably can't predict what's more efficient here, it depends on everything, type of objects, size of objects, complexity of converting data to visible graphics and most of all the speed of your internet connection will limit your application.
In the end you probably want to try both and measure their performance. Even then you might want to implement it as a setting so the user can flip between the two.

Categories