对于录制屏幕转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;
}
}
}
四 效果如下: