如何读取AVI文件的第一帧图象并转换成位图?(100分)

  • 主题发起人 主题发起人 remix
  • 开始时间 开始时间
R

remix

Unregistered / Unconfirmed
GUEST, unregistred user!
我需要将AVI文件的第一争图象读取出来并转换为位图以供使用,哪位
大虾能提供相关代码,奉送100分.
 
Do you want avi file's format.
I can mail it to you.

another way, use TAnimate control, it can access avi files.
but you should grap bitmap from its canvas or DC(I'd not tried).
 
我指的是带有声音的AVI文件,不是动画AVI。

非常感谢 bethouvnlue,如果你是中文的Avi格式说明,请寄至
如下地址:

remix@sicimage.hust.edu.cn


 
同意bethouvnlue的意见. 从Avi中取得第一帧的图像,转换到Bmp的对应位置。这
需要了解*.avi和*.bmp的文件格式!
 
BMP格式很简单的。你可以把BMP图看成是一个
矩阵。再加上图象的颜色。就可以把BMP的图在
CANVAS上画出来的。用一个TIMAGE控件就可以很简单
的处理BMP图 的。
AVI的格式我不知道的
 
>remix
很可惜是英文的,我没时间给你翻译了,不过文档不算复杂,你还需要吗?
 
晚上给你个完整例子.
 
跟踪吧! eyes总是有掏不完的宝贝..:-)
 
呵呵, 最简单用抓屏就可以:-)
 
对,cytown说的不错,用抓屏就可以,干么要了解AVI的格式?
 
function GetAviFrame(AviFilename : String;
Index: Integer;
var bmp: TBitmap): boolean;
说明:
avifilename: avi文件名
index: 要取的桢号
bmp: 存放返回图象, 如果为nil则自动建立一个bitmap. 如果存在则按bmp
定义的大小存放stretch后的图象.
返回值: true 成功, false 失败.

代码:

uses windows, graphics;

interface

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 'avifil32.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 'avifil32.dll' index 53;

function AVIStreamInfo(pstream : PAVIStream;
psi : PAVISTREAMINFO;
lsize : longint) : 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 : PBitmapInfoHeader;
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 infodo

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 := image^.biSize + 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.

 
哇, eyes简直(省去xxK字)....
有没有mpeg的抓桢方法?
 
eyes是我们的百宝箱,呵呵!
 
非常感谢各位的帮助。特别是Another-eYes 和 bethouvnlue的帮助。

在Another_eYes的提示下我成功的读取了Avi的各帧图象。

不过我将Another_eYes 的代码略做了改动:

具体的代码如下:

function GetAviFrame(AviFilename : String;
Index: Integer;
var bmp: TBitmap): boolean;
&amp;#203;μ&amp;#195;÷:
avifilename: avi&amp;#206;&amp;#196;&amp;#188;t&amp;#195;&amp;#251;
index: òaè&amp;#161;μ&amp;#196;è&amp;#229;o&amp;#197;
bmp: ′&amp;#230;·&amp;#197;·μ&amp;#187;&amp;#216;í&amp;#188;&amp;#207;ó, è&amp;#231;1&amp;#251;&amp;#206;anil&amp;#212;ò×&amp;#212;&amp;#182;ˉ&amp;#189;¨á¢ò&amp;#187;&amp;#184;&amp;#246;bitmap. è&amp;#231;1&amp;#251;′&amp;#230;&amp;#212;ú&amp;#212;ò°′bmp
&amp;#182;¨ò&amp;#229;μ&amp;#196;′óD&amp;#161;′&amp;#230;·&amp;#197;stretchoóμ&amp;#196;í&amp;#188;&amp;#207;ó.
·μ&amp;#187;&amp;#216;&amp;#214;μ: true 3é1|, false ꧰ü.

′ú&amp;#194;&amp;#235;:

uses windows, graphics;

interface

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 'avifil32.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 'avifil32.dll' index 53;

function AVIStreamInfo(pstream : PAVIStream;
psi : PAVISTREAMINFO;
lsize : longint) : 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 : PBitmapInfoHeader;

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 infodo

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);

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 := image^.biSize + image^.biClrUsed * 4;

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.


 
时间太久,强制结束。 wjiachun
 

Similar threads

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