AVI英文全称为Audio Video Interleaved,即音频视频交错格式。它是一种将语音和影像同步组合在一起的文件格式。AVI支持256色和RLE压缩,主要应用在多媒体光盘上,主要用来保存电视、电影等各种影像信息。
在Windows系统中,借助于API之利,我们能够轻易的实现AVI文件的分解与重组。下面,我给出一个C#版本的AVI分解示例。
using
System;
using
System.Drawing;
using
System.Runtime.InteropServices;
using
System.IO;

namespace
org.loon.util

...
{

/**////<summary>
///org.loon.util.AVIUtil用于AVI文件处理
///</summary>

publicclassAVIUtil...{
[StructLayout(LayoutKind.Sequential,Pack=1)]
structBITMAPFILEHEADER

...{
publicushortbfType;
publicuintbfSize;
publicushortbfReserved1;
publicushortbfReserved2;
publicuintbfOffBits;
}

[StructLayout(LayoutKind.Sequential,Pack=1)]
structBITMAPINFOHEADER

...{
publicuintbiSize;
publicintbiWidth;
publicintbiHeight;
publicushortbiPlanes;
publicushortbiBitCount;
publicuintbiCompression;
publicuintbiSizeImage;
publicintbiXPelsPerMeter;
publicintbiYPelsPerMeter;
publicuintbiClrUsed;
publicuintbiClrImportant;
publicconstintBI_RGB=0;
}

constuintDIB_RGB_COLORS=0;

constuintDIB_PAL_COLORS=1;


/**////<summary>
///对象转换
///</summary>
///<paramname="pBITMAPINFOHEADER"></param>
///<returns></returns>
publicstaticBitmapToBitmap(IntPtrpBITMAPINFOHEADER)

...{
unsafe

...{
BITMAPINFOHEADER*pbmi=(BITMAPINFOHEADER*)pBITMAPINFOHEADER;
BITMAPFILEHEADERpbmfi;
pbmfi.bfType=(int)'M'<<8|(int)'B';
pbmfi.bfOffBits=(uint)(sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER));
pbmfi.bfSize=pbmfi.bfOffBits+pbmi->biSizeImage;

MemoryStreamstream=newMemoryStream();
BinaryWriterbw=newBinaryWriter(stream);
byte[]data=newbyte[sizeof(BITMAPFILEHEADER)];
Marshal.Copy((IntPtr)(&pbmfi),data,0,data.Length);
bw.Write(data);

data=newbyte[sizeof(BITMAPINFOHEADER)];
Marshal.Copy(pBITMAPINFOHEADER,data,0,data.Length);
bw.Write(data);

data=newbyte[pbmi->biSizeImage];
++pbmi;
Marshal.Copy((IntPtr)pbmi,data,0,data.Length);
bw.Write(data);
bw.Flush();
bw.BaseStream.Position=0;

returnnewBitmap(bw.BaseStream);
}
}
}


/**////<summary>
///AviFile,用于AVI文件处理
///</summary>
publicclassAviFile:IDisposable

...{
conststringAVIFILE32="AVIFIL32";
constintAVIGETFRAMEF_BESTDISPLAYFMT=1;

internalenumOpenFileFlags:uint

...{
OF_READ=0x00000000,
OF_WRITE=0x00000001,
OF_READWRITE=0x00000002,
OF_SHARE_COMPAT=0x00000000,
OF_SHARE_EXCLUSIVE=0x00000010,
OF_SHARE_DENY_WRITE=0x00000020,
OF_SHARE_DENY_READ=0x00000030,
OF_SHARE_DENY_NONE=0x00000040,
OF_PARSE=0x00000100,
OF_DELETE=0x00000200,
OF_VERIFY=0x00000400,
OF_CANCEL=0x00000800,
OF_CREATE=0x00001000,
OF_PROMPT=0x00002000,
OF_EXIST=0x00004000,
OF_REOPEN=0x00008000,
}


[DllImport(AVIFILE32)]
externinternalstaticvoidAVIFileInit();

[DllImport(AVIFILE32)]
externinternalstaticvoidAVIFileExit();

[DllImport(AVIFILE32)]
externinternalstaticuintAVIFileOpen(outIntPtrppfile,stringszFile,OpenFileFlagsmode,IntPtrpclsidHandler);

[DllImport(AVIFILE32)]
externinternalstaticintAVIFileRelease(IntPtrpfile);

[DllImport(AVIFILE32)]
externinternalstaticuintAVIFileGetStream(IntPtrpfile,outIntPtrppavi,uintfccType,intlParam);

[DllImport(AVIFILE32)]
externinternalstaticintAVIStreamRelease(IntPtrpavi);

[DllImport(AVIFILE32)]
externinternalstaticIntPtrAVIStreamGetFrameOpen(IntPtrpavi,intlpbiWanted);

[DllImport(AVIFILE32)]
externinternalstaticIntPtrAVIStreamGetFrame(IntPtrpgf,intlPos);

[DllImport(AVIFILE32)]
externinternalstaticintAVIStreamLength(IntPtrpavi);

[DllImport(AVIFILE32)]
externinternalstaticuintAVIStreamGetFrameClose(IntPtrpget);


staticuintmmioFOURCC(charc0,charc1,charc2,charc3)

...{
return(uint)c3<<24|(uint)c2<<16|(uint)c1<<8|(uint)c0;
}

staticreadonlyuintstreamtypeVIDEO=mmioFOURCC('v','i','d','s');
staticreadonlyuintstreamtypeAUDIO=mmioFOURCC('a','u','d','s');
staticreadonlyuintstreamtypeMIDI=mmioFOURCC('m','i','d','s');
staticreadonlyuintstreamtypeTEXT=mmioFOURCC('t','x','t','s');

IntPtraviFile=IntPtr.Zero;
IntPtraviStream=IntPtr.Zero;
booldisposed=false;

publicstaticvoidInitialize()

...{
AVIFileInit();
}

publicstaticvoidTerminate()

...{
AVIFileExit();
}

publicAviFile(stringfilename)

...{
uintresult;
result=AVIFileOpen(outaviFile,filename,OpenFileFlags.OF_READ,IntPtr.Zero);
if(result!=0)

...{
Release();
thrownewException("AVIFileOpenfailure.");
}

result=AVIFileGetStream(aviFile,outaviStream,streamtypeVIDEO,0);
if(result!=0)

...{
Release();
thrownewException("AVIFileGetStreamfailure.");
}
}

~AviFile()

...{
Dispose(false);
}

voidRelease()

...{
if(aviStream!=IntPtr.Zero)

...{
AVIStreamRelease(aviStream);
aviStream=IntPtr.Zero;
}

if(aviFile!=IntPtr.Zero)

...{
AVIFileRelease(aviFile);
aviFile=IntPtr.Zero;
}
}

publicintGetMaxFrameCount()

...{
if(aviStream==IntPtr.Zero)
thrownewInvalidOperationException();
returnAVIStreamLength(aviStream);
}

publicBitmapGetFrame(intno)

...{
if(aviStream==IntPtr.Zero)
thrownewInvalidOperationException();

IntPtrframe=IntPtr.Zero;
try

...{
frame=AVIStreamGetFrameOpen(aviStream,AVIGETFRAMEF_BESTDISPLAYFMT);
IntPtrpbmi=AVIStreamGetFrame(frame,no);
returnorg.loon.util.AVIUtil.ToBitmap(pbmi);

}
finally

...{
if(frame!=IntPtr.Zero)
AVIStreamGetFrameClose(frame);
}
}

protectedvoidDispose(booldisposing)

...{
if(disposed)
return;
disposed=true;
Release();
}

publicvoidDispose()

...{
//不让垃圾回收器终止指定对象(即不将指定对象调入终止序列中)
GC.SuppressFinalize(this);
Dispose(true);
}

}

}
分解AVI:
string
filename
=
"
d:/test.avi
"
;
//
初始化
org.loon.util.AviFile.Initialize();

using
(org.loon.util.AviFileavi
=
new
org.loon.util.AviFile(filename))

...
{
intmax=avi.GetMaxFrameCount();
for(inti=0;i<max;++i)

...{
Bitmapbmp=avi.GetFrame(i);
bmp.Save("d:/test/"+i+".bmp");
bmp.Dispose();
}
}
//
完成
org.loon.util.AviFile.Terminate();
在Windows系统中,借助于API之利,我们能够轻易的实现AVI文件的分解与重组。下面,我给出一个C#版本的AVI分解示例。


















































































































































































































































































分解AVI:

















