因为组内测试序列制作需要,需要将制作好的BMP位图,无压缩封装为AVI视频,并附有多种要求(基准和实验序列交替出现、随机组合等)。因此,需要实现BMP到AVI的无压缩封装。

由于整个测试序列集有大概几千张图片,需要统一的命令规范。因此,无论是采用命令行还是批处理,都还是不够简洁。

早期,针对这个封装需求,尝试使用的是ffmpeg,无压缩封装。整个过程虽然较为简单,但是却出了一些BUG。

    1.FFmpeg识别RGB24格式为BGR24,且处理时由于与标准RGB的存储不一致,会导致图像颠倒。

    2.将BMP封装为AVI,原图像素会产生位移。

以下为我使用ffmpeg产生    基准——空白——试验    测试序列的批处理文件。(其中list.txt为拼接视频列表)

ffmpeg.exe -i 100.bmp -r 1 -c:v copy 1.avi
ffmpeg.exe -i 100.bmp -r 1 -c:v copy 2.avi
ffmpeg.exe -i 100.bmp -r 1 -c:v copy 3.avi
ffmpeg.exe -i 100.bmp -r 1 -c:v copy 4.avi
ffmpeg.exe -i 100.bmp -r 1 -c:v copy 5.avi
ffmpeg.exe -i gray.bmp -r 1 -c:v copy 6.avi
ffmpeg.exe -i 50.bmp -r 1 -c:v copy 7.avi
ffmpeg.exe -i 50.bmp -r 1 -c:v copy 8.avi
ffmpeg.exe -i 50.bmp -r 1 -c:v copy 9.avi
ffmpeg.exe -i 50.bmp -r 1 -c:v copy 10.avi
ffmpeg.exe -i 50.bmp -r 1 -c:v copy 11.avi
ffmpeg.exe -f concat -i list.txt -c copy output.avi
pause

直接使用ffmpeg处理的BMP图片如上。

由于是主观图像质量评价测试,因此图片不能有二次转码、压缩、额外处理操作。

此时,参考了许多解决办法。由于需要处理海量图片、命名格式又不一致,因此还是决定自己写个程序解决。

直接上代码好了……

1.简单实用了MFC框架,遍历文件夹

2.实用AVI服务,直接封装BMP图片

3.根据需要设置了1帧/秒和十张图片组成一个AVI视频的写入方法

