C# gif截取

很多时候下载了gif动画,但只想截取其中的的一部分(包括画面的一部分或者部分帧),于是做了个软件完成这部分功能。

1.软件布局

点击“截取”按钮则跳出保持对话框,“调整”按钮可进行GIF速度与分辨率调整,点选1:1会限制截取框的比例,开始与结束为需要保存的帧范围。


2.代码

需要引入Gif.Components.dll,网上可以下载这个dll
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Imaging;
using System.IO;
using Gif.Components;  

namespace GIF截取
{
    public partial class FormGIF : Form
    {
        
        private Point startPoint = new Point();
        private Rectangle cutRect  ;
        private bool startDraw = false;
        private Image srcImg;
        FrameDimension fd = null;
        int FrameCount=0, nowFrameCount=0;
        String  FilePath;
        public FormGIF()
        {
            InitializeComponent();
        }
        private bool picbox_loadpic(Image img)
        {
            cutRect.Width = 0; cutRect.Height = 0;
            fd = new FrameDimension(img.FrameDimensionsList[0]);
            FrameCount = img.GetFrameCount(fd);
            num_start.Maximum = FrameCount;
            num_end.Maximum = FrameCount  ;
            num_start.Value = num_start.Minimum;
            num_end.Value = num_end.Maximum;
            label_cnt.Text = "帧数:"+FrameCount.ToString();
           
            pictureBox_Main.Cursor = Cursors.Cross;
            pictureBox_Main.Size = new System.Drawing.Size(img.Width, img.Height);
            this.ClientSize = new System.Drawing.Size(pictureBox_Main.Right + 8, pictureBox_Main.Bottom+8);
            Bitmap g_tempMainbmp = new Bitmap(img );   //清空缓存
            //Graphics g = Graphics.FromImage(g_tempMainbmp);
            //g.DrawImage(img, new Rectangle(0, 0, pictureBox_Main.Width, pictureBox_Main.Height), new Rectangle(0, 0, pictureBox_Main.Width, pictureBox_Main.Height), GraphicsUnit.Pixel);
            pictureBox_Main.Image = g_tempMainbmp;      //加载图片
            //g.Dispose();
            return true;
        }
        private void btn_open_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();//实例化文件打开对话框
            ofd.Filter = "GIF|*.gif"; //设置对话框打开文件的括展名
            if ( ofd.ShowDialog() == DialogResult.OK )
            {
                try
                {
                    srcImg = Image.FromStream(new MemoryStream(File.ReadAllBytes(ofd.FileName)));
                    picbox_loadpic(srcImg);
                    FilePath = ofd.FileName;
                }
                catch
                {
                    MessageBox.Show("文件不能识别","tip");
                }
            }
        }

        private void btn_cut_Click(object sender, EventArgs e)
        {
            if (fd != null && cutRect.Width!=0 )
            {

                SaveFileDialog sfd = new SaveFileDialog();
                sfd.Filter = "GIF|*.gif";
                sfd.DefaultExt = ".gif";
                if ( sfd.ShowDialog() == System.Windows.Forms.DialogResult.OK )
                {
                label_cnt.Text = "转换...";
                label_cnt.Refresh();
                AnimatedGifEncoder en = new AnimatedGifEncoder();
                string ph = //Path.GetFullPath(FilePath) + "x.GIF";
                sfd.FileName;
                try
                {
                    PropertyItem invtime = srcImg.GetPropertyItem(0x5100);
                    int delay = invtime.Value[0] + invtime.Value[1] * 256 + invtime.Value[2] * 256 * 256 + invtime.Value[3] * 256 * 256 * 256;
                    en.Start(ph);
                    en.SetRepeat(0);  //-1:不循环,0:总是循环 播放  
                    en.SetDelay(delay);    // 延迟间隔
                    int start = 0, end = FrameCount-1;
                    if (checkBox_enbleframe.Checked)
                    {
                        int swap=0;
                        start = (int)num_start.Value - 1;
                        end = (int)num_end.Value - 1;
                        if (start > end) { swap = start; start = end; end = swap; }
                    }
                    for (int i = start; i <= end; i++)
                    {
                        srcImg.SelectActiveFrame(fd, i);
                        Bitmap bmp = new System.Drawing.Bitmap(srcImg);
                        Bitmap tbmp = new Bitmap(cutRect.Width, cutRect.Height);
                        Graphics g = Graphics.FromImage(tbmp);
                        g.DrawImage(bmp, new Rectangle(0, 0, cutRect.Width, cutRect.Height), cutRect, GraphicsUnit.Pixel);
                        //Image img = tbmp;
                        en.AddFrame(tbmp);
                        g.Dispose();
                    }
                }
                catch
                {
                    MessageBox.Show("不是GIF");
                }
                en.Finish();
                label_cnt.Text = "OK";
                }
            }
        }
        //将点限制在S内
        void limitPoint(ref Point p , Size s)
        {
            if (p.X < 0) p.X = 0; if (p.Y < 0) p.Y = 0;
            if (p.X >= s.Width) p.X = s.Width - 1; if (p.Y >= s.Height) p.Y = s.Height - 1;
        }

