究竟是谁惹的祸--编程高手看过来----关于AVI捕获与截取的问题(100分)

  • 主题发起人 主题发起人 easydo
  • 开始时间 开始时间
E

easydo

Unregistered / Unconfirmed
GUEST, unregistred user!
我需要将AVI文件的第一帧图象读取出来并转换为位图以供使用,所以编写了一个函数
function GetAviFrame(AviFilename : String; Index: Integer; var bmp: TBitmap):
boolean;
说明:
avifilename: avi文件名
index: 要取的帧号
bmp: 存放返回图象, 如果为nil则自动建立一个bitmap. 如果存在则按bmp定义的大小存放stretch后的图象.
返回值: true 成功, false 失败
现在的问题是编译没有问题,但是我用一个Image控件显示得到的BMP图片时,却发现根本得不到第一帧的
图片,请DELPHI高手帮忙!!!,多谢!!!
函数代码如下:
unit Unit_GetAviFrame;
interface
uses windows, graphics;
const
streamtypeAUDIO : longint = $73647561;
streamtypeVIDEO : longint = $73646976;
type
TAVIStream = record
fccType : longint;
fccHandler : longint;
dwFlags : longint;
dwCaps : longint;
wPriority : word;
wLanguage : word;
dwScale : longint;
dwRate : longint;
dwStart : longint;
dwLength : longint;
dwInitialFrames : longint;
dwSuggestedBufferSize : longint;
dwQuality : longint;
dwSampleSize : longint;
rcFrame : TRect;
dwEditCount : longint;
dwFormatChangeCount : longint;
Name : array [0..64] of char;
end;
PAVIStream = ^TAVIStream;
PAVIFile = pointer;
TAVIFileInfo = record
dwMaxBytesPerSec : longint;
dwFlags : longint;
dwCaps : longint;
dwStreams : longint;
dwSuggestedBufferSize : longint;
dwWidth : longint;
dwHeight : longint;
dwScale : longint;
dwRate : longint;
dwLength : longint;
dwEditCount : longint;
szFileType : array[0..63] of char;
end;
PAVIFileInfo = ^TAVIFileInfo;
TAVIStreamInfo = record
fccType : longint;
fccHandler : longint;
dwFlags : longint;
dwCaps : longint;
wPriority : word;
wLanguage : word;
dwScale : longint;
dwRate : longint;
dwStart : longint;
dwLength : longint;
dwInitialFrames : longint;
dwSuggestedBufferSize : longint;
dwQuality : longint;
dwSampleSize : longint;
rcFrame : TRect;
dwEditCount : longint;
dwFormatChangeCount : longint;
szName : array[0..63] of char;
end;
PAVIStreamInfo = ^TAVIStreamInfo;
function AVIFileOpen(avifile : pointer; filename : pchar; mode : integer;
CLSID : pointer) : integer; stdcall; external 'avifil32.dll
' index 16;
function AVIFileRelease(avifile : pointer) : longint; stdcall; external 'avif
il32.dll' index 20;
function AVIFileGetStream(avifile : pointer; avistream : PAVIStream;
streamtype : longint; lParam : longint) : integer;
stdcall;
external 'avifil32.dll' index 11;
function AVIStreamGetFrameOpen(avistream : PAVIStream; bitmapwanted : pointer
) : pointer;
stdcall; external 'avifil32.dll' index 42;
procedure AVIStreamGetFrameClose(pget : pointer); stdcall; external 'avifil32.
dll' index 41;
function AVIStreamGetFrame(getframe : pointer; position : longint) : pointer;
stdcall;
external 'avifil32.dll' index 40;
procedure AVIStreamRelease(avistream : PAVIStream); stdcall; external 'avifil3
2.dll' index 53;
function AVIStreamInfo(pstream : PAVIStream; psi : PAVISTREAMINFO; lsize : lo
ngint) :
integer; stdcall; external 'avifil32.dll' index 44;
function GetAviFrame(AviFilename : String; Index: Integer; var bmp: TBitmap):
boolean;
implementation
function GetAviFrame(AviFilename : String; Index: Integer; var bmp: TBitmap):
boolean;
var
FAviFile : Pointer;
FVideoStream : Pointer;
FGetFrame : Pointer;
info : TAVIStreamInfo;
FFrameWidth, FFrameHeight : Integer;
FStartFrame, FStopFrame : Integer;
image : pointer;
imagestart : Integer;
begin
result := false;
if (AVIFileOpen(@favifile, pchar(AviFileName), 0, nil) <> 0) then
exit;
if (AVIFileGetStream(favifile, @fvideostream, streamtypeVIDEO, 0) <> 0) then
begin
AVIFileRelease(favifile);
exit;
end;
AVIStreamInfo(fvideostream, @info, sizeof(info));
with info do
begin
fFrameWidth := rcframe.right - rcframe.left;
fFrameHeight := rcframe.bottom - rcframe.top;
fStartFrame := dwStart;
fStopFrame := dwLength - 1;
end;
if (index <fstartframe) or (index > fstopframe) then
begin
AVIStreamRelease(fvideostream);
AVIFileRelease(favifile);
exit;
end;
fgetframe := AVIStreamGetFrameOpen(fvideostream, nil);
if (fgetframe = nil) then
begin
AVIStreamRelease(fvideostream);
AVIFileRelease(favifile);
exit;
end;
image := AVIStreamGetFrame(fGetFrame, Index);
if assigned(image) then
begin
if not assigned(bmp) then
begin
bmp := tbitmap.create;
bmp.width := fframewidth;
bmp.height := fframeheight;
end
else if bmp.empty then
begin
bmp.width := fframewidth;
bmp.height := fframeheight;
end;
imagestart := TBitmapInfoHeader(image^).biSize +
TBitmapInfoHeader(image^).biClrUsed * 4;
StretchDIBits(bmp.canvas.handle, 0, 0, bmp.width, bmp.height,
0, 0, fframewidth, fframeheight,
pchar(image) + imagestart,
TBitmapInfo(image^), 0, SRCCOPY);
result := true;
end;
AVIStreamGetFrameClose(fgetframe);
AVIStreamRelease(fvideostream);
AVIFileRelease(favifile);
end;
end.

//显示图片的代码如下(在空白窗体上添加一个Image控件和Button控件)
procedure TForm1.Button1Click(Sender: TObject);
var
bmp : Tbitmap;
begin
bmp := Tbitmap.Create;
if (Unit_GetAviFrame.GetAviFrame('2.avi',1000,bmp) = True) then
begin
image1.Picture.Bitmap.Assign(bmp);
Image1.Refresh;
showmessage('ok');
end;
bmp.Free;
end;
 
研究一下:http://delphibbs.com/delphibbs/dispq.asp?lid=1949444
能给点参考
我们都用这个方面的东西,
你的QQ?我们再联系
zhoufujin@sohu.com
 
关注此贴内容并学习之!yckxzjj@163.com
 
刚刚回答了这个问题
http://www.delphibbs.com/delphibbs/dispq.asp?lid=1559219
如何能够获得视频文件的头一帧(或者是第二帧),并且把它保存为图片?
多多利用DirectX吧,
 
后退
顶部