简体   繁体   中英

C# PictureBox control flickering / performance issues

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM