首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ Builder >

为什么从AVI提取的位图打不开,该怎么解决

2012-02-24 
为什么从AVI提取的位图打不开 - C++ Builder / Windows SDK/API#include vfw.h#include Unit1.h//----

为什么从AVI提取的位图打不开 - C++ Builder / Windows SDK/API
#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次!

热点排行