Animation using List<Image> - c#

I'm skeptical if I'm doing this the right way.
I have to play an animation at about 60fps. I'm using a List<Image> to load all the frames at the time of initialization. And then using a System.Timers.Timer to call an event at every 10ms which will change the image in the pictureBox.
List<Image> imageList = new List<Image>();
private static Timer_Event(o, e)
{
pictureBox.Image = imageList[i++];
}
So, am I doing this right? Is there a better approach?

What you're describing seems unlikely to work in a robust fashion. Here's a brief summary:
In my experience, timers aren't generally accurate. Since timer messages go through the Windows Message pump, they can only move as fast as your Windows UI processes messages. Any application that interferes with messages will cause your timers to stutter, although careful work can prevent most of this. Some classic discussion of timers here: Winforms Timer for Dummies
In general, List is a very inefficient way to store images. For a one-second animation at 60 frames per second, you will have to hold 60 images in memory and decompress each one individually.
Here are some possible solutions, and the tradeoffs they entail:
Full Motion Video
If you are looking to present a full motion video on your form, you should really consider using a MediaElement (for WPF applications: http://www.c-sharpcorner.com/uploadfile/dpatra/media-element-in-wpf/ ) or a MediaPlayer object (for WinForms applications: http://msdn.microsoft.com/en-us/library/bb383953(v=vs.90).aspx ).
This will allow you to play a lengthy video that contains extremely high quality images, varied compression, and start or stop the playback arbitrarily. However, the startup and memory usage requirements of a full video player are greater than just displaying a single image on screen. You will find that your application takes a moment to initialize the video subsystem, which may be annoying.
Animated Images
It's possible to show an animated image in a picturebox in Windows Forms or WPF. You would simply generate the animated image - generally using a GIF animation file. This will work smoothly for a majority of simple animations, and it's possible to get free-to-use animated GIFs from websites like this one: http://www.chimply.com/Generator
Here's a walkthrough of how to place an animated GIF on your form: http://trompelecode.com/2010/12/animated-progress-indicator-in-csharp-windows-forms/
Sprite Animation
Let's say you need to accurately represent each image exactly (which isn't necessary if you're simply trying to look appealing), and that you don't want the overhead of a video system (which is okay if you're only playing a second or two worth of animations). What you want to do then is create a single composite "sprite" image. This reduces the memory overhead requirements of your application and reduces the amount of time decompressing files.
For example, here's a website that generates PNG sprites for you: http://wearekiss.com/spritepad
Once you generate an image with sprites, you can place it within a picturebox and animate the image by changing the relative position of the image within the picturebox. Here's a walkthrough of how to accomplish this: C# picturebox load image with an offset
Summary
Any way you choose to display an animated image, you will have some tradeoffs. I like to pick the simplest possible solution for myself - and in my case I like to use an animated GIF image. Good luck animating!

The .avi is alternative otherwise, however, if you have bunch of images than probably utilizing threads/timers apparently seems to be the way forward.

The easiest way would be to use an animated gif in that pictureBox and don't mess with timers.

You may also be able to put your animation together using WPF or Silverlight ... if you need the animation to be interactive or programmatically controllable that would probably be the way to go.
If on the other hand the animated content is static then AVI (or MPEG etc.) is probably your best bet.
You don't say exactly what you're trying to accomplish so I can't be sure.

Related

Xamarin iOS Image animation

I want to animate a UIImage, or better said a UIView. I've got a Background consisting of multiple layers where each layer should be animated a little differently (lets assume this is a picture of a jungle and the second background layer is a plant). My first thoughts were to use a gif, but sadly this results in poor quality and big image sizes. The next thought was to use a "sprite sheet" image where the animation consists of 4 images which will be updated every 0.x seconds. Well this could work but i wanted to code as much as possible and use as less images as possible.
After the background is animated I want to animate a monkey running from the left to the right side. For sure the monkey itself should a animated and it should do this again after a random amount of seconds.
Which way would you implement such a thing and where would you start?
Edit
Forgot to mention that this should run with as low battery usage as possible

Best way to draw moving sphere in a smooth way in C#

Hello: I am trying to create an app which will display a moving sphere. App will vary speed and direction. I've tried Adobe Flash but cannot get it smooth. Smoothness is essential in this case. So I am trying C#.
Initially, I can see that this can be implemented by:
1) Creating a PictureBox of a sphere, and using a Timer, change its coordinates. or
2) Using the this.paint function to draw a filled circle, and somehow, with a timer, erasing and redrawing it.
Can someone recommend the best path to take? I'll have a main menu where the user will chose speed/direction/how many etc... and then simply show the "game window" with the moving spheres. Any guidance would be much appreciated.
This is to be displayed on a PC only.
Thanks
-Ed
I just answered a similar question here.
NOTE: Depending on your needs, it is possible to achieve smooth animations under winforms (under certain conditions) though you are responsible for everything. wpf provides an animation framework but wpf is perhaps a milestone harder.
It probably does not matter should you pursue winforms first or WPF. You arguably could learn the basics under winforms then move over to wpf. wpf may require you to learn quite a bit before you can do anything.
Summary
Essentially what this does is to create an offscreen bitmap that we will draw into first. It is the same size as the UserControl. The control's OnPaint calls DrawOffscreen passing in the Graphics that is attached to the offscreen bitmap. Here we loop around just rendering the tiles/sky that are visible and ignoring others so as to improve performance.
Once it's all done we zap the entire offscreen bitmap to the display in one operation. This serves to eliminate:
Flicker
Tearing effects (typically associated with lateral movement)
There is a Timer that is scheduled to update the positions of all the tiles based on the time since the last update. This allows for a more realistic movement and avoids speed-ups and slow-downs under load. Tiles are moved in the OnUpdate method.
If you note in the code for Timer1OnTick I call Invalidate(Bounds); after animating everything. This does not cause an immediate paint rather Windows will queue a paint operation to be done at a later time. Consecutive pending operations will be fused into one. This means that we can be animating positions more frequently than painting during heavy load. Animation mechanic is independent of paint. That's a good thing, you don't want to be waiting for paints to occur. xna does a similar thing
Please refer to my full SO answer complete with sample code
Here are a few hints to get you going:
First you will need to come to a decision about which platform to target: WPF or Winforms.
Then you should know what to move across what; a nice Bitmap or just a circle across an empty background or a Bitmap or a Form with controls on it.
In Winforms both your approaches will work, esp. if you set a circular region see here for an example of that. (The part in the fun comment!)
And yes, a Timer is the way to animate the sphere. Btw, a Panel or even a Label can display an Bitmap just as well as a PictureBox.
For smooth movements make sure to set the Form.Doublebuffered=true, if you move across a Form. If you move across any other control (except a PictureBox or a Label) you will need to subclass it to get access to the DoubleBuffered property!
It is often also a good idea to keep the Location of a moving item in a variable as a PointF and use floats for its speed because this way you can fine grain the speed and Location changes and also the Timer Intervals!

