如何向winform窗体中插入动态图片

如何向winform窗体中插入动态图片,第1张

winfrom窗体中使用动态图:

方法一(简单):用label,然后设置为背景图片

方法二:使用GDI+ 来实现 (很粗略的实现,没有帧间隔)

            Image image = Image.FromFile("e://temp.gif")

 

            FrameDimension fd = new FrameDimension(image.FrameDimensionsList[0])

            int count = image.GetFrameCount(fd)

            Graphics g = this.panel1.CreateGraphics()

            while (true)

            {

 

                for (int i = 0 i < count i++)

                {

 

                    //g.Clear(Color.White)

                    image.SelectActiveFrame(fd, i)

                    g.DrawImage(image, new Point(0, 0))

                    System.Threading.Thread.Sleep(100)

                    Application.DoEvents()

                }

            }

方法三:(推荐)

            Bitmap animatedGif = new Bitmap("e://temp2.gif")

            Graphics g = this.panel1.CreateGraphics()

            // A Gif image's frame delays are contained in a byte array

            // in the image's PropertyTagFrameDelay Property Item's

            // value property.

            // Retrieve the byte array...

            int PropertyTagFrameDelay = 0x5100

            PropertyItem propItem = animatedGif.GetPropertyItem(PropertyTagFrameDelay)

            byte[] bytes = propItem.Value

            // Get the frame count for the Gif...

            FrameDimension frameDimension = new FrameDimension(animatedGif.FrameDimensionsList[0])

            int frameCount = animatedGif.GetFrameCount(FrameDimension.Time)

            // Create an array of integers to contain the delays,

            // in hundredths of a second, between each frame in the Gif image.

            int[] delays = new int[frameCount + 1]

            int i = 0

            for (i = 0 i <= frameCount - 1 i++)

            {

                delays[i] = BitConverter.ToInt32(bytes, i * 4)

            }

            // Play the Gif one time...

            while (true)

            {

                for (i = 0 i <= animatedGif.GetFrameCount(frameDimension) - 1 i++)

                {

                    animatedGif.SelectActiveFrame(frameDimension, i)

                    g.DrawImage(animatedGif, new Point(0, 0))

                    Application.DoEvents()

                    Thread.Sleep(delays[i] * 10)

                }

            }

方法四: 使用.NET 自带的类:System.Drawing.ImageAnimator

最近在做一个图片查看器,由于使用一般的PctureBox,在性能和缩放控制上都无法满足预期的要求,因此所有组件的呈现均是通过重写控件的OnPaint事件来绘制。在查看gif图片时发现Graphics.DrawImage只呈现第一帧,无法满足预期要求,因此经过摸索寻找到了解决自绘gif的较好办法。

这里介绍一个.net自身携带的类ImageAnimator,这个类类似于控制动画的时间轴,使用ImageAnimator.CanAnimate可以判断一个图片是否为动画,调用ImageAnimator.Animate可以开始播放动画,即每经过一帧的时间触发一次OnFrameChanged委托,我们只要在该委托中将Image的活动帧选至下一帧再迫使界面重绘就可以实现动画效果了。

为了方便以后的使用,我将这些代码整合到了一起,形成一个AnimateImage类,该类提供了CanAnimate、FrameCount、CurrentFrame等属性,以及Play()、Stop()、Reset()等动画常用的方法,代码如下:

 

using System      

using System.Collections.Generic      

using System.Text      

using System.Drawing      

using System.Drawing.Imaging      

     

namespace GifTest      

{      

    /**//// <summary>      

  /// 表示一类带动画功能的图像。      

  /// </summary>      

  public class AnimateImage      

   {      

       Image image      

       FrameDimension frameDimension      

      /**//// <summary>      

      /// 动画当前帧发生改变时触发。      

      /// </summary>      

      public event EventHandler<EventArgs> OnFrameChanged      

  

     /**//// <summary>      

      /// 实例化一个AnimateImage。      

      /// </summary>      

      /// <param name="img">动画图片。</param>      

      public AnimateImage(Image img)      

       {      

           image = img      

          lock (image)      

          {      

               mCanAnimate = ImageAnimator.CanAnimate(image)      

              if (mCanAnimate)      

               {      

                  Guid[] guid = image.FrameDimensionsList      

                   mFrameCount = image.GetFrameCount(frameDimension)      

               }      

           }      

       }      

  

     bool mCanAnimate      

     int mFrameCount = 1, mCurrentFrame = 0      

  

      /**//// <summary>      

     /// 图片。      

      /// </summary>      

      public Image Image      

       {      

          get { return image }      

       }      

  

      /**//// <summary>      

      /// 是否动画。      

     /// </summary>      

      public bool CanAnimate      

       {      

          get { return mCanAnimate }      

      }      

  

       /**//// <summary>      

    /// 总帧数。      

      /// </summary>      

      public int FrameCount      

       {      

           get { return mFrameCount }      

        }      

  

       /**//// <summary>      

       /// 播放的当前帧。      