        private void pictureBox_Main_MouseDown(object sender, MouseEventArgs e)
        {
            startDraw = true;
            startPoint = e.Location;
        }

        private void pictureBox_Main_MouseMove(object sender, MouseEventArgs e)
        {
            if (startDraw && pictureBox_Main.Image !=null)
            {
                Bitmap   scratchImg = new Bitmap(pictureBox_Main.Width, pictureBox_Main.Height);
                Graphics gg = Graphics.FromImage(scratchImg);

                int width = 0;
                int heigth = 0;
                Point rectStartPoint = startPoint;
                Point nowPointX = e.Location;
                limitPoint(ref  nowPointX, pictureBox_Main.Size );
                {//画矩形
                    width = Math.Abs(nowPointX.X - startPoint.X); //确定矩形的宽
                    heigth = Math.Abs(nowPointX.Y - startPoint.Y);//确定矩形的高

                    if (checkBox_ratio.Checked)     //  1:1限制
                    {
                        if (width > heigth) width = heigth;
                        if (nowPointX.X < rectStartPoint.X)
                        {
                            if (nowPointX.Y < rectStartPoint.Y)
                            {
                                cutRect = new Rectangle(rectStartPoint.X -  width, rectStartPoint.Y - width, width, width); 
                            }
                            else 
                            {
                                cutRect = new Rectangle(rectStartPoint.X - width, rectStartPoint.Y, width, width);
                            }
                        }
                        else 
                        {
                            if (nowPointX.Y < rectStartPoint.Y)
                            {
                                cutRect = new Rectangle(rectStartPoint.X, rectStartPoint.Y - width, width, width);
                            }
                            else
                            {
                                cutRect = new Rectangle(rectStartPoint.X, rectStartPoint.Y  , width, width); 
                            }
                        }
                         
                    }
                    else  
                    {
                        if (nowPointX.X < startPoint.X)
                        {
                            rectStartPoint.X = nowPointX.X;
                        }
                        if (nowPointX.Y < startPoint.Y)
                        {
                            rectStartPoint.Y = nowPointX.Y;
                        }
                        cutRect = new Rectangle(rectStartPoint.X, rectStartPoint.Y, width, heigth);
                    }
                   
                    Pen dpen = new Pen(Color.Blue,1);
                    dpen.DashStyle = System.Drawing.Drawing2D.DashStyle.Custom;
                    dpen.DashPattern = new float[] {5,5};
                    gg.DrawRectangle(Pens.Red, cutRect);
                    gg.DrawRectangle(dpen, cutRect);
                }
                gg.Dispose();
                pictureBox_Main.Refresh();  // 这个位置很关键,不能放在最后
                
                Graphics gp = pictureBox_Main.CreateGraphics();
                gp.DrawImage(scratchImg, 0, 0);
                gp.Dispose();
            }
        }

        private void pictureBox_Main_MouseUp(object sender, MouseEventArgs e)
        {
            if (startDraw)
            {
                startDraw = false;
            }
        }

        private void btn_next_Click(object sender, EventArgs e)
        {
            if (fd != null)
            {
                nowFrameCount++;
                if (nowFrameCount >= FrameCount) nowFrameCount = 0;
                srcImg.SelectActiveFrame(fd, nowFrameCount);
                btn_next.Text = "下一帧:" + ( (nowFrameCount+1) % (FrameCount+1) ).ToString();
                
                Bitmap bmp = new System.Drawing.Bitmap(srcImg);
                pictureBox_Main.Image = bmp;
            }
        }

        private void btn_run_Click(object sender, EventArgs e)
        {
            if (srcImg != null)
            {
                if (btn_run.Text == "播放")
                {
                    btn_run.Text = "停止";
                    btn_cut.Enabled = false;
                    pictureBox_Main.Image = srcImg;
                }
                else
                {
                    btn_run.Text = "播放";
                    btn_cut.Enabled = true;
                    
                    Bitmap bmp = new System.Drawing.Bitmap(srcImg);
                    pictureBox_Main.Image = bmp;
                }
            }
        }

        private void gifSet(int w, int h, int v)
        {
            if (  w * h > 0)
            {
                SaveFileDialog sfd = new SaveFileDialog();
                sfd.Filter = "GIF|*.gif";
                sfd.DefaultExt = ".gif";
                if (sfd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    label_cnt.Text = "压缩...";
                    label_cnt.Refresh();
                    AnimatedGifEncoder en = new AnimatedGifEncoder();
                    string ph = //Path.GetFullPath(FilePath) + "x.GIF";
                    sfd.FileName;
                    try
                    {
                        PropertyItem invtime = srcImg.GetPropertyItem(0x5100);
                        int delay = invtime.Value[0] + invtime.Value[1] * 256 + invtime.Value[2] * 256 * 256 + invtime.Value[3] * 256 * 256 * 256;
                        en.Start(ph);
                        en.SetRepeat(0);  //-1:不循环,0:总是循环 播放  
                        if (v == 5) 
                        { }
                        else {
                            double x = v / 5.0;
                            delay = delay * (int)x;
                        }
                        en.SetDelay(delay*10);    // 延迟间隔

                        int start = 0, end = FrameCount - 1;
                        if (checkBox_enbleframe.Checked)
                        {
                            int swap = 0;
                            start = (int)num_start.Value - 1;
                            end = (int)num_end.Value - 1;
                            if (start > end) { swap = start; start = end; end = swap; }
                        }

                        for (int i = start; i <= end; i++)
                        {
                            srcImg.SelectActiveFrame(fd, i);
                            Bitmap bmp = new System.Drawing.Bitmap(srcImg);
                            Bitmap tbmp = new Bitmap(w, h);
                            Graphics g = Graphics.FromImage(tbmp);
                            g.DrawImage(bmp,0,0 ,w , h );

                            en.AddFrame(tbmp);
                            g.Dispose();
                        }
                    }
                    catch
                    {
                        MessageBox.Show("不是GIF");
                    }
                    en.Finish();
                    label_cnt.Text = "OK";
                }
            }
        }
        private void btn_rar_Click(object sender, EventArgs e)
        {
            if (fd != null)
            {
                FormResolution fr = new FormResolution();
                if (fr.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    int v = fr.time;
                    int w = fr.w;
                    int h = fr.h;
                    fr.Dispose();
                    gifSet(w, h, v);
                }
            }
        }
        private void pictureBox_Main_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (fd != null)
            {
                PropertyItem invtime = srcImg.GetPropertyItem(0x5100);
                MessageBox.Show("ID:"+invtime.Id.ToString() + "\r\ntime:" + invtime.Value[0].ToString() + "," + invtime.Value[1].ToString() + "," + invtime.Value[2].ToString() + "," + invtime.Value[3].ToString());
            }
        }
    }
}

3.效果

选择一幅GIF,鼠标选取需要的部分,点击截取按钮,就可以保存下来了。

可设置分辨率,速度


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值