Capture a single pixel row from each frame of video and compile them together

I'm working on a project where I need to take a single horizontal or vertical pixel row (or column, I guess) from each frame of a supplied video file and create an image out of it, basically appending the pixel row onto the image throughout the video. The video file I plan to supply isn't a regular video, it's actually just a capture of a panning camera from a video game (Halo: Reach) looking straight down (or as far as the game will let me, which is -85.5°). I'll look down, pan the camera forward over the landscape very slowly, then take a single pixel row from each frame the captured video file (30fps) and compile the rows into an image that will effectively (hopefully) reconstruct the landscape into a single image.
I thought about doing this the quick and dirty way, using a AxWindowsMediaPlayer control and locking the form so that it couldn't be moved or resized, then just using a Graphics object to capture the screen, but that wouldn't be fast enough, there would be way too many problems, I need direct access to the frames.
I've heard about FFLib, and DirectShow.NET, I actually just installed the Windows SDK but haven't had a chance to mess with and of the DirectX stuff yet (I remember it being very confusing for me a while back when I messed with it). Hopefully someone can give me a pointer in the right direction.
If anyone has any information they think might help, I'd be super grateful for it. Thank you!
You could use a video rendered in renderless mode (E.g. VMR9, EVR), which allows you to process every frame yourself. By using frame stepping playback you can step one frame each time and process the frame.
DirectShow.NET can help you to use managed code where possible, and I can recommend it. It is however only a wrapper to DirectShow, so it might be worthwhile to look for more advanced libraries as well.
A few sidenotes: wouldn't you experience issues with lighting which differs from angle to angle? Perhaps it's easier to capture some screenshots and use existing stitching algorithms?

