如何把Avi转成Bmp(100分)

  • 主题发起人 主题发起人 SamuelDelphi
  • 开始时间 开始时间
S

SamuelDelphi

Unregistered / Unconfirmed
GUEST, unregistred user!
在Delphi中可以用TMediaPlayer的Step一副副的播放Avi文件到一个窗口上。我想把Avi文件的内容存成一副副的Bitmap但遇到如下问题:
1。在播放中,我无法得知Avi画面的Height与Width(TMediaPlayer的Height,Width时Player在DesignTime时的长、宽),因此无法动态的调节显示Avi的窗口的大小(即Display指向的窗口),无法“恰到好处”的显示图象。
2。显示的相应窗口(Display属性是TWinControl),没有相应的TGraphic的属性用来
Bmp := TBitmap.Create;
Bmp.Height := ...
Bmp.Width := ...
Bmp.Canvas.Draw(0, 0, 显示窗口的TGraphic属性)
Bmp.SaveToFile(....);
故我无法把其保存为Bitmap文件。
望高人指教。
SamuelDelphi@263.net

VC中有没有把Avi直接转为Bmp的控件?
Samuel0713@263.net
 
看看frame行不行?
 
B :=TBitmap.Create;
B.PixelFormat :=pf24Bit;//:)
B.Canvas.CopyRect(rect(0,0,B.Width,B.Height),XXXXX.Canvas,rect(0,0,XXXXX.Width,XXXXX.Height));
B.SaveToFile(....);
 
最根本的办法是用AVIStreamRead读出图象数据后再保存.
 
MSDN中有一个AVIEdit的sample,稍微改一下就能用来做AVI->BMP
 
csdn的delphi栏目里有一个AVI转BMP的例子,他用API读出AVI的数据一幅幅画在IMAGE上,
应该有帮助。
 
自已在API里找一下,很简单的。
 
利用 VC 实现AVI文件的图像截取

[ 作者: 刘涛 添加时间: 2001-10-23 8:48:00 ]

来源:www.yesky.com

AVI文件就是我们所说的多媒体文件,所谓的AVI图像就是视频图像,该文件是一个RIFF
说明文件,它用于获取、编辑、演示音频、视频序列。一般的AVI文件包含音频流和视频流,
有的特殊的AVI还包含一个控制路径或MIDI路径作为附加的数据流。

  现在播放AVI文件的软件很多,但大多无法从AVI视频文件中读取一帧图像并生成BMP格
式的文件。笔者在使用AVI文件开发项目过程中对AVI文件的操作积累了一些经验,对于如何
实现从AVI视频流中获取任意帧的图像数据并存储成BMP文件,其中最关键的是要从AVI文件
中获取具体某一帧的图像数据,为此我利用Windows提供的API函数实现了自定义的CAvi类,
用于操作AVI文件。

  在使用API函数操作AVI文件时,一定要注意用AVIFileInit()来初始化AVI库,程序结束
时用AVIFileExit()释放AVI库,否则API函数无法使用。现以操作包含真彩色图像的AVI文件
为例,给出Cavi类的部分函数的具体实现,其中CaviCreate()函数用于读取AVI文件信息并
初始化Cavi类的成员,例如根据AVI文件信息定义每帧图像的宽、高、每帧图像的信息头结
构等等;函数AviRead(int mFrame)用于从AVI文件中读取第mFrame帧。实现代码显示如下:

//Cavi类头文件定义;
class CAvi file://AVI类,处理AVI文件
{
 public:
 int cy;//图象高
 int cx;//图象宽
 file://long m_maxFrame;
 BYTE *pData;//寸储图象数据
 BITMAPINFO *m_pBMI;//位图文件信息头
 PAVISTREAM pavi;//AVI流
 PAVIFILE pfile;//AVI文件指针
 AVIFILEINFO * pfi; file://AVI信息
 BOOL AviRead(int mFrame);//读AVI文件的第mFrame帧
 CAvi();//标准构造函数
 CAviCreate(CString &string);//用文件名初始化AVI类的成员
 virtual ~CAvi();
};
//Cavi类文件实现部分;
CAvi::CAvi()
{ AVIFileInit();//初始化AVI库
 cx=0;//定义图象宽、高、等成员
 cy=0;
 m_pBMI=NULL;
 pData=NULL;
 file://m_maxFrame=0;
 pfi=NULL;
}
CAvi::~CAvi()//析构、释放指针
{
 // AVIFileClose(pfile);
 AVIFileExit();
 if(pData!=NULL)
  delete pData;
  pData=NULL;

 if(m_pBMI!=NULL)
  delete m_pBMI;
  m_pBMI=NULL;
  if(pfi!=NULL)
   delete pfi;
   pfi=NULL;
}
CAvi::CAviCreate(CString &string)//读文件初始化该类
{
 HRESULT hr;
 pfi=new AVIFILEINFO;
 hr = AVIFileOpen(&pfile, // returned file pointer
 string, // file name
 OF_READ, // mode to open file with
 NULL);
 hr= AVIFileInfo(pfile, file://获取AVI信息,放入pfi中
 pfi,
 sizeof(AVIFILEINFO)
);
cx=pfi->dwWidth;//图象宽、高
cy=pfi->dwHeight;
hr=AVIFileGetStream(//将AVI变成视频流
pfile,
&pavi,
streamtypeVIDEO,
0//LONG lParam
);
m_pBMI=new BITMAPINFO;//定义BMP信息头
m_pBMI->bmiHeader.biBitCount=24;
m_pBMI->bmiHeader.biClrImportant=0;
m_pBMI->bmiHeader.biClrUsed=0;
m_pBMI->bmiHeader.biCompression=BI_RGB;
m_pBMI->bmiHeader.biHeight=cy;
m_pBMI->bmiHeader.biWidth=cx;
m_pBMI->bmiHeader.biPlanes=1;
m_pBMI->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
m_pBMI->bmiHeader.biXPelsPerMeter=0;
m_pBMI->bmiHeader.biYPelsPerMeter=0;
m_pBMI->bmiHeader.biSizeImage=cx*cy*3;
pData=(BYTE*)new char[cx*cy*3];//根据AVI中BMP图象的信息定义缓冲区
}
BOOL CAvi::AviRead(int mFrame)//将AVI文件的M帧数据读入PData缓冲区
{
HRESULT hr;
hr= AVIStreamRead( pavi,
mFrame,
1,
pData,
cx*cy*3,
NULL,
NULL
);
if(hr==0)
return TRUE;
else
return FALSE;
}



  上述Cavi类实现部分所涉及到的API函数可以参考微软提供的MSDN。Cavi类中的pData缓
冲区存放AVI文件中的具体某一帧图像数据,同时Cavi类的m_pBMI为BMP图像文件信息结构,
这时可以根据图像的大小定义BMP图像文件头结构,关于BMP文件的存储,由于篇幅的原因,
我不在多讲了,有兴趣的读者可以参见笔者的拙作"Visual C++6.0开发灰度位图处理"(天
极网软件栏目2001.9.10发表),该文里面讲述了如何存取BMP文件。以上程序在
Windows2000、Visual C++6.0环境下顺利编译通过,运行正常。
 
我也有类似的问题,不过我需要的是每帧的画面,而不能通过截屏,那位高手可以解答?
 
时间太长,强制结束吧! 分拿来!:)
 
都2年了拿分来。
 
多人接受答案了。
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
I
回复
0
查看
794
import
I
D
回复
0
查看
2K
DelphiTeacher的专栏
D
后退
顶部