I'm writing a app to built a CAD viewer.
When I using EllipseGeometry in canvas, it's very slow to create/move graphics.
So i change to use DrawVisual. it's faster than using EllipseGeometry, but still very slow to move the whole graphics.
is there any sample code to show me how to deal with so many ellipses.
I think it's probabily too much for WPF.
I would go for DirectX. See SharpDX which is no longer mantained but will give you an idea.
See also Fast 2D graphics in WPF
Related
I am working with a WPF application and I came from web development background where I used to use images to show all kind of icons. But in this wpf project I found my senior developer draws them using wpf shapes.
So, it occurred to me is there a well known reason to do that? I mean does it enhance the performance somehow if I draw the icons instead of using images?
So, it occurred to me is there a well known reason to do that?
WPF has vector graphics. They stretch infinitely without losing resolution / quality.
In contrast, bitmaps (such as PNG or JPG) have a specific pixel resolution and they look bad when enlarged too much.
In terms of performance, displaying a bitmap is much cheaper than drawing a vector icon.
I am currently working in Windows Form Apps and am making what will essentially be a map editor for a game. The way i have gone about this is by having a central TabControl where each TabPage contains a custom PictureBox control and all the other UI controls are around this central TabControl. The PictureBox uses its Paint event to draw everything that is placed on the map, and therefore draws multiple images of many sizes, rotations and scales etc to the single PictureBox. This has all gone well so far. The TabPage is essentially used as a view window for the PictureBox and is of size (1280x720).
The problem is with the scale to which the maps are being produced. The avg (and also maximum) map size on screen is around 19200x10800px and can be made up of hundreds of items at any one point. When drawing just a backdrop image of size 19200x10800px the PictureBox starts to flicker when it redraws and makes the program unusable. As the map is so big you are able to pan around them and this is where the flickering really shows. Also i do not want to use a 19200x10800px image source if possible for the sake of file sizes and the scaled image quality isn't an issue at all.
I have done heaps of reading on why this might be and feel like I have tried everything up until this point. So far ive tried:
Having the background image only 1920x1080 and scaling it up by 10x
Starting with a 1920x1080 image, programatically resizing it and drawing this image
Slicing the background into multiple segments (i tried many different amounts) and drawing only the ones that the view window can see (tried this for both a small(1080p) and large(10800p) images)
Using graphics clipping so that only the things on screen would be drawn
Used Double Buffering on both the picturebox and the form that the picturebox is on
Converting the image at initialisation to an "optimised bitmap" with faster formatting and then drawing the bitmap
I've probably tried a couple other things along with minor optimisations but its taken me so long ive forgotten the rest. From what i've read its most likely something to do with the control redrawing too slowly for some sort of performance reason or a limitation with picturebox's, however exactly what is going on i cannot tell due to lack of experience with form apps controls.
Currently to draw the background in the Paint event i have either:
g.DrawImage(image, new Rectangle(0, 0, (int)(image.Size.Width * levelScale), (int)(image.Size.Height * levelScale)));
or
g.ScaleTransform(levelScale, levelScale);
g.DrawImage(image, new Rectangle(0, 0, (int)(image.Size.Width), (int)(image.Size.Height)));
Where g is the Graphics object.
Have I hit the limit of Win form apps capabilities or is there something i may be missing?
Any and all help appreciated,
Thanks in advance.
Just for formality I though id answer my own question just in case anyone else would like to know the outcome.
Based off the overwhelming consensus that winforms was just not made to do the things I was trying to do with it I decided I had to move to some other platform. Suggested to me was WPF, DirectX and OpenGL but after some extensive searching around I found what I think is the optimal solution.
In order to utilise the power of DirectX hardware acceleration MS has made it so that you can embed XNA graphics devices into a winforms application. Essentially you can create custom controls that run in the normal winform style that have access to a much higher caliber of graphics control. In this manner (with a bit of extra work) I have replaced the picturebox I was using with a custom graphics control which handles all of the drawing. This has worked very well, and on the up side i havent had to take too much of a hit to my development time.
For those looking for more info refer to this question which has further links that should help. Once again thanks to all those who gave their advice!
This is a quoted answer from the URL at the bottom. There are code examples at the link at the bottom. Hope this is helpful; not sure if you tried this yet and maybe it'll help you get a little more juice out of the existing picturebox control. As explain in the other answers, it sounds like you will be forced to a more powerful solution in the near future regardless (DirectX/OpenGL or WPF)
** Partial quote from http://social.msdn.microsoft.com/Forums/en-US/68ecd1f6-2eeb-45ce-a881-24c62145ab0e/c-picturebox-problems
"I'd guess the real problem is that it takes too long to redraw the images. GDI+ is pretty slow, it doesn't use any video hardware acceleration. To speed it up, be sure to avoid rescaling the drawing and to use the Format32PArgb format. It is about 10 times faster than any other format. Load the images into a Bitmap with the right format first."
If you have a LOT of items (Maybe realized as controls), forget about the standard event mechanism of Windows Forms. Some time ago, i've written a logic gate editor/simulator which supported lots of thousands of gates in the editor and was really fast. There, I've used the canvas and draw the gates as custom "images" instead of putting them as controls. You'll have to write a custom GetUnderlyingGate function which resolves the current gate / tile (Is your editor a tilemap editor?) from a coordinate array. Also, there were some visible area optimizations.
Maybe, when i'm back home, I'll upload some sourcecode and notify you.
I would like to write a simple ray tracer using WPF. It is a learning project and thus I favour configurability over performance (otherwise I'd go for C++).
I still want relatively fast pixel drawing. A previous question on StackOverflow contains code to achieve this in WPF, by obtaining a GDI bitmap. From the relatively little I know about Windows programming,
GDI is slow
DirectX is fast
WPF uses DirectX underneath (not sure which parts of WPF though)
Is it possible to obtain pixel-level access using DirectX (not GDI) through the WPF Canvas (or similar)?
I will also consider suggestions for incorporating DirectX API calls within a WPF window (alongside other WPF controls) if that is possible.
Thanks in advance.
Interesting, but with raytracing, writing the pixels to the screen will (should) not be the slow part. You can use WriteableBitmap for the purpose, though. It's certainly quick enough for what you want.
http://msdn.microsoft.com/en-us/library/system.windows.media.imaging.writeablebitmap.aspx
(For info, I use it in this emu/IDE - http://0x10c-devkit.com/ - and it can refresh a low res display with great performance. There's the source to that on the github repository, the LEM1802 plugin.)
Ah, this bit: https://github.com/kierenj/0x10c-DevKit/blob/master/PluginAPI/NyaElektriska.LEM1802/GPU.cs - see UpdateDisplay.
Another solution is WriteableBitmapEx. It extends the builtin WriteableBitmap.
There is an open Source Project Called Direct Canvas wich is A hardware accelerated, 2D drawing API that supports vector graphics, multimedia files, extensible pixel shaders, blending modes and more!
http://directcanvas.codeplex.com/
Demo http://www.youtube.com/user/jdollah69#p/u
I need to speed up my image viewer, and wondering if I should be looking into creating my own DirectX control to do so.
My image viewer displays medical images. They can be pretty large. We're talking 55mb when it comes to mammography. The pixel data is 16bit greyscale stored in a ushort array. Without getting into the gory details, my current approach is loading the pixel data into an ImageSource, and using the WPF Image control.
I've never done anything with DirectX. Is it worth diving into it? Would it be any faster than the native WPF stuff? If so how significantly? Or, should I just forget about DirectX and look into areas where I can improve my current approach?
Before somebody says so, I know WPF utilize DirectX. I'm wondering If removing the WPF layer and writing the DirectX myself will improve performance.
I have some experience drawing multi-gigabyte satellite and chart imagery. Working with imagery around 55MB should probably work okay even without trying to optimize it too much. You haven't really given enough detail to recommend one alternative over the other, so I will give my opinion on the pros and cons.
Using 2D windows APIs will be the simplest to implement and should always be fast enough if you don't need to rotate and simply want to display an image and zoom and pan around. If you treat it as one large image the performance will not be as good when you zoom out if you are drawing with halftoning to give a nice smooth image. This is because it will effectively have to read all 55mb of image every time it draws.
To get around this performance issue you can make multiple bitmaps, effectively mip-mapping your image. As you zoom out you can pick the reduced resolution image closest to the resolution you are trying to draw . If you are not familiar with mip-mapping here is a Wikipedia link:
http://en.wikipedia.org/wiki/Mipmap
Implementing it with DirectX will be 10x as difficult. Different graphics hardware has different maximum texture sizes. Most likely you will need to break your image up in to multiple textures to draw and you will also have to keep track of render states, viewing matrices, etc.
However, if you do use DirectX, you can implement lots of real-time photo adjustments You can do real-time rotation by simply adjusting view matrices. You can do real-time contrast, brightness, gamma, and sharpness easily in a pixel shader.
There are two other API's I might suggest. If you are willing to limit yourself to Vista or later then Direct2D would be a little simpler than Direct3D. Also if you ever will need to implement it on a non-windows platform I would suggest using OpenGL instead. My current project is in Direct3D because a few years ago when we started it OpenGL was falling behind and I didn't forsee the popularity of Android devices. I now wish we had used OpenGL instead.
Try profiling to see where WPF is spending its time. Are you displaying the images at their native resolution? If not it might be worthwhile to do some preprocessing and create 1/2 resolution versions.
Greetings, everyone.
I'm trying to learn some Silverlight basics, and have decided to write a simple Mandelbrot-set drawing application for that reason. In Silverlight, of course. ;)
The application is mostly done. I'm using a WriteableBitmap to work on the pixels, and a simple Image placed on an empty form to display this bitmap (using the Source property). I've even managed to get zooming and moving the fractal around under control.
Now I wanted to spice things up a little bit by adding just a slight bit of animations; I know I cannot make the fractal move, as it's a scalar graphics object, but for example, when I zoom in, it would be nice if the initial zoom was a smooth animation, after which the application would recalculate the new, "zoomed in and sharp as a knife" image. Likewise, if I drag the image around (which is used to move the fractal) and the mouse leaves the image area, it would be great if the fractal returned smoothly to it's initial position (as it is now, it just "snaps" back as the initial settings are restored).
My problem is that I have no idea which parameter to control in an animation. I'm using ScaleTransform, for example, for zooming, but that is used to render the WriteableBitmap on the bitmap itself rather than use the transform properties of the image object. I did so because when I started manipulating the image properties, then the whole image started to move around the form, when I'd rather it's boundaries stay in place.
I suspect I may be trying to do something which Silverlight wasn't really meant to do in the first place (or I've started doing this whole thing wrong), but if I COULD add such little animations, that would be great. As such, any tips appreciated.
It sounds like you want to use the Silverlight animation engine to animate your own custom properties, that control your image display, rather than the image elements or containers.
If your properties for controlling the appearance of the image were exposed as double Dependancy Properties, then the animation system can use the basic DoubleAnimation objects to change your settings smoothly over time. You can even author animations in Expression Blend.
The animation engine would certainly give you easing functions etc to smooth out motion. If I had more detail on how your object was structured I could be more specific, but I hope this helps.