为什么从AVI提取的位图打不开
#include "vfw.h"
#include "Unit1.h"
//---------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
#pragma link "vfw32.lib "
TForm1 *Form1;
int m_nFrameNo; // 帧号
PAVIFILE m_pAviFile;
LPCTSTR m_strAviFileName="e:/search.avi"; //AVI文件名
PAVISTREAM m_pAviStream;//Handle for video stream
AVISTREAMINFO m_AviStreamInfo;//Information about video stream
PGETFRAME m_pGetFrame;
//AVI文件内容之属性
int m_nFrameWidth; //Frame's width
int m_nFrameHeight; //Frame's Height
int m_nFrameFirst; //First Frame
int m_nFrameLast; //Last Frame
int m_nFrameTotalNum; //Frames,总帧数
int m_nFramePerSec; //Frames Per Second
int m_nFramePlayBegin; //起始播放帧
int m_nFramePlayEnd; //结尾播放帧
int m_nFrameCurSel; // 当前选中帧
//---------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------
bool TForm1::SaveFrame(LPCTSTR fn, int frameno)
{
BITMAPFILEHEADERBMPFileHeader;
LPBITMAPINFOHEADERlpbi;
PGETFRAMEpgf;
DWORDlpNumberOfBytesWritten;
//Prepare to decompress video frames from video stream
pgf = AVIStreamGetFrameOpen( m_pAviStream, NULL );
if (pgf==NULL)
return false;
//Get the address of a decompressed video frame
lpbi = (LPBITMAPINFOHEADER)AVIStreamGetFrame( pgf, frameno );
if ( lpbi==NULL )
return false;
//Fill BITMAPFILEHEADER structure
BMPFileHeader.bfType = 0x4d42;
BMPFileHeader.bfSize = (DWORD)(sizeof(BITMAPFILEHEADER)+lpbi->biSize+lpbi->biClrUsed*sizeof(RGBQUAD)+lpbi->biSizeImage);
BMPFileHeader.bfReserved1 = 0;
BMPFileHeader.bfReserved2 = 0;
BMPFileHeader.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER)+lpbi->biSize+lpbi->biClrUsed*sizeof(RGBQUAD);
//Create BMP file
HANDLEhFile=CreateFile(fn,GENERIC_READ|GENERIC_WRITE,(DWORD)0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,(HANDLE)NULL);
if (hFile==INVALID_HANDLE_VALUE)
{
AVIStreamGetFrameClose(pgf);
return false;
}
//Save BITMAPFILEHEADER
if (WriteFile(hFile,(LPVOID)&BMPFileHeader,sizeof(BITMAPFILEHEADER),(LPDWORD)&lpNumberOfBytesWritten,NULL)==0)
{
AVIStreamGetFrameClose(pgf);
CloseHandle(hFile);
return false;
}
//Save bitmap of a decompressed video frame
if (WriteFile(hFile,(LPVOID)lpbi,sizeof(BITMAPFILEHEADER)+lpbi->biSize+lpbi->biClrUsed*sizeof(RGBQUAD)+lpbi->biSizeImage,(LPDWORD)&lpNumberOfBytesWritten,NULL)==0)
{
AVIStreamGetFrameClose(pgf);
CloseHandle(hFile);
return false;
}
AVIStreamGetFrameClose( pgf );
CloseHandle( hFile );
return true;
}
//------------------------------------------
BOOL TForm1::GetAviFileInfo(void)
{
AVIFileInit();
int retVal = AVIFileOpen( &m_pAviFile, m_strAviFileName, OF_READ, NULL );
if ( retVal!=0 )
{
return FALSE;
}
retVal = AVIFileGetStream( m_pAviFile, &m_pAviStream, streamtypeVIDEO, 0 );
if ( retVal!=0 )
{
return FALSE;
}
retVal = AVIStreamInfo( m_pAviStream, &m_AviStreamInfo, sizeof(m_AviStreamInfo) );
if ( retVal!=0 )
{
return FALSE;
}
m_nFrameWidth = m_AviStreamInfo.rcFrame.right-m_AviStreamInfo.rcFrame.left;
m_nFrameHeight = m_AviStreamInfo.rcFrame.bottom-m_AviStreamInfo.rcFrame.top;
m_nFrameFirst = m_AviStreamInfo.dwStart;
m_nFrameLast = m_AviStreamInfo.dwStart+m_AviStreamInfo.dwLength-1;
m_nFrameTotalNum = m_AviStreamInfo.dwLength;
m_nFramePerSec = m_AviStreamInfo.dwRate/m_AviStreamInfo.dwScale;
AVIFileRelease( m_pAviFile ); // closes the file
AVIFileExit(); // releases AVIFile library
return true;
}
//------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
MediaPlayer1->FileName="e:/search.avi";
MediaPlayer1->Open();
MediaPlayer1->Play();
LPCTSTR fn="e://11.bmp";
int frameno=0;
if(!GetAviFileInfo())
{
return;
}
SaveFrame(fn, frameno);
//Image1->Picture->LoadFromFile("e:/search.bmp");
}
//---------------------------------------
[解决办法]
很明显 sizeof(BITMAPFILEHEADER)保存了2次!