Home > Back-end >  Is there another way to use Graphics.DrawImage()?
Is there another way to use Graphics.DrawImage()?

Time:01-01

I have my paint method drawing images using the e.Graphics.DrawImage(myImage); e is the paint event args. I want to show an animation if a bool is true, otherwise I want to draw some other images.

In the paint event method, I have code similar to this:

if(myBool) 
{
  e.Graphics.DrawImage(nextFrame);
}
else
{
  e.Graphics.DrawImage(backgroundImage);
}

backgroundImage is a picture for my background, not just one plain color that I could replace with the actual Form1 background attribute. nextFrameis an image that is set to the next frame of the animation I want to play by a timer. When I run my program, there is significant lag and I think it's because I'm constantly using an if statement whenever the paint method is called.

If there was a way to use e.Graphics.DrawImage(); in another method, then I would use it then so that there are less if statements. Or is there a way to simplify my paint method to be less laggy.

Note: The animation and background images cover the entire screen, which have a resolution of 2256x1504, meaning those also might be causing the lag, in which case I would need to find a way to improve the speed of e.Graphics.DrawImage();

CodePudding user response:

Your question is whether there's another way to use Graphics.DrawImage in order to draw the entire screen quickly enough to serve as an animation.

One "other way" would be to invoke it indirectly by detecting changes to the myBool property and modifying the BackgroundImage property of the main form in response to that. If myBool is true, the animation consists of iterating the array of background images.

When I tested this approach it seemed pretty zippy, but you may have to actually animation

public partial class MainForm : Form
{
    public MainForm()
    {
        InitializeComponent();
        DoubleBuffered = true; // Smoother if true but compare performance with/without.
        var dir = 
            Path.Combine(
                AppDomain.CurrentDomain.BaseDirectory,
                "Backgrounds");

        _backgrounds =
            Directory
            .GetFiles(dir)
            .Select(_ => (Bitmap)Bitmap.FromFile(_))
            .ToArray();
        BackgroundImage = _backgrounds[0];
        checkBoxMyBool.CheckedChanged  = (sender, e) => myBool = checkBoxMyBool.Checked;
    }
    private readonly Bitmap[] _backgrounds;

    public bool myBool
    {
        get => _myBool;
        set
        {
            if (!Equals(_myBool, value))
            {
                _myBool = value;
                _ = onMyBoolChanged();
            }
        }
    }
    bool _myBool = false;
    private async Task onMyBoolChanged()
    {
        if(myBool)
        {                
            for (int i = 1; i < _backgrounds.Length; i  )
            {
                BackgroundImage = _backgrounds[i];
                await Task.Delay(100);
            }
        }
        else
        {
            BackgroundImage = _backgrounds[0];
        }
    }
}
  • Related