       /// </summary>      

       public int CurrentFrame      

        {      

           get { return mCurrentFrame }      

        }        

       /**//// <summary>      

      /// 播放这个动画。      

      /// </summary>      

       public void Play()      

       {      

          if (mCanAnimate)      

           {      

              lock (image)      

               {      

                   ImageAnimator.Animate(image, new EventHandler(FrameChanged))      

               }      

           }      

       }      

  

      /**//// <summary>      

      /// 停止播放。      

      /// </summary>      

      public void Stop()      

       {      

          if (mCanAnimate)      

           {      

              lock (image)      

               {      

                   ImageAnimator.StopAnimate(image, new EventHandler(FrameChanged))      

               }      

           }      

       }      

  

      /**//// <summary>      

      /// 重置动画,使之停止在第0帧位置上。      

      /// </summary>      

      public void Reset()      

       {      

          if (mCanAnimate)      

           {      

               ImageAnimator.StopAnimate(image, new EventHandler(FrameChanged))      

              lock (image)      

               {      

                   image.SelectActiveFrame(frameDimension, 0)      

                   mCurrentFrame = 0      

               }      

           }      

       }      

  

      private void FrameChanged(object sender, EventArgs e)      

       {      

           mCurrentFrame = mCurrentFrame + 1 >= mFrameCount ? 0 : mCurrentFrame + 1      

          lock (image)      

           {      

               image.SelectActiveFrame(frameDimension, mCurrentFrame)      

           }      

          if (OnFrameChanged != null)      

           {      

               OnFrameChanged(image, e)      

           }      

       }      

   }      

   

 

 

使用如下方法调用:

 

view plaincopy to clipboardprint?

 

using System      

using System.Collections.Generic      

using System.ComponentModel      

using System.Data      

using System.Drawing      

using System.Drawing.Imaging      

using System.Text      

using System.Windows.Forms      

     

namespace GifTest      

{      

    public partial class Form1 : Form      

     {      

         AnimateImage image      

     

        public Form1()      

         {      

             InitializeComponent()      

             image = new AnimateImage(Image.FromFile(@"C:/Documents and Settings/Administrator/My Documents/My Pictures/未命名.gif"))      

             image.OnFrameChanged += new EventHandler<EventArgs>(image_OnFrameChanged)      

             SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint, true)      

         }      

     

        void image_OnFrameChanged(object sender, EventArgs e)      

         {      

             Invalidate()      

         }      

     

        private void Form1_Load(object sender, EventArgs e)      

         {      

             image.Play()      

         }      

     

        private void Form1_Paint(object sender, PaintEventArgs e)      

         {      

            lock (image.Image)      

             {      

                 e.Graphics.DrawImage(image.Image, new Point(0, 0))      

             }      

         }      

     

        private void button1_Click(object sender, EventArgs e)      

         {      

            if (button1.Text.Equals("Stop"))      

             {      

                 image.Stop()      

                 button1.Text = "Play"      

             }      

            else     

             {      

                 image.Play()      

                 button1.Text = "Stop"      

             }      

             Invalidate()      

         }      

     

        private void button2_Click(object sender, EventArgs e)      

         {      

             image.Reset()      

             button1.Text = "Play"      

             Invalidate()      

         }      

     }      

}

树节点的图片要通过imageList 里面的图片才能获得,可以是键值,也可以是索引。我给你个例子。

稍微修改下,你就能用。你可以把Button里面代码包装成一个函数,就可以去添加了

控件就是界面的

后台代码如下:

using System

using System.Collections.Generic

using System.ComponentModel

using System.Data

using System.Diagnostics

using System.Drawing

using System.Linq

using System.Text

using System.Threading.Tasks

using System.Windows.Forms

namespace WindowsFormsApplication2

{

    public partial class Form1 : Form

    {

        public Form1()

        {

            InitializeComponent()

            this.treeView1.ImageList = imagelist

          

        }

        ImageList imagelist = new ImageList()     

        private void button1_Click(object sender, EventArgs e)

        {

            try

            {

                string filename = this.textBox1.Text.Trim()

                string key = this.textBox2.Text.Trim()

                Image im = Image.FromFile(filename)

                imagelist.Images.Add(key,im)

                string name = this.textBox3.Text.Trim()

                TreeNode tn = new TreeNode(name)

                tn.ImageKey = key

                this.treeView1.Nodes.Add(tn)

            }

            catch

            {

}

        }

        private void Form1_Load(object sender, EventArgs e)

        {

}

    }

}

         this.Controls.Add(pic)//在这句之后

         pic.Click += (this.pictureBox1_Click)

        private void pic_Click(object sender, EventArgs e)

        {

            //获取点击的pic

            PictureBox pic = sender as PictureBox

            //其他要做的事情

        }


欢迎分享,转载请注明来源:内存溢出

原文地址: https://www.outofmemory.cn/bake/11454264.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-16
下一篇 2023-05-16

发表评论

登录后才能评论

评论列表(0条)

保存