Is there a more performant alternative to ImageList.Images.Add?

I have a winforms ImageList which contains 200 256x256 images.
When I add the images, 1 by one, half of the programs time spent on the Add method according to ANTS .NET profiler.
So the program takes 10 secs to launch and 5 is spent there. That is very slow in my opinion.
I implemented the same thing using ImageList.Images.AddRange. The result did not change.
Does anyone know any alternatives or optimizations to solve this? Is the WPF ImageList any faster? Is there a faster winforms ImageList?
EDIT:
foreach (string imageFile in images)
{
imageList.Images.Add(Image.FromFile(imageFile)); // takes pretty much all of program's execution time.
}
Have a look at the album and list views in PhotoSuru, one of Microsoft's WPF sample applications. They have a couple different thumbnail view screens that load pretty quickly (all the images are loaded asynchronously, and only the images necessary are loaded). And there's full source code to get you started if it's what you are looking for.
It not precisely like Picasa (they decided only to show full rows of photos instead of a partially covered row like Picasa), but by implementing your own virtualizing IScrollInfo panel (reasonably straightforward, and Ben Constable has a great series of posts on it), you should be able to get the performance you're looking for and the behaviour you want.
A final note: You might be doing this already (are your images stored as 256x256 pixel images?), but whenever you're trying to display image thumbnails, you'll want to avoid loading the full image. Reading 2 MB+ image files off of the disk just to render an entire screenful of 256x256 pixel thumbnails always has a bigger performance hit than reading an appropriately sized small thumbnail image instead. If you can, cache the thumbnails somewhere (like Windows and Picasa do), or at the very least, try to use the embedded thumbnails in any JPEG files you encounter.
Are you using a ListView for the UI part using that ImageList?
The general solution to these kind of problems is to only load some of the images, because only some of them are shown at a time, and then load the other as needed. ListView has a VirtualMode property for this kind of scenarios.
Loading and adding 200 images at once may be too much to do, you could load the first shown images and then use a background thread to load the others. Have a look at how Win7 display images, it shows some placeholder when you scroll and then, when the image is loaded it shows the real picture. Be warned that this is not a simple thing to do.
try my code here to scale-down your image and make a thumbnail out of it.
Yes it is. Load images to List<Image>. Then call ImageList.Images.AddRange(list).
List<Image> list = new List<Image>();
foreach (string imageFile in images)
{
list.Add(Image.FromFile(imageFile));
}
imageList.Images.AddRange(list.ToArray());

Animation effect in .NET?

Can someone point me to a C# open source implementaion with a simple image animations.
e.g. I feed the input image to animator, and the animation code produces a few dozen of images which if displayed sequentially looks like animation.
I am not something extremely fancy - a simple DirectX filter like animations would do.
You would be look for a sprite then? Microsoft has tutorials on this including:
http://msevents.microsoft.com/cui/WebCastEventDetails.aspx?culture=en-US&EventID=1032273446&CountryCode=US
and general graphics in C# here:
http://www.microsoft.com/events/series/msdnvisualcsharp.aspx?tab=webcasts
Hmmm... I'm not sure if this is what you want, but I've have created a library called Transitions that lets you animate most properties of UI controls easily. You could use it to move the position of pictures, transition between pictures or grow and shrink pictures. But I'm not sure that this is exactly the effects you're after? Anyway, if it's any help, my library is here:
http://code.google.com/p/dot-net-transitions/

Categories