简体   繁体   中英

Flickering Image in C#

I have some code which renders an image to a form and using a trackbar to rotate that image. The code was taken from a you tube tutorial and works. However, when the image rotates it flickers. The tutorial poster says that using threads will remove the flickering, but I have no clue as to how to go about doing that. Any help would be very much appreciated. The code is set out below:

public partial class Form1 : Form
{

    Image img;
    int angle;

    public Form1()
    {
        InitializeComponent();
    }

    Thread th;
    Graphics graphicToDraw;
    Graphics graphicToScreen;
    Bitmap bmp;

    private void Form1_Load(object sender, EventArgs e)
    {

        img = Image.FromFile(@"c:\images\clock face with second hand 2.png");


    }

    private void Form1_Paint(object sender, PaintEventArgs paint)
    {


        bmp = new Bitmap(img.Width / 2, img.Height / 2);
        graphicToDraw = Graphics.FromImage(bmp);
       
        graphicToDraw.TranslateTransform(bmp.Width / 2, bmp.Height / 2);
        graphicToDraw.RotateTransform(angle);
        graphicToDraw.TranslateTransform(-bmp.Width / 2, -bmp.Height / 2);
        graphicToDraw.InterpolationMode = InterpolationMode.HighQualityBicubic;

        graphicToDraw.DrawImage(img, 0, 0);

        paint.Graphics.TranslateTransform(this.Width / 2, this.Height / 2);

        paint.Graphics.DrawImage(bmp, -bmp.Width / 2, -bmp.Height / 2);

        Debug.WriteLine("image width = " + bmp.Width);
        Debug.WriteLine("image height = " + bmp.Height);


    }

    private void Form1_Resize(object sender, EventArgs e)
    {
        Invalidate();
    }

    private void trackBar1_ValueChanged(object sender, EventArgs e)
    {
        angle = trackBar1.Value;
        Invalidate();
    }
}

Using threads is probably the wrong approach here. See How to: Reduce Graphics Flicker with Double Buffering for Forms and Controls . Ie set DoubleBuffered to true for your form or control.

DoubleBuffered = true;

You can not use any background thread to draw to the UI. Only the UI thread is allowed to access any UI classes, and the paint event will always be called on the UI thread. You could use a background thread to do the intermediate drawing to the buffer. But as far as I can see this is completely unnecessary, you should just set whatever transform you need on the graphics object and draw directly to it, there should be no need for the intermediate buffer. And if you do use a intermediate buffer, please ensure everything is correctly disposed.

The main case where such a background buffer could be useful is if you have lots of complicated drawing to do, and you only need to update the buffer infrequently. Then it may make sense to do the drawing to this buffer on a background thread.

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