can anyone give me a quick comparison what are pros and cons of System.Windows.Media.Imaging.WriteableBitmap compared to System.Drawing.Image?
Why I'm asking because I have an program/api where I can basically choose between which one I want to use.
I know that not both can bind to the same controls for instance, but I'm interested a bit more in terms whats "under the hood".
The api I want to use is for displaying "realtime"/"fast" images and therefore have a fps of about 20-30 (if this matters somehow for the comparison).
Well in case you want to go low level (well its still c# not c++) but the writeable bitmap allows for locking of the bitmap data, to run some unsafe code against it (usually graphics stuff needs super fast dirty trick logic processing )
So if you plan to go low level, work with pointers and stride, then i would go for it. BTW you can create functions to exchange formats, if all you want to do is displaying an image, maybe rotate or flip it or thinking about displaying stream data into an an image i'd choose the other one.
Related
As part of my audio libary i would like to create a sample visualisations.
I know how I get the values I want to draw like fft results and so on.
But the main problem is that I don t know whats the best way to draw them. I have quite a lot of experience in using wpf but I never had to do something like this. What should I use to keep performance as good as possible?
There are a number of different approaches you can take, depending on the quality you need, memory usage, and performance....here are just some.
create a new object derived from FrameworkElement, and then inside draw the "visual" aspect dynamically by drawing onto a DrawingContext during OnRender. Drawings have a much lower overhead than other WPF elements such as Shapes, Image, etc. However, it still may not scale well if you have 1000s of elements. http://msdn.microsoft.com/en-us/library/ms751619.aspx
WriteableBitmapEx....it will give you the drawing primitives you need to write into a Bitmap directly. http://writeablebitmapex.codeplex.com/ .. see this for some demos which are spookily similar to what you would do for an audio visualization. http://blogs.claritycon.com/blog/2011/03/advanced-animation-animating-15000-visuals-in-silverlight-2/
use DirectX with Direct2D. This offers DirectX like performance, but you would need to use COM interop or C++/CLI code wrappers to make it available to your .NET C# code. http://www.codeproject.com/Articles/113991/Using-Direct2D-with-WPF
Some other links:
http://jeremiahmorrill.wordpress.com/2011/02/14/a-critical-deep-dive-into-the-wpf-rendering-system/
I'm developing depth processing (Xbox Kinect, Asus Xtion, etc) applications using OpenNI.
I need a really simple and fast way of drawing on a Windows form when new depth data is available from the sensor (30 or 60 fps depending on resolution).
Currently I'm invalidating a double-buffered panel from a seperate thread when the data becomes available, and then setting pixels of a bitmap in the panel's paint method, yielding a predictably awful 5fps.
System.Drawing.Graphics seems to lack a fast way to set individual pixels, unless anyone can instruct otherwise.
I literally just need to set pixel colours, so would like to avoid using third party high speed rendering APIs if possible, and ideally use something as native as possible.
Does anyone have any suggestions?
If you're using Bitmaps, then you should use LockBits and UnlockBits to access the data directly in memory. In C#, you can get some extra performance by using unsafe code blocks and pointers.
See this link for more information: http://web.archive.org/web/20150227183132/http://bobpowell.net/lockingbits.aspx
image.SetPixel() is very slow when you are replacing many pixels per frame and you need many frames per second.
It will be a lot faster when you use a WriteableBitmap and call CopyPixels
This way you can fill the array with pixel data using multiple threads and simply blit the array to the image in a single call.
EDIT
Note that WriteableBitmap is a WPF class. If you are bound to WinForms you might need to create your own implementation. WPF/WinForms/GDI interop: converting a WriteableBitmap to a System.Drawing.Image?
You could try my LINQ image processing library to work with your "buffer-bitmaps". It uses an accessible LINQ syntax but is very performant for large bitmaps. It is available on Nuget as a single file include in your project.
Hope that helps!
I am stumped by this very simple problem. I am making a tile-based game engine and need to be able to allow a user to edit the map using a WPF User Interface. Naively, I had assumed that I could simply constantly update a good old fashioned "buffered" System.Drawing.Graphics.Bitmap using Graphics.FromImage. I would draw onto the bitmap the tiles that make up the map, and then blit the buffer Bitmap to the screen. However, from my thorough research I now believe that it isn't that easy at all.
Rather than bore you with what I've found out so far (that either doesn't work, or is incredibly slow), may I ask very simply, what is the best way for continuously drawing large numbers of bitmaps efficiently via a WPF UI?
I will accept such suggestions as "go back to Windows Forms". If that's the case, then I am going to be very dissapointed with WPF!
The WriteableBitmap class is a high-performance WPF-compatible bitmap that allows direct access to its bits. This MSDN documentation page contains a fairly thorough example of using it.
Freezable can make a big difference to performance when dealing with Bitmaps, you can then also load the buffer using a background thread to stop the UI locking up.
This tutorial covers the basics
Is WPF be able to manipulate large bitmaps where GDI+ cannot due to memory limitations?
I have bitmaps that are 10,000x10,000 easily, and could even be much larger than that. Worst case I think I can break the single bitmap into large tiles and work with that I guess.
I basically need to do four things
Take an set of tiled images
Put all of those tiles into a single bitmap
Convert the bitmap to black and white
Scan the bitmap looking for changes from black to white
I know how to do these things in GDI+, but the problem I am running into is that the size of my bitmap is too large for the machine I am using, and it causes the program to crash, and I cannot make the image any smaller, so I am hoping that WPF will be able to succeed where GDI+ has failed me.
I don't think WPF will be able to help you here.
Why do you want to use bitmap object? You may as well work with an two-dimensional array of bytes or doubles (or any other type, depending oh what accuracy and range do you need), especially if you work with one channel only. Bitmaps have accessor methods (GetPixel and such) with huge computational overhead, working with arrays is by orders of magnitude faster (I know from personal experience), the only issue is that you can't display them as they are (you would have to convert the array back into image, which is fairly simple). But since you seem to want to do some sort of analysis on the data, I think array would be much more suitable for your needs.
I can post code samples detailing conversion from bitmap (either WPF or WinForms) to array an back if you want.
But remember, that 32bit .NET application can use approximately 1.2-1.4 gigabytes of memory - you have to fit in this space or you start getting OutOfMemory exceptions.
I eventually decided that the best course of action was to only work with the tiles, and then have an array that holds the actual information about each tile that I need. Given the number of tiles, it was the only sensible thing I could do.
Like CommanderZ said. Its Windows PRESENTATION Foundation, not Windows Image-manipulation Foundation.
You should try to either find some kind of image-manipulation library, but looking at size of your image, then doing everything yourself might be only way.
Especialy, you probably wont be able to work with bitmap as a whole, so you are going to work with tiles. Then it becomes problematic if you need to work with neighboring pixels. But I guess you should look into this yourself.
I have a .NET GDI+ bitmap object (or if it makes the problem easier a WPF bitmap object) and what I want to to is shift the whole lot by dx,dy (whole pixels) and I would ideally like to do it using .NET but API calls are ok.
It has to be efficient bacause its going to be called 10,000 times say with moderately large bitmaps.
I have implemented a solution using DrawImage - but its slow and it halts the application for minutes while the GC cleans up the temp objects that have been used.
I have also started to work on a version using ScrollDC but so far have had no luck getting it to work on the DC of the bitmap (I can make it work buy creating an API bitmap with bitmap handle, then creating a compatible DC asnd calling ScrollDC but then I have to put it back into the bitmap object).
There has to be an "inplace" way of shifting a bitmap.
mikej
Have you found the Graphics.FromImage method? That will let you manipulate the bitmap directly. I'm not sure what you're using with DrawImage, but Graphics.DrawImage should let you copy an area of the bitmap onto itself (and apply a shift in the process).
Alternatively, given a Graphics object, you can use Graphics.GetHdc, ScrollDC and Graphics.ReleaseHdc.
Do you just want to move the whole graphic? DrawImage has x,y parameters to do that. I'm probably not interpreting your question correctly.
As an aside, GDI is not going to be efficient period when you're working with 10,000 images. If you want anywhere near real-time performance you're going to have to either rework your algorithm or look into a 3D API (like DirectX or OpenGL) or possibly both.
Sorry if my question wasn't too clear.
All I'm trying to do is in place scroll a bitmap i.e. do a shift operation.
For example, a method like Scroll(B,1,0) would shift the entire bitmap B one pixel to the right.
I've got reasonable solution using both DrawImage and the ScrollWindowEx API call which is about 10 time faster.
I'm still trying to work out how I could do something faster using WPF.
I've written up my solution to the problem at Scrolling a bitmap but I'm still not sure that there isn't a better way and if it might be better done in say WPF?