基于ffmpeg的GIF制作工具

本文介绍了如何利用ffmpeg工具结合Duilib库创建一个生成GIF动态图的应用。通过cmd调用ffmpeg执行命令,实现图片或视频转GIF,并详细讲述了Duilib库的使用,包括其组件、布局和核心操作。
摘要由CSDN通过智能技术生成

ffmpeg简介

FFmpeg即是一块音视频编解码工具,同时也是一组音视频编解码开发套件,为开发者提供了丰富的音视频处理调用接口。FFmpeg中的"FF"指的是"Fast Forward",mpeg则是动态图像专家组。 它提供了录制、转换以及流化音视频的完整解决方案。

FFmpeg由以下几部分组成:

  1. ffmpeg 视频文件转换命令行工具,也支持经过实时电视卡抓取和编码成视频文件
  2. ffserver 基于 HTTP、RTSP 用于实时广播的多媒体服务器.也支持时间平移
  3. ffplay 用 SDL 和 FFmpeg 库开发的一个简单的媒体播放器
  4. libavcodec 一个包含了所有 FFmpeg 音视频编解码器的库.为了保证最优性能和高可复用性,大多数编解码器从头开发的.
  5. libavformat 一个包含了所有的普通音视格式的解析器和产生器的库
具体实现原理

项目有两种生成gif动态图方式:
1. 使用图片生成
2. 使用短视频生成
在这里插入图片描述
实现原理:在程序中通过cmd控制台调用ffmpeg.exe工具,并给该工具发送对应的命令,完成所需操作,发命令时,cmd窗口隐藏在后台。

功能

由用户选择用图片或是视频来生成Gif。
用户在选择后输入所在目录,若是图片,直接生成动态图;若是视频,截取视频片段,提取视频裸流,直接生成Gif或提取视频字幕
【视频中的字幕必须是外挂字幕,否则使用的工具无法提取】由用户编辑文字显示在视频上最后生成Gif

本项目界面方面主要是依靠duilib界面库完成
  • Duilib库简介

Duilib 是由杭州月牙儿网络技术有限公司开发一款强大轻量级的界面开发工具,可以将用户界面和处理逻辑彻底分离,极大地提高用户界面的开发效率。提供所见即所得的开发工具UIDesigner。
Duilib主打的界面制作方式是XML+UI引擎+win32框架,通过XML的方式来重写窗口,然后Duilib对XML进行解析,将窗口创建成功。

DuiLib库的源码下载地址:https://github.com/duilib/duilib
Win32简单理解:https://www.cnblogs.com/mazhen/archive/2012/01/15/2323183.html

下载后先将duilib运行一遍,注意运行时将其设置为启动项,并且进行批生成。

Duilib库目录主要包含4个目录:
  • Control:Duilib各个控件对应的UI类,比如:按钮(CButtonUI)、编辑框(CEditUI)、下拉框(CComboBoxUI)等
  • Layout:Duilib的各种布局器所对应的UI类,比如:水平布局(CHorizontalLayoutUI)、垂直布局(CVerticalLayoutUI)等
  • Core:Duilib库的核心操作:窗口相关(Win32流程封装–CWindowWnd)、窗口解析(CMarkup)等。
  • Utils:Duilib封装的一些类型:CDUIString、CPoint、委托、压缩等

项目界面生成:需要与项目.exe相同目录下创建一xml文件,用生成的DuiDesigner_d应用程序对.xml文件进行编辑
在这里插入图片描述
在这里插入图片描述
最终生成的界面:
在这里插入图片描述
Duilib环境配置:https://www.cnblogs.com/Alberl/p/3342030.html

