模糊测试之AVI文件分析
本次试验主要是针对AVI的处理,了解AVI的基本概念,并且掌握AVI文件常用的程序读写方法。知道AVI视频文件的帧的读取方法,以及了解BMP和AVI的基本关系。
本文作者:i春秋签约作家——天天
一 AVI的基本概念
1. 什么是AVI
AVI是音频视频交错(Audio Video Interleaved)的英文缩写,它是Microsoft公司开发的一种符合RIFF文件规范的数字音频与视频文件格式,原先用于Microsoft Video for Windows (简称VFW)环境,现在已被Windows 95/98、OS/2等多数操作系统直接支持。
2. AVI格式的优缺点
图像质量好、可跨平台使用、体积庞大、压缩标准不统一。
3. AVI的文件结构
AVI是符合RIFF文件规范的数字音频与视频文件格式,在介绍AVI文件前,我们要先来看看RIFF文件结构。AVI文件采用的是RIFF文件结构方式,RIFF(Resource Interchange File Format,资源互换文件格式)是微软公司定义的一种用于管理windows环境中多媒体数据的文件格式,波形音频wave,MIDI和数字视频AVI 都采用这种格式存储。构造RIFF文件的基本单元叫做数据块(Chunk),每个数据块包含3个部分:4字节的数据块标记(或者叫做数据块的ID)、数据块的大小、数据。整个RIFF文件可以看成一个数据块,其数据块ID为RIFF,称为RIFF块。
一个RIFF文件中只允许存在一个RIFF块。RIFF块中包含一系列的子块,其中有一种字块的ID为”LIST”,称为LIST,LIST块中可以再包含一系列的子块,但除了LIST块外的其他所有的子块都不能再包含子块。RIFF和LIST块分别比普通的数据块多一个被称为形式类型(Form Type)和列表类型(List Type)的数据域,其组成为: 4字节的数据块标记(Chunk ID)、数据块的大小、4字节的形式类型或者列表类型、数据。
下面我们看看AVI文件的结构。AVI文件是目前使用的最复杂的RIFF文件,它能同时存储同步表现的音频视频数据。AVI的RIFF块的形式类型是AVI,它包含3个子块,如下所述:
(1)信息块,一个ID为”hdrl”的LIST块,定义AVI文件的数据格式。
(2)数据块,一个ID为 “movi”的LIST块,包含AVI的音视频序列数据。
(3)索引块,ID为 “idxl”的子块,定义 “movi”LIST块的索引数据,是可选块。
AVI文件的结构如下图所示,下面将具体介绍AVI文件的各子块构造。
二.AVI与BMP的关系
一个AVI文件是由多个BMP文件构成。如下图:
AVI视频序列中的“帧”即为位图。
AVI视频序列中的“帧”的数量和位图数量是对应的。
三.分析analysis目录里AVI操作函数的写法
在此目录下运行如下:
上图的一些命令是用来合成avi的,在一下函数的调用:
cvLoadImage:从文件中读取图像 。
cvCreateVideoWriter:创建视频文件写入器 。
cvWriteFrame:写入一帧到一个视频文件中。
cvGetCaptureProperty:获得视频获取结构的属性,如视频序列的帧数等。
cvCaptureFromFile 为从文件中读取而打开文件
cvQueryFrame从摄像头或者文件中抓取并返回一帧
可以很方便的把BMP合成AVI。一下是合成的过程:
最终可以打开结果看一下:
四.OpenCV 及MFC实现AVI的合成和分解
1. 创建一个MFC对话框应用程序(Dialog-based Application),在名称栏输入创建项目的名称,点击“确定”。
2. 在出现的“MFC应用程序向导”对话框内,选择“基于对话框”,并取消“使用Unicode库(N)”其他选项不做修改,单击“下一步”如下图:
3. 一直点击“下一步”到“生成的类”对话框,选择基类为“CDialog”单击完成即可创建一个MFC对话框。如下图:
4. 删除“TODO:在此放置对话框控件。”、“确定”和“取消”控件。然后点击“工具”中的“Button”添加以下五个控件并改名。结果如下下图:
5. 接着点击属性栏中的“控制事件“按钮 ,弹出如下对话框:
选择分别添加OnBnClickedButton1()•••OnBnClickedButton5()
6. 在工具箱中点击在图中添加后如下图:
7. 在工具箱中点击“Group Box” ,从左上角往右下角拖拉到 “开始分解”止,同时修改其属性栏里的 的“静态”为“AVI的合成”,完成后如图:
同理可得完成下一部分:
8. 依次右击“示例编辑框”按钮分别添加变量,如图:
变量名分别为m_1, m_2, m_3, m_4。
9. 在“解决方案资源管理器下”打开“BY_MFC_YJCDlg.h”,在“#pragma one”下面添加:
#include “cv.h”
#include “highgui.h”
#include “cxcore.h”
#include <stdio.h>
#include “shlwapi.h”
#include <direct.h>
#include <io.h>
#include <vector>
using namespace std;
#define UM_PROGRESS WM_USER+1
10. 在最后的“}”内添加:
afx_msg LRESULT Onrogress(WPARAM, LPARAM);
public:
char* choisebmppath(HWND hWnd,CHAR *szTitle, CHAR *szPath);
public:
int bmptoavi();
public:
afx_msg void OnBnClickedButton10();
void GetFile(CString sPath, vector<CString> *filePaths);
CString getFileExt(CString filePath);
BOOL __cdecl isSameType (char *Ext,const char *format, …);
11. 打开源文件“BY_MFC_YJCDlg.cpp”,在“#ifdef_DEBUG”上添加:
#include <stdlib.h>
在 “#endif”下添加:
CString bmp_path1;
CString bmp_path;//bmp路径(hecheng)
CString AviFileName;//AVIL路径
CString AVI_path;
int i = 1;
//int bmptoavi(LPVOID lpParameter);//shengming
CEdit dlg;
12. 在“END_MESSAGE-MAP()”的上面和
下面添加:
ON_MESSAGE(UM_PROGRESS,Onrogress)
13. 在下面添加:
char* COPENCV_AVI_BMPDlg::choisebmppath(HWND hWnd,CHAR *szTitle, CHAR *szPath)//获得文件夹
{
BROWSEINFO bi;
LPCITEMIDLIST pItemIDList;
bi.hwndOwner = AfxGetMainWnd()->GetSafeHwnd();
bi.pidlRoot = NULL;
bi.pszDisplayName = szPath;
bi.lpszTitle = szTitle;
bi.ulFlags = BIF_RETURNONLYFSDIRS;
bi.lpfn = NULL;
bi.iImage = 0;
pItemIDList = SHBrowseForFolder(&bi);
if(NULL == SHGetPathFromIDList(pItemIDList, szPath) )
{
AfxMessageBox(“路径为获取“);
}
return (char*)szPath;
}
14. 在OnBnClickedButton2()下添加:
if (0 == m_1.GetWindowTextLength())
{
AfxMessageBox(“please CHOISE bmp_filename!”);
exit(1);
}
if (0 == m_1.GetWindowTextLength())
{
AfxMessageBox(“please INPUT bmp_filename!”);
exit(1);
}
//AfxBeginThread((AFX_THREADPROC)bmptoavi, (void*)this);
PostMessage(UM_PROGRESS);
bmptoavi();
}
int COPENCV_AVI_BMPDlg::bmptoavi()
{
CString FileName;
CvVideoWriter *writer;
IplImage *frame;
vector<CString> imgFilePaths;
GetDlgItemText(IDC_EDIT1,bmp_path);//BMP的文件路径
GetFile(bmp_path, &imgFilePaths);
for (int i=0 ;i< imgFilePaths.size();++i)
{
frame = cvLoadImage(imgFilePaths.at(i).GetBuffer());
if(i == 0)
{
int AviForamt = -1;//设置压缩格式
int FPS = 25;
int AviColor = 1;
writer=cvCreateVideoWriter(AviFileName,-1,FPS,cvGetSize(frame),AviColor);
}
cvWriteFrame(writer,frame);
cvWaitKey(1);
cvReleaseImage(&frame);
}
cvReleaseVideoWriter(&writer);
return 0;
}
/*
* 功能:获取文件夹下的所有图片文件
*/
void COPENCV_AVI_BMPDlg::GetFile(CString sPath, vector<CString> *filePaths)
{
if (sPath.IsEmpty())
{
return;
}
CFileFind ff;
CString szDir = sPath;
CString Ext;
if(szDir.Right(1) != “\\”)
szDir += “\\”;
szDir += “*.*”;
BOOL res = ff.FindFile(szDir);
while( res )
{
res = ff.FindNextFile();
CString sFileName;
if (ff.IsDirectory() && !ff.IsDots())//文件夹
{
CString sFilePath = ff.GetFilePath();
sFileName = ff.GetFileTitle();
GetFile(sFilePath, filePaths);
}
else if (!ff.IsDirectory() && !ff.IsDots())//文件
{
CString strFilePath = ff.GetFilePath();
Ext = getFileExt(ff.GetFilePath());
if (isSameType(Ext.GetBuffer(),“ss”,“bmp”,“jpg”))
{
filePaths->push_back(strFilePath);
}
}
}
ff.Close();
}
CString COPENCV_AVI_BMPDlg::getFileExt(CString filePath)
{
filePath.ReleaseBuffer();
int pos = filePath.ReverseFind(‘.’);
if (pos >= 0)
{
return filePath.Right(filePath.GetLength() – pos -1);
}
}
BOOL __cdecl COPENCV_AVI_BMPDlg::isSameType (char *Ext,const char *format, …)
{
va_list ap;
int buffing;
int retval;
char ch;
char *ext;
va_start(ap, format);
_ASSERTE(format != NULL);
ext = strlwr(Ext);
while(ch = *(format++))
{
switch(ch)
{
case ‘s’:
{
char *p = va_arg(ap, char *);
if (0 == strcmp(Ext,p))
{
return 1;
}
break;
}
default:
{
printf(“input parameter is error \n”);
return -1;
}
break;
}
}
return(0);
15. 在OnBnClickedButton1()下添加:
char path[MAX_PATH];
choisebmppath(m_hWnd,“bmp文件夹“,path);
bmp_path = path;
SetDlgItemText(IDC_EDIT1,bmp_path);
AviFileName = “E:\\avi.avi”;
SetDlgItemText(IDC_EDIT2,“E:\\avi.avi”);
16. 在OnBnClickedButton3()下添加:
CFileDialog dlg(true,NULL,NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,NULL,NULL,0);
if(!dlg.DoModal())
{
AfxMessageBox(“创建失败“);
exit(1);
}
AVI_path = dlg.GetPathName();
SetDlgItemText(IDC_EDIT3,AVI_path);
}
LRESULT COPENCV_AVI_BMPDlg::Onrogress(WPARAM, LPARAM)
{
pgctrl.OffsetPos(2);
pgctrl.SetStep(1);//设置步长
pgctrl.SetRange32(1,1000);
pgctrl.SetPos(i);
pgctrl.SetBkColor(RGB(255, 0, 0));
pgctrl.StepIt();//让进度条动起来
return 1;
17. 在OnBnClickedButton4()下添加:
if (m_3.GetWindowTextLength() == 0)
{
AfxMessageBox(“AVI文件出错“);
exit(1);
}
CvCapture *capture;
IplImage *frame;
capture = cvCaptureFromAVI(AVI_path);
CString FileName;
CString strtemp;
CString newFileName;
int i=1;
UpdateData(FALSE);
for (i = 1;i<101;i++)
{
FileName.Format(“Frame-%03d.bmp”, i);
if (i==1)
{
GetDlgItemText(IDC_EDIT4,strtemp);
}
newFileName = strtemp + FileName;
frame = cvQueryFrame(capture);
if (!cvSaveImage( newFileName,frame))
{
AfxMessageBox(“提取失败“);
}
cvWaitKey(1);
}
}
18. 然后修改相应位置的所有“COPENCV-AVI-BMPDlg”为“C(工程名)Dlg”。并且在“项目属性”的“附加依赖项”添加 “cv.lib highgui.lib cvaux.lib cxcore.lib”运行 得:
五.实验心得与总结
本次试验主要是针对AVI的处理,了解AVI的基本概念,并且掌握AVI文件常用的程序读写方法。
知道AVI视频文件的帧的读取方法,以及了解BMP和AVI的基本关系。
由于试验目的需要对一些代码的理解,对C++有更深度的认识,建议各位同学多看一些有关C++的内容。以更深一步的理解Opencv的机制与功能,将Opencv透彻的系统学习,加深对其的理解。
模糊测试之AVI文件分析的更多相关文章
- windows XP系统内核文件分析(全)
Windows XP个别 System32 文件 System32 文件夹下个别要移除的文件 我们就要删除另外600 个 system32 文件...我们要一次把它们全都解决掉. 以下是我所删除的 S ...
- 富文本存储型XSS的模糊测试之道
富文本存储型XSS的模糊测试之道 凭借黑吧安全网漏洞报告平台的公开案例数据,我们足以管中窥豹,跨站脚本漏洞(Cross-site Script)仍是不少企业在业务安全风险排查和修复过程中需要对抗的“大 ...
- RPM 打包技术与典型 SPEC 文件分析
一 .rpm 介绍 1. 概述 RPM全称是 Red Hat Package Manager(Red Hat包管理器).几乎所有的 Linux 发行版本都使用这种形式的软件包管理安装.更新和卸载软件. ...
- linux实践之ELF文件分析
linux实践之ELF文件分析 下面开始elf文件的分析. 我们首先编写一个简单的C代码. 编译链接生成可执行文件. 首先,查看scn15elf.o文件的详细信息. 以16进制形式查看scn15elf ...
- 蓝屏 Dump文件分析方法
WinDbg使用有点麻烦,还要符号表什么的.试了下,感觉显示很乱,分析的也不够全面... 试试其他的吧!今天电脑蓝屏了,就使用其dump文件测试,如下: 1.首先,最详细的,要属Osr Online这 ...
- avi文件打开出现花屏、打开不了问题
以avi为后缀名文件,其编码格式并不是单一的,而是多种格式都可以以avi作为后缀. AVI(Audio Video Interleaved的缩写)是一种RIFF(Resource Interchang ...
- (转)AVI文件格式解析+AVI文件解析工具
AVI文件解析工具下载地址:http://download.csdn.net/detail/zjq634359531/7556659 AVI(Audio Video Interleaved的缩写)是一 ...
- KEIL MDK输出map文件分析
一.文件分析流程 1.第一部分:Section Cross References 主要是各个源文件生成的模块之间相互引用的关系. stm32f10x.o(STACK) refers (Special) ...
- 转:电子取证中AVI文件的文件雕复
电子取证中AVI文件的文件雕复 收藏本文 分享 1引言在电子取证工作中,恢复数字设备中被删除的数据是极为重要的工作之一,恢复数据又分依赖系统元信息的传统数据恢复技术和不依赖系统元信息的文件雕刻.文件雕 ...
随机推荐
- Python 函数装饰器简明教程
定义类的静态方法时,就使用了装饰器.其实面向对象中的静态方法都是使用了装饰器. @staticmethod def jump(): print(" 3 meters high") ...
- 什么是Jenkins 以及如何使用?
Jenkins是什么? Jenkins是一个功能强大的应用程序,允许持续集成和持续交付项目,无论用的是什么平台.这是一个免费的源代码,可以处理任何类型的构建或持续集成.集成Jenkins可以用于一些测 ...
- centos 安装或更新最新版本软件包(git python etc)的方法 SCL IUS
使用centos 经常发现官方提供的软件包版本过低,很多时候大家会选择下载源码自行编译,带来了很多麻烦. centos安装最新版本软件包,例如git,python等,可以通过红帽官方提供的softwa ...
- php连接mssql
首先修改php.ini,将下行的前的分号去掉. extension=php_mssql.dll 由于本机没有安装客户端,所以要将ntwdblib.dll复制到C:\WINDOWS\system32目录 ...
- 【Win】编写简单的bat文件
bat是dos下的批处理文件.批处理文件是无格式的文本文件,它包含一条或多条命令.它的文件扩展名为 .bat 或 .cmd.在命令提示下键入批处理文件的名称,或者双击该批处理文件,系统就会调用Cmd. ...
- 二进制搭建kubernetes多master集群【四、配置k8s node】
上一篇我们部署了kubernetes的master集群,参考:二进制搭建kubernetes多master集群[三.配置k8s master及高可用] 本文在以下主机上操作部署k8s node k8s ...
- IntelliJ IDEA 2017版 spring-boot使用JdbcTemplate实例
搭建总框架: (1)在pom.xml加入jdbcTemplate的依赖: (2)编写Dao类,声明为:@Repository,引入JdbcTemplate (3)编写Service类,引入Dao进行使 ...
- Linux Bash命令总结
Bash命令 一:man命令,是manual 手册的意思,如man ps表示查看ps命令的手册,man man查看man命令的手册:也可以通过man xx查看是否有xx命令. 二:cat命令,用来一次 ...
- UltraEdit配置
1.如何在vivado中调用UltraEdit 1.语法高亮 支持不同的编程语言,但是要添加相就的文件,这样不同语言的关键字就可以高亮显示. 在高级-> 配置 –> 语法高亮,选择文档 2 ...
- 新浪微博mid和url的互算
我们在使用新浪微博API时,有时需要得到一个微博的url,但是如statuses/public_timeline等接口中取得的微博status的字段中并没有包含.不过,status中包含了一个mid字 ...