// RandomAviOutput.cpp: 定义控制台应用程序的入口点。
//#include "stdafx.h"
#include <afx.h>
#include <atlimage.h>
#include "Vfw.h"
#include  <direct.h>
#include  <stdio.h>
#include <string>
//#include "afx.h"void ImageToAVI(CString AviPath, CString ImgPath);
void CreateAVI(CImage img, CString name, int videoWidth, int videoHeight, int bpp);
//argv[1]=输入BMP文件夹,argv[2]=输出文件名
int main(int argc, char *argv[])
{printf("input BMP DirPath %s\n", argv[1]);printf("output AVI Path %s\n", argv[2]);if (argc < 2){printf("check input argv\n");return 0;}char rootpath[MAX_PATH];_getcwd(rootpath, MAX_PATH);CString path = rootpath;CString input,output;if (argc = 3){input = argv[1];output = argv[2];}else{input = rootpath;output = rootpath;}ImageToAVI(output, input);printf("BMP to AVI All Done! \n");return 0;
}
//======================================================================================
//
// 功能 : 将目录中的BMP图像无压缩封装为AVI视频
//
//======================================================================================
void ImageToAVI(CString AviPath, CString ImgPath)
{// 初始化AVI 库AVIFileInit();CFileFind finder;CString ImgDir=ImgPath+"\\*.bmp";BOOL bFind = finder.FindFile(ImgDir);//遍历文件夹路径中所有的*.bmp文件while (bFind){bFind = finder.FindNextFile();if (!finder.IsDots() && !finder.IsDirectory())//若不为空且非文件夹{// 获取图像文件绝对路径CString str = finder.GetFilePath();CString title = finder.GetFileTitle();CString name = AviPath + "\\"+title+".avi";//拷贝bmp图片文件名作为生成avi文件名//// Open Image and get image info & data//使用CImage读取图片信息CImage img;      if (FAILED(img.Load(str))){TRACE("Warning : fail to load file %s!!!\n", str);continue;}int w, h,bpp;w = img.GetWidth();h = img.GetHeight();bpp = img.GetBPP();//img.Destroy();//释放CImage,使用FILE读写图片数据//std::string s = CT2A(str.GetBuffer(0));//FILE *fp;//fopen_s(&fp,s.c_str(), "rb");CreateAVI(img,name,w,h,bpp);//创建avi视频函数printf("BMP to AVI Done and Go Next! \n");}}AVIFileExit();}
void CreateAVI(CImage img,CString name, int videoWidth, int videoHeight, int bpp)
{//// Create AVI file//PAVIFILE pAviFile = NULL;HRESULT hr = AVIFileOpen(&pAviFile, name, OF_WRITE | OF_CREATE, NULL);if (0 != hr){return;}//// Create AVI video stream//AVISTREAMINFO strhdr;memset(&strhdr, 0, sizeof(strhdr));strhdr.fccType = streamtypeVIDEO;strhdr.fccHandler = mmioFOURCC('X', 'V', 'I', 'D');strhdr.dwScale = 1;strhdr.dwRate = 0.1;//设置帧速 1秒/帧UINT pitch = (videoWidth * bpp + 31) / 32 * 4;UINT biSizeImage = (videoWidth * bpp + 31) / 32 * 4 * videoHeight;strhdr.dwSuggestedBufferSize = biSizeImage;SetRect(&strhdr.rcFrame, 0, 0, videoWidth, videoHeight);// And create the stream;PAVISTREAM pAviStream = NULL;hr = AVIFileCreateStream(pAviFile, &pAviStream, &strhdr);if (0 != hr){AVIFileRelease(pAviFile);pAviFile = NULL;return;}//// Set stream format//BITMAPINFOHEADER bih;memset(&bih, 0, sizeof(BITMAPINFOHEADER));bih.biBitCount = bpp;bih.biClrImportant = 0;bih.biClrUsed = 0;bih.biCompression = BI_RGB;bih.biPlanes = 1;bih.biSize = 40;bih.biXPelsPerMeter = 0;bih.biYPelsPerMeter = 0;bih.biWidth = videoWidth;bih.biHeight = videoHeight;bih.biSizeImage = biSizeImage;hr = AVIStreamSetFormat(pAviStream, 0, &bih, sizeof(bih));if (0 != hr){AVIStreamClose(pAviStream);pAviStream = NULL;AVIFileRelease(pAviFile);pAviFile = NULL;}// 图像数据缓冲区BYTE * pData = new BYTE[biSizeImage];if (pData){memset(pData, 0, biSizeImage);}//// 读取图像数据,更新AVI视频帧//if (pData){for (int nFrames = 0; nFrames < 1; nFrames++)//同一图像拷贝10帧,由图像生成10秒avi视频{for (int i = 0; i < videoHeight; i++){for (int j = 0; j < videoWidth; j++){COLORREF clr = img.GetPixel(j, videoHeight - 1 - i);//(j,i)  pData[i * pitch + j * (bpp / 8) + 0] = GetBValue(clr);pData[i * pitch + j * (bpp / 8) + 1] = GetGValue(clr);pData[i * pitch + j * (bpp / 8) + 2] = GetRValue(clr);}}hr = AVIStreamWrite(pAviStream, nFrames, 1, pData, biSizeImage, AVIIF_KEYFRAME, NULL, NULL);}}if (pData != NULL){delete[] pData;pData = NULL;}if (pAviStream != NULL){AVIStreamClose(pAviStream);pAviStream = NULL;}if (pAviFile != NULL){AVIFileRelease(pAviFile);pAviFile = NULL;}
}

github:https://github.com/EthanXzhang/BmpToAvi

BMP无压缩封装为AVI视频相关推荐

  1. 关于Matlab中avi视频的读取问题

    关于Matlab中avi视频的读取问题 转自:http://wenku.baidu.com/view/a88c6a8bd4d8d15abe234e9c.html 很多学员反映matlab对一些视频利用 ...

  2. 【数据压缩】调用VFW库对无压缩avi的解封装

    一.实验原理   AVI文件格式是微软公司推出的,Windows操作系统上最常用的流媒体文件之一.AVI文件是一种最复杂的RIFF文件,现在常用的AVI文件有两种:AVI-1和AVI-2.在AVI-2 ...

  3. HDMI原理详解以及时序流程(视频是三对差分信号,音频Audio是PCM级(无压缩)传输,包含在数据包内,依靠协议规定采样)HDMI可以传输RGB与YUV两种格式

    资料来源:HDMI介绍与流程 - TaigaComplex - 博客园 最近要用ZYNQ开发版的HDMI做显示,看着硬件管脚和例程只能发呆,于是决心去弄清楚HDMI的工作原理,查找了很多资料,都是碎片 ...

  4. 标准G726音频解码和与H264视频封装为avi

    avilib库并不能直接支持G726音频的封装,源码中只支持G711A.G711U和MULAW_PCM,但查看源码可发现,avilib其实也是将G711U等音频先解码为16位linear PCM,再将 ...

  5. avi视频和bmp图像的相互转化

    为了对avi进行读写,微软提供了一套API,总共50个函数,他们的用途主要有两类,一个是avi文件的操作,一类是数据流streams的操作. 1.打开和关闭文件 AVIFileOpen ,AVIFil ...

  6. AVI视频格式分析-封装格式

    AVI视频封装格式分析 使用的工具 RIFF块 CHUNK块 LIST块 hdrl LIST avih CHUNK strl LIST strh CHUNK strf CHUNK JUNK CHUNK ...

  7. AVI视频封装格式(阅读笔记)

    文章目录 1.AVI简介(本节为抄录) 2.AVI格式示意图(本节为抄录) 3.示意图 VS 数据结构 VS 具体数据 3.1 RIFF文件头[最开始12个字节] 3.2 hdrl信息[第13-24字 ...

  8. 256色无压缩BMP文件格式

    256色的BMP文件分为 BMP文件头,BMP信息头,彩色表和位图信息矩阵4部分. BMP文件头结构; struct BITMAPFILEHEADER_ {     short type;//---- ...

  9. 使用matlab来压缩avi视频文件,版本 matlab2014a

    使用matlab来压缩avi视频文件,版本:matlab 2014a. 记录一下自己的工作 fileName = 'input.avi'; %输入的视频文件名 %读取视频函数 obj = VideoR ...

最新文章

  1. android用什么包管理器,android – 包管理器已经死了
  2. 基于深度学习的NLP 32页最新进展综述,190篇参考文献
  3. ThreadLocal 原理 以及设计思想
  4. 任务的定义、任务切换的原理及实现
  5. Codeforces 997D Cycles in Product (点分治、DP计数)
  6. 【机器学习基础】kaggle竞赛中数据抽样方式
  7. 掉电引起的ORA-1172错误解决过程(二)
  8. ASP.NET使用AJAX应注意IIS有没有.ashx扩展
  9. Leetcode-998 Maximum Binary Tree II(最大二叉树 II)
  10. jsTree如何自定义节点的icon
  11. 数据属性和访问器属性
  12. 用bbp公式计算pi_家用配电箱里设计几个回路合适?用这个公式,计算起来很方便...
  13. PLC编程软件等工具打包下载1.0【好用绿色三菱plc编程软件】
  14. 怎样搬运视频不侵权,王者剪辑的指纹检测如何检测原创度
  15. fabao_get.y
  16. 百度账号更换绑定的手机号
  17. 傻瓜式部署教程2:docker搭建oracle11g数据库
  18. 生活中的小技巧-2:洗衣机洗衣服打结缠绕,该如何解决?学上几个实用招数
  19. Win11触控板如何关闭 Win11关闭触控板的方法
  20. 穆迪分析在Chartis报告中被评为CLO解决方案类别领导者

热门文章

  1. [Android]在App中使用相机
  2. 论企业IT信息化与企业文化的关系
  3. QString中文乱码
  4. hdu 1276 士兵队列训练问题
  5. 论文查找路径 查找IEEE、ScienceDirect论文 免费查看的方法
  6. 使用QT设计师界面类创建2个界面,通过按键从界面1切换到界面2
  7. Day16-购物车页面-商品列表修改购物车商品的勾选状态
  8. Webshell免杀-JSP
  9. 字符串指针的定义、初始化与赋值
  10. 养老院管理系统(Java+Web+MySQL)