#include “UIlib.h”
using namespace Duilib;
Duilib创建简单的窗口
class CDuiFramWnd : public CWindowWnd 
{
   
public:
 // CWindowWnd类的纯虚函数,在该函数中必须返回用户所定义窗口的类名称,注册窗口时需要用到 
 	virtual LPCTSTR GetWindowClassName() const 
 	{
    
 		return _T("DuiFramWnd");
 	} 
 };
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) 
{
    
	CDuiFramWnd framWnd; 
	// Cashier即在窗口右上角显式的名字 
	// UI_WNDSTYLE_FRAME: duilib封装的宏,代表窗口可视,具有标题栏,最大化最小化,关闭功能等 
	// WS_EX_WINDOWEDGE: Win32的窗口风格,带有边框 
	framWnd.Create(NULL, _T("Cashier"), 
	UI_WNDSTYLE_FRAME, WS_EX_WINDOWEDGE); 
	//显示窗口,激活消息循环 
	framWnd.ShowModal(); 
	return 0; 
}

至此,一个简单的Win32窗口就创建成功

但是上述创建窗口的过程还是比较复杂,没有体现到Duilib的优势,Duilib主打的界面制作方式是XML + UI引擎 +win32框架,通过XML的方式来重写窗口,然后Duilib对XML进行解析,将窗口创建成功
下面是XML格式的Win32窗口

主函数
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int
	nCmdShow)
{
   
	//对应xml文件,因为要找到路径
	CPaintManagerUI::SetInstance(hInstance);
	// 设置资源的默认路径(和exe在同一目录)
	CPaintManagerUI::SetResourcePath(CPaintManagerUI::GetInstancePath());
	CDuiFramWnd framWnd;
	// UI_WNDSTYLE_FRAME: duilib封装的宏,代表窗口可视,具有标题栏,最大化最小化,关闭功能等
	framWnd.Create(NULL, _T("MakeGif"), UI_WNDSTYLE_FRAME, WS_EX_WINDOWEDGE);
	framWnd.CenterWindow();
	//显示窗口,激活消息循环
	framWnd.ShowModal();
	return 0;
}
窗口类

Duilib已经对常用的操作进行了很好的封装,正常使用时不需要按照上述方式实现,只需要让用户实现的窗口类继承自Duilib封装的:WindowImplBase 类即可,该类是一个duilib的基础框架类,封装了常用操作,以方便大家使用。 它是以XML作为界面描述的,所以用它的时候,我们必须将界面描述写到XML里。

class CDuiFramWnd : public WindowImplBase
各类函数
  • XML文件窗口
   //需要返回xml所在文件夹
	virtual CDuiString GetSkinFolder()
	{
   
		return _T("");//这里不用给xml文件的路径,在主函数中已经给了
	}
	//需要返回xml文件名
	virtual CDuiString GetSkinFile()
	{
   
		return _T("gifMake.xml");//一定要与目录放的xml文件文件名称相同

	}
	//需要返回窗口的类名
	virtual LPCTSTR GetWindowClassName(void)const
	{
   
		return _T("GIFMakeWnd");
	}
  • 消息处理
virtual void Notify(TNotifyUI& msg)
	{
   
		CDuiString strName = msg.pSender->GetName();//获取控件的名字
		if (msg.sType == _T("click"))//鼠标点击
		{
   
			if (strName == _T("btn_close"))//关闭按钮
			{
   
				Close();
			}
			else if (strName == _T("btn_min"))//最小化按钮
			{
   
				SendMessage(WM_SYSCOMMAND, SC_MINIMIZE, 0);
			}
			else if (strName == _T("btn_load"))
			{
   
				LoadFile();
			}
			else if (strName == _T("btn_cut"))//截取视频
			{
   
				Cutview();
			}
			else if (strName == _T("btn_get_srt"))//提取字幕
			{
   
				GetSRTFile();
				LoadSRT();
			}
			else if (strName == _T("btn_commit"))//提交
			{
   
				CEditUI* pEdit = (CEditUI*)m_PaintManager.FindControl(_T("edit_word"));
				CDuiString strWord = pEdit->GetText();//获取文本

				//将该文本写回到list中
				CListUI* pList = (CListUI*)m_PaintManager.FindControl(_T("List_srt"));
				CListTextElementUI* pListItem = 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值