多幅图片生成avi

时间:2023-02-04 06:07:55
最近遇到问题不知如何调试,还请高手帮忙,指点迷津。

我之前写了一个把bmp文件(320.*240)合成avi的程序,可以运行。调试过程中出了乱码,后来发现是合成avi的时候没有把颜色表给写进avi。

后来,我自己生成了一堆bmp文件(129*129),结果用之前的合成avi程序跑,又出来了乱码。我怀疑还是数据写的时候出错了。但不知道是哪里错。写入图片的函数是从一本书上copy下来的,图片也能生成。

还请高手指点一下可能出错的地方。谢谢~

9 个解决方案

#1


不贴代码怎么知道

#2


学习一下

#3


看不到??????

#4


以前整过这样的,只是当时图片切换的时候时间调的不好,出来的AVI不流畅,呵呵,不知道楼主是如何整的,看不到代码

#5


不如用现成的工具,呵呵。
FFMPEG内核,很好使。。。

#6


试试OpenCV中的FFMPEG相关封装好的函数呢?

#7


不好意思啊~ 各位,这几天正好在回学校的途中,所以不能发上程序。

#8



//生成图片的代码
void CBmp_aviDlg::ImageShow(unsigned char *data, int Width, int Height, CString PathName)
{
if (!data)
{
return ;
}
unsigned char *Mydata;
//颜色表,设定为灰度图像
int colorTablesize=1024;
int widthStep=(Width+3)/4*4;
//将数据重新排列成符合bmp规则的方式
Mydata=new unsigned char[widthStep*Height];
for (int i=0;i<Height;i++)
{
for (int j=0;j<Width;j++)
{
*(Mydata+i*widthStep+j)=*(data+i*Width+j);
}
}
RGBQUAD pColorTable[256];
//open a file to write bmp data
FILE *fp=fopen(PathName,"wb");
if (0==fp)
{
return;
}
//申请位图文件头信息,填写文件头信息
BITMAPFILEHEADER fileHead;
fileHead.bfType=0x4D42;

fileHead.bfSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+colorTablesize
+widthStep*Height;
fileHead.bfReserved1=0;
fileHead.bfReserved2=0;

//bfoffBits the begin 3 parts 
fileHead.bfOffBits=54+colorTablesize;
//write into file head
fwrite(&fileHead,sizeof(BITMAPFILEHEADER),1,fp);

//申请位图信息头结构信息,填写信息头信息
BITMAPINFOHEADER head;
head.biBitCount=8;
head.biClrImportant=0;
head.biClrUsed=0;
head.biCompression=0;
head.biHeight=Height;
head.biPlanes=1;
head.biSize=40;
head.biSizeImage=widthStep*Height;
head.biWidth=Width;
head.biXPelsPerMeter=0;
head.biYPelsPerMeter=0;
//写位图信息进内存
fwrite(&head,sizeof(BITMAPINFOHEADER),1,fp);
//构建颜色表,并写入
for (i=0; i<256; i++)
{
pColorTable[i].rgbBlue=i;
pColorTable[i].rgbGreen=i;
pColorTable[i].rgbRed=i;
pColorTable[i].rgbReserved=0;
}

fwrite(pColorTable,sizeof(RGBQUAD),256,fp);
//write the data in file
fwrite(Mydata,Height*widthStep,1,fp);
fclose(fp);
delete [] Mydata;
return;
}

#9



//生成avi的代码,
//图片读取的路径已经设定好
bool CBmp_aviDlg::bmp_avi(CString aviName, CString bmpPath)
{
CFileFind finder;
//路径名
//若调试中不能打开图片,在路径前面加上"."表示当前文件夹
AVIFileInit(); 
PAVIFILE pfile;
PAVISTREAM ps; 
BITMAPFILEHEADER bmpFileHdr;
DWORD   dwSize ;
LPBITMAPINFOHEADER pDib;
HANDLE hdib;
//压缩格式: 未压缩
AVICOMPRESSOPTIONS strcm;
strcm.cbFormat=0;
strcm.cbParms=0;
strcm.cbFormat=0;
strcm.cbParms=0;
strcm.dwBytesPerSecond=0;
strcm.dwFlags=8;
strcm.dwInterleaveEvery=0;
strcm.dwKeyFrameEvery=0;
strcm.dwQuality=0;
strcm.fccHandler=COMPRESS_NOCOMPRESS;
strcm.fccType=mmioFOURCC('V','I','D','C');
strcm.lpFormat=NULL;
strcm.lpParms=NULL;

int nFrames =0; //frame number
HRESULT hr; 
//判断是否存在路径
BOOL bFind = finder.FindFile(bmpPath);
if (!bFind)
{
AfxMessageBox("don't exist bmp file");
return false;
}
while(bFind)
{
bFind = finder.FindNextFile();//判断是否文件夹为空
if(!finder.IsDots() && !finder.IsDirectory())//判断找到的文件不是当前目录or父目录
{
CString str = finder.GetFilePath();
CFile bmpfile;
// 打开文件
if(bmpfile.Open(str,CFile::modeRead|CFile::shareDenyNone,NULL)==0)
return false;
bmpfile.Read(&bmpFileHdr,sizeof(BITMAPFILEHEADER));
dwSize=bmpFileHdr.bfSize-sizeof(BITMAPFILEHEADER);
hdib=GlobalAlloc(GHND,dwSize);//分配内存
pDib=(LPBITMAPINFOHEADER)GlobalLock(hdib);
bmpfile.Read(pDib,dwSize);

if(nFrames ==0 )
{
AVISTREAMINFO strhdr;
//将要写入AVI文件的名字,不存在的就创建一个
AVIFileOpen(&pfile,aviName , OF_WRITE | OF_CREATE , NULL);
_fmemset(&strhdr, 0, sizeof(strhdr));//Sets buffers to a specified character
//the function is similar to initial.
strhdr.fccType = streamtypeVIDEO;// stream type
strhdr.fccHandler = 0;
strhdr.dwScale = 1;
strhdr.dwRate = 20; // 15 fps
strhdr.dwSuggestedBufferSize = pDib->biSizeImage ;
SetRect(&strhdr.rcFrame, 0, 0, pDib->biWidth, pDib->biHeight);
// And create the stream;
hr = AVIFileCreateStream(pfile,&ps,&strhdr); 
hr = AVIStreamSetFormat(ps,0,pDib,
pDib->biSize+pDib->biClrUsed*sizeof(RGBQUAD));
}
hr = AVIStreamWrite(ps, nFrames , 1, 
(LPBYTE)pDib+pDib->biSize+pDib->biClrUsed*sizeof(RGBQUAD),
pDib->biSizeImage, 
AVIIF_KEYFRAME, 
NULL,
NULL);
GlobalFreePtr(pDib);
nFrames ++; 
}
}
AVIStreamClose(ps);
if(pfile != NULL)
AVIFileRelease(pfile);
AVIFileExit();
return true;
}

#1


不贴代码怎么知道

#2


学习一下

#3


看不到??????

#4


以前整过这样的,只是当时图片切换的时候时间调的不好,出来的AVI不流畅,呵呵,不知道楼主是如何整的,看不到代码

#5


不如用现成的工具,呵呵。
FFMPEG内核,很好使。。。

#6


试试OpenCV中的FFMPEG相关封装好的函数呢?

#7


不好意思啊~ 各位,这几天正好在回学校的途中,所以不能发上程序。

#8



//生成图片的代码
void CBmp_aviDlg::ImageShow(unsigned char *data, int Width, int Height, CString PathName)
{
if (!data)
{
return ;
}
unsigned char *Mydata;
//颜色表,设定为灰度图像
int colorTablesize=1024;
int widthStep=(Width+3)/4*4;
//将数据重新排列成符合bmp规则的方式
Mydata=new unsigned char[widthStep*Height];
for (int i=0;i<Height;i++)
{
for (int j=0;j<Width;j++)
{
*(Mydata+i*widthStep+j)=*(data+i*Width+j);
}
}
RGBQUAD pColorTable[256];
//open a file to write bmp data
FILE *fp=fopen(PathName,"wb");
if (0==fp)
{
return;
}
//申请位图文件头信息,填写文件头信息
BITMAPFILEHEADER fileHead;
fileHead.bfType=0x4D42;

fileHead.bfSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+colorTablesize
+widthStep*Height;
fileHead.bfReserved1=0;
fileHead.bfReserved2=0;

//bfoffBits the begin 3 parts 
fileHead.bfOffBits=54+colorTablesize;
//write into file head
fwrite(&fileHead,sizeof(BITMAPFILEHEADER),1,fp);

//申请位图信息头结构信息,填写信息头信息
BITMAPINFOHEADER head;
head.biBitCount=8;
head.biClrImportant=0;
head.biClrUsed=0;
head.biCompression=0;
head.biHeight=Height;
head.biPlanes=1;
head.biSize=40;
head.biSizeImage=widthStep*Height;
head.biWidth=Width;
head.biXPelsPerMeter=0;
head.biYPelsPerMeter=0;
//写位图信息进内存
fwrite(&head,sizeof(BITMAPINFOHEADER),1,fp);
//构建颜色表,并写入
for (i=0; i<256; i++)
{
pColorTable[i].rgbBlue=i;
pColorTable[i].rgbGreen=i;
pColorTable[i].rgbRed=i;
pColorTable[i].rgbReserved=0;
}

fwrite(pColorTable,sizeof(RGBQUAD),256,fp);
//write the data in file
fwrite(Mydata,Height*widthStep,1,fp);
fclose(fp);
delete [] Mydata;
return;
}

#9



//生成avi的代码,
//图片读取的路径已经设定好
bool CBmp_aviDlg::bmp_avi(CString aviName, CString bmpPath)
{
CFileFind finder;
//路径名
//若调试中不能打开图片,在路径前面加上"."表示当前文件夹
AVIFileInit(); 
PAVIFILE pfile;
PAVISTREAM ps; 
BITMAPFILEHEADER bmpFileHdr;
DWORD   dwSize ;
LPBITMAPINFOHEADER pDib;
HANDLE hdib;
//压缩格式: 未压缩
AVICOMPRESSOPTIONS strcm;
strcm.cbFormat=0;
strcm.cbParms=0;
strcm.cbFormat=0;
strcm.cbParms=0;
strcm.dwBytesPerSecond=0;
strcm.dwFlags=8;
strcm.dwInterleaveEvery=0;
strcm.dwKeyFrameEvery=0;
strcm.dwQuality=0;
strcm.fccHandler=COMPRESS_NOCOMPRESS;
strcm.fccType=mmioFOURCC('V','I','D','C');
strcm.lpFormat=NULL;
strcm.lpParms=NULL;

int nFrames =0; //frame number
HRESULT hr; 
//判断是否存在路径
BOOL bFind = finder.FindFile(bmpPath);
if (!bFind)
{
AfxMessageBox("don't exist bmp file");
return false;
}
while(bFind)
{
bFind = finder.FindNextFile();//判断是否文件夹为空
if(!finder.IsDots() && !finder.IsDirectory())//判断找到的文件不是当前目录or父目录
{
CString str = finder.GetFilePath();
CFile bmpfile;
// 打开文件
if(bmpfile.Open(str,CFile::modeRead|CFile::shareDenyNone,NULL)==0)
return false;
bmpfile.Read(&bmpFileHdr,sizeof(BITMAPFILEHEADER));
dwSize=bmpFileHdr.bfSize-sizeof(BITMAPFILEHEADER);
hdib=GlobalAlloc(GHND,dwSize);//分配内存
pDib=(LPBITMAPINFOHEADER)GlobalLock(hdib);
bmpfile.Read(pDib,dwSize);

if(nFrames ==0 )
{
AVISTREAMINFO strhdr;
//将要写入AVI文件的名字,不存在的就创建一个
AVIFileOpen(&pfile,aviName , OF_WRITE | OF_CREATE , NULL);
_fmemset(&strhdr, 0, sizeof(strhdr));//Sets buffers to a specified character
//the function is similar to initial.
strhdr.fccType = streamtypeVIDEO;// stream type
strhdr.fccHandler = 0;
strhdr.dwScale = 1;
strhdr.dwRate = 20; // 15 fps
strhdr.dwSuggestedBufferSize = pDib->biSizeImage ;
SetRect(&strhdr.rcFrame, 0, 0, pDib->biWidth, pDib->biHeight);
// And create the stream;
hr = AVIFileCreateStream(pfile,&ps,&strhdr); 
hr = AVIStreamSetFormat(ps,0,pDib,
pDib->biSize+pDib->biClrUsed*sizeof(RGBQUAD));
}
hr = AVIStreamWrite(ps, nFrames , 1, 
(LPBYTE)pDib+pDib->biSize+pDib->biClrUsed*sizeof(RGBQUAD),
pDib->biSizeImage, 
AVIIF_KEYFRAME, 
NULL,
NULL);
GlobalFreePtr(pDib);
nFrames ++; 
}
}
AVIStreamClose(ps);
if(pfile != NULL)
AVIFileRelease(pfile);
AVIFileExit();
return true;
}