贴个代码备忘,关于avi和bmp的互相转化
代码怎么写网上都能找到,我改在console下运行
注意头文件的顺序,容易报错
这个是将avi视频拆卸成bmp一帧画面的代码,适用于24位图,8位或者其他有用到调色盘的bmp格式需要做些小修改
#pragma comment(lib, "vfw32")
#include <atlstr.h>
#include <Vfw.h>
#include<string>
#include<stdio.h>
int main()
{
std::string s1 = "C:\\Users\\asus\\Desktop\\Task\\xxx.avi";
std::string s2 = "C:\\Users\\asus\\Desktop\\Task\\picture";
CString strAVIFileName;
CString strBmpDir;
strAVIFileName.Format("%s",s1.data());
strBmpDir.Format("%s",s2.data());
AVIFileInit();
PAVIFILE avi;
int res=AVIFileOpen(&avi, strAVIFileName, OF_READ, NULL);
int n = GetLastError();
if (res!=AVIERR_OK)
{
//an error occures
if (avi!=NULL)
AVIFileRelease(avi);
return 0;
}
AVIFILEINFO avi_info;
AVIFileInfo(avi, &avi_info, sizeof(AVIFILEINFO));
PAVISTREAM pStream;
res=AVIFileGetStream(avi, &pStream, streamtypeVIDEO /*video stream*/,
0 /*first stream*/);
if (res!=AVIERR_OK)
{
if (pStream!=NULL)
AVIStreamRelease(pStream);
AVIFileExit();
return 0;
}
//do some task with the stream
int iNumFrames;
int iFirstFrame;
iFirstFrame=AVIStreamStart(pStream);
if (iFirstFrame==-1)
{
//Error getteing the frame inside the stream
if (pStream!=NULL)
AVIStreamRelease(pStream);
AVIFileExit();
return 0;
}
iNumFrames=AVIStreamLength(pStream);
if (iNumFrames==-1)
{
//Error getteing the number of frames inside the stream
if (pStream!=NULL)
AVIStreamRelease(pStream);
AVIFileExit();
return 0;
}
//getting bitmap from frame
BITMAPINFOHEADER bih;
ZeroMemory(&bih, sizeof(BITMAPINFOHEADER));
bih.biBitCount=8; //24 bit per pixel
bih.biClrImportant=0;
bih.biClrUsed = 256;
bih.biCompression = BI_RGB;
bih.biPlanes = 1;
bih.biSize = 40;
//bih.biSize=sizeof(bih);//
bih.biXPelsPerMeter = 0;
bih.biYPelsPerMeter = 0;
//calculate total size of RGBQUAD scanlines (DWORD aligned)
bih.biSizeImage = (((bih.biWidth * 3) + 3) & 0xFFFC) * bih.biHeight ;
//--
//bih.biSizeImage=(bih.biWidth*bih.biBitCount+31)/32*4*bih.biHeight*3;
//----
PGETFRAME pFrame;
pFrame=AVIStreamGetFrameOpen(pStream, NULL );
AVISTREAMINFO streaminfo;
AVIStreamInfo(pStream,&streaminfo,sizeof(AVISTREAMINFO));
//Get the first frame
BITMAPINFOHEADER bih2;
long lsize = sizeof(bih2);
int index=0;
//AVIStreamReadFormat(pStream,index,&bih2,&lsize);
for (int i=iFirstFrame; i<iNumFrames; i++)
{
index= i-iFirstFrame;
BYTE* pDIB = (BYTE*) AVIStreamGetFrame(pFrame, index); //
AVIStreamReadFormat(pStream,index,&bih2,&lsize);
BITMAPFILEHEADER stFileHdr;
RGBTRIPLE stP;
int h = bih2.biHeight;
int w = bih2.biWidth;
int bc = bih2.biBitCount;
int cm = bih2.biClrImportant;
int bcu = bih2.biClrUsed;
int com = bih2.biCompression;
int pl = bih2.biPlanes;
int s = bih2.biSize;
int si = bih2.biSizeImage;
int x = bih2.biXPelsPerMeter;
int y = bih2.biYPelsPerMeter;
//printf("h:%d w:%d bitcount:%d clrI:%d clrU:%d comp:%d planes:%d size:%d sizeImage:%d xppm:%d yppm:%d\n",h,w,bc,cm,bcu,com,pl,s,si,x,y);
BYTE* Bits=new BYTE[bih2.biSizeImage];
AVIStreamRead(pStream,index,1,Bits,bih2.biSizeImage,NULL,NULL);
//RtlMoveMemory(Bits, pDIB + sizeof(BITMAPINFOHEADER), bih2.biSizeImage);//---原来注释
bih2.biClrUsed =256;
stFileHdr.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
stFileHdr.bfSize=sizeof(BITMAPFILEHEADER);
stFileHdr.bfType=0x4d42;
CString FileName;
FileName.Format("Frame-%05dof%d.bmp", index,iNumFrames);
CString strtemp = strBmpDir;
strtemp += "//";
strtemp += FileName;
FILE* fp=_tfopen(strtemp ,_T("wb"));
fwrite(&stFileHdr,1,sizeof(BITMAPFILEHEADER),fp);
fwrite(&bih2,1,sizeof(BITMAPINFOHEADER),fp);
//fwrite(&stP,1,1024,fp); //注:每个调色盘4B,8Bit图像有256个
//--
int ff = fwrite(Bits,1,bih2.biSizeImage,fp);
int e = GetLastError();
fclose(fp);
/
delete Bits;
//CreateFromPackedDIBPointer(pDIB, index);
}
AVIStreamGetFrameClose(pFrame);
//close the stream after finishing the task
if (pStream!=NULL)
AVIStreamRelease(pStream);
AVIFileExit();
return 0;
}
这个是用bmp组装avi视频,帧速可以自己定的
#pragma comment(lib, "vfw32")
#include <afx.h>
#include <atlstr.h>
#include<string>
#include<stdio.h>
#include<string.h>
#include <Vfw.h>
void main ()
{
CString szAVIName;
CString strBmpDir;
szAVIName = "C:\\Users\\asus\\Desktop\\Task\\pic\\tt.avi";
strBmpDir = "C:\\Users\\asus\\Desktop\\Task\\picture";
CFileFind finder;
strBmpDir += _T("\\*.*");
AVIFileInit();
AVISTREAMINFO strhdr;
PAVIFILE pfile;
PAVISTREAM ps;
int nFrames =0;
HRESULT hr;
BOOL bFind = finder.FindFile(strBmpDir);
while(bFind)
{
bFind = finder.FindNextFile();
if(!finder.IsDots() && !finder.IsDirectory())
{
CString str = finder.GetFilePath();
FILE *fp = fopen(str,"rb");
BITMAPFILEHEADER bmpFileHdr;
BITMAPINFOHEADER bmpInfoHdr;
fseek( fp,0,SEEK_SET);
fread(&bmpFileHdr,sizeof(BITMAPFILEHEADER),1, fp);
fread(&bmpInfoHdr,sizeof(BITMAPINFOHEADER),1, fp);
BYTE *tmp_buf = NULL;
if(nFrames ==0 )
{
AVIFileOpen(&pfile,szAVIName,OF_WRITE | OF_CREATE,NULL);
memset(&strhdr, 0, sizeof(strhdr));
strhdr.fccType = streamtypeVIDEO;// stream type
strhdr.fccHandler = 0;
strhdr.dwScale = 1;
strhdr.dwRate = 15; // 15 fps
strhdr.dwSuggestedBufferSize = bmpInfoHdr.biSizeImage ;
SetRect(&strhdr.rcFrame, 0, 0, bmpInfoHdr.biWidth, bmpInfoHdr.biHeight);
// And create the stream;
hr = AVIFileCreateStream(pfile,&ps,&strhdr);
// hr = AVIStreamSetFormat(ps,nFrames,&bmpInfoHdr,sizeof(bmpInfoHdr));
}
tmp_buf = new BYTE[bmpInfoHdr.biWidth * bmpInfoHdr.biHeight * 3];
fread(tmp_buf, 1, bmpInfoHdr.biWidth * bmpInfoHdr.biHeight * 3, fp);
hr = AVIStreamSetFormat(ps,nFrames,&bmpInfoHdr,sizeof(bmpInfoHdr));
hr = AVIStreamWrite(ps, // stream pointer
nFrames , // time of this frame
1, // number to write
(LPBYTE) tmp_buf,
bmpInfoHdr.biSizeImage , // size of this frame
AVIIF_KEYFRAME, // flags....
NULL,
NULL);
nFrames ++;
fclose(fp);
}
}
AVIStreamClose(ps);
if(pfile != NULL)
AVIFileRelease(pfile);
AVIFileExit();
}