屏幕录制并转gif(C#)

对于录制屏幕转gif图片,网上看到的都是使用人家公司写好的api,看不到源码,而且收费,翻了好久,没有找到很好的思路,然后自己瞎搞了两天,做了一个,效果不是很好,仅供参考,由于水平有限,请多多指教

 

好了,进入正题

 

操作前:最好先参考一下我前面写的两篇文章

1  Winform控件镂空、窗体本身镂空和鼠标击穿(录屏会用到):   https://blog.csdn.net/zxy13826134783/article/details/103097204

2  C# 实现多张图片合成一张gif(录屏可能会用到) : https://blog.csdn.net/zxy13826134783/article/details/103100369

 

步骤:

一   下载Gif.Components.dll,这个作用是Image转gif,下载地址:https://pan.baidu.com/s/1INUkPqci-UUAI2wm994PsQ 
提取码:4pwa 

 

二  新建一个winfomr项目,并引用Gif.Components.dll,界面布局如下:

 

三  编写代码如下:

using Gif.Components;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace 屏幕录制
{
    public partial class FrmRecord : Form
    {
        private const uint WS_EX_LAYERED = 0x80000;
        private const int GWL_EXSTYLE = -20;
        private const int LWA_COLORKEY = 1;

       

        [DllImport("user32", EntryPoint = "SetLayeredWindowAttributes")]
        private static extern int SetLayeredWindowAttributes(IntPtr hwnd, int crKey, int bAlpha, int dwFlags);
        public FrmRecord()
        {
            InitializeComponent();
            this.TopMost = true;
            
           
            SetLayeredWindowAttributes(this.panel2.Handle,0, 0, LWA_COLORKEY);
            

            
            //设置进度条基础属性
            this.progressBar1.Value = 0;
            this.progressBar1.Style = ProgressBarStyle.Blocks;
            this.progressBar1.Minimum = 0;
            this.progressBar1.MarqueeAnimationSpeed = 100;
            this.progressBar1.Step = 1;

            // 界面中控件的控制
            UIEnable(true, false, false);
            
        }


        Rectangle tScreenRect;
        private  Bitmap GetScreenCapture()
        {
            
            Bitmap tSrcBmp = new Bitmap(tScreenRect.Width, tScreenRect.Height); // 用于屏幕原始图片保存
            Graphics gp = Graphics.FromImage(tSrcBmp);
            gp.CopyFromScreen(PositionX, PositionY, 0, 0, tScreenRect.Size);

            gp.DrawImage(tSrcBmp, PositionX, PositionY, tScreenRect, GraphicsUnit.Pixel);
            return tSrcBmp;
        }



        AnimatedGifEncoder el = new AnimatedGifEncoder();

        private void Start(int time,string gifPath) {
            el.SetDelay(time);
            //0:循环播放    -1:不循环播放
            el.SetRepeat(0);
            el.Start(gifPath);
        }
        int PositionX;
        int PositionY;
        private void btnStart_Click(object sender, EventArgs e)
        {
            
            PositionX = this.Location.X + 6;
            PositionY = this.Location.Y + 30;

            int Width = this.panel2.Size.Width;
            int Height = this.panel2.Size.Height;
            tScreenRect = new Rectangle(PositionX, PositionY, Width, Height);

           


            //打开用户设置保存路径的对话框
            string fileName=ShowSaveFileDialog();
            if (fileName.Length == 0)
            {
                MessageBox.Show("请输入保存的文件名","保存提示",MessageBoxButtons.OK,MessageBoxIcon.Error);
                return;
            }
            Start(300, fileName);

            this.timer1.Start();
            Thread thread = new Thread(GifManager.Instance.SaveBif);
            thread.IsBackground = true;
            thread.Start();
            // 界面中控件的控制
            UIEnable(false,true, false);
            
        }


        /// <summary>
        /// 弹出选择保存路径的对话框,让用户设置保存的路径
        /// </summary>
        /// <returns></returns>
        private string ShowSaveFileDialog()
        {
            string localFilePath = "";
            //string localFilePath, fileNameExt, newFileName, FilePath; 
            SaveFileDialog sfd = new SaveFileDialog();
            //设置文件类型 
            sfd.Filter = "gif格式(*.gif)|*.gif";

            //设置默认文件类型显示顺序 
            sfd.FilterIndex = 1;

            //保存对话框是否记忆上次打开的目录 
            sfd.RestoreDirectory = true;

            //点了保存按钮进入 
            if (sfd.ShowDialog() == DialogResult.OK)
            {
                localFilePath = sfd.FileName.ToString(); //获得文件路径 
            }

            return localFilePath;
        }

        
        /// <summary>
        /// 定时器1事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void timer1_Tick(object sender, EventArgs e)
        {
            Bitmap bitMap = GetScreenCapture();

            GifManager.Instance.AddBitMap(el, bitMap);
        }


        //保存进度条的最大值
        int ProcessMaxValue = 0;
        private void btnEnd_Click(object sender, EventArgs e)
        {
            this.timer1.Stop();
            GifManager.Instance.IsStop = true;
            ProcessMaxValue = GifManager.Instance.GetProcess();
            this.progressBar1.Maximum = ProcessMaxValue;
            this.progressBar1.Value =0;
            this.timer2.Start();
        }


        /// <summary>
        /// 定时器2事件,用来给显示保存的进度
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void timer2_Tick(object sender, EventArgs e)
        {
            this.progressBar1.Value =ProcessMaxValue- GifManager.Instance.GetProcess();
            // 界面中控件的控制
            UIEnable(false,false,true);
            //已经加载完毕
            if (ProcessMaxValue == this.progressBar1.Value)
            {
                DataReSet();
                
            }
        }

        /// <summary>
        /// 数据重新设置
        /// </summary>
        private void DataReSet() {
            this.timer2.Stop();
            this.progressBar1.Value = 0;
            ProcessMaxValue = 0;
            GifManager.Instance = new GifManager();
            el = new AnimatedGifEncoder();
            // 界面中控件的控制
            UIEnable(true, false, false);
        }

        /// <summary>
        /// 界面中控件的控制
        /// </summary>
        /// <param name="btnSave"></param>
        /// <param name="btnStop"></param>
        /// <param name="progress"></param>
        private void UIEnable(bool btnSave,bool btnStop,bool progress) {
            this.btnStart.Enabled = btnSave;
            this.btnEnd.Enabled = btnStop;
            this.label1.Visible = progress;
            this.progressBar1.Visible = progress;
        }
        
    }



    class GifManager {
        public static GifManager Instance=new GifManager();
        public bool IsStop = false;
        Stack<Bitmap> stack = new Stack<Bitmap>();
        AnimatedGifEncoder el=null;
 
        /// <summary>
        /// 把截屏的图片保存到队列中
        /// </summary>
        /// <param name="gifEncoder"></param>
        /// <param name="bitMap"></param>
        public void AddBitMap(AnimatedGifEncoder gifEncoder,Bitmap bitMap)
        {
            if (this.el == null)
            {
                this.el = gifEncoder;
            }
            stack.Push(bitMap);
        }

        /// <summary>
        /// 保存图片到gif
        /// </summary>
        public void SaveBif() {
            while (!IsStop||stack.Count>0)
            {
                if (stack.Count > 0)
                {
                    Bitmap bitMap = stack.Pop();
                    this.el.AddFrame(bitMap);
                }
            }
            //当队列中没有了图片,就停止保存
            EndSave();
        }

        /// <summary>
        /// 保存完毕
        /// </summary>
        private void EndSave() {
            el.Finish();
        }

        /// <summary>
        /// 获取进度值
        /// </summary>
        /// <returns></returns>
        public int GetProcess() {
            return stack.Count;
        }

    }
}

 

 

四  效果如下:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zxy2847225301

测试使用

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值