继续上一篇blog
运行:
播放画面如下:
生成的文件属性如下,与我们设定的参数相符:
是 不是很简单?实际上,借助于avifile32 api,我们甚至可以改变文件压缩格式,加入背景音乐,乃至植入病毒(咳,通常我们结合桌面截图及avi生成还有模拟键盘,就可以远程操作或者监控、记录 电脑操作……)总之,在windows下操作avi文件是一件再简单没有的事情了。
有兴趣的话可以这两篇博文为基础,将其修改为自己的字幕组工具、屏幕录像工具、乃至远程监控工具等。有疑问的话,可以发email到:ceponline@yahoo.com.cn
using
System;
using System.Runtime.InteropServices;
using System.Drawing;
using System.Drawing.Imaging;
namespace org.loon.util
... {
/**////<summary>
///AVIWriter的摘要说明,chenpeng,Email:ceponline@yahoo.com.cn。
///</summary>
publicclassAVIWriter
...{
conststringAVIFILE32="AVIFIL32";
privateint_pfile=0;
privateIntPtr_ps=newIntPtr(0);
privateIntPtr_psCompressed=newIntPtr(0);
privateUInt32_frameRate=0;
privateint_count=0;
privateUInt32_width=0;
privateUInt32_stride=0;
privateUInt32_height=0;
//avi标识
privateUInt32_fccType=1935960438;//vids
privateUInt32_fccHandler=808810089;//IV50
privateBitmap_bmp;
[DllImport(AVIFILE32)]
privatestaticexternvoidAVIFileInit();
[DllImport(AVIFILE32)]
privatestaticexternintAVIFileOpenW(refintptr_pfile,[MarshalAs(UnmanagedType.LPWStr)]stringfileName,intflags,intdummy);
[DllImport(AVIFILE32)]
privatestaticexternintAVIFileCreateStream(intptr_pfile,outIntPtrptr_ptr_avi,refAVISTREAMINFOWptr_streaminfo);
[DllImport(AVIFILE32)]
privatestaticexternintAVIMakeCompressedStream(outIntPtrppsCompressed,IntPtraviStream,refAVICOMPRESSOPTIONSao,intdummy);
[DllImport(AVIFILE32)]
privatestaticexternintAVIStreamSetFormat(IntPtraviStream,Int32lPos,refBITMAPINFOHEADERlpFormat,Int32cbFormat);
[DllImport(AVIFILE32)]
unsafeprivatestaticexternintAVISaveOptions(inthwnd,UInt32flags,intnStreams,IntPtr*ptr_ptr_avi,AVICOMPRESSOPTIONS**ao);
[DllImport(AVIFILE32)]
privatestaticexternintAVIStreamWrite(IntPtraviStream,Int32lStart,Int32lSamples,IntPtrlpBuffer,Int32cbBuffer,Int32dwFlags,Int32dummy1,Int32dummy2);
[DllImport(AVIFILE32)]
privatestaticexternintAVIStreamRelease(IntPtraviStream);
[DllImport(AVIFILE32)]
privatestaticexternintAVIFileRelease(intpfile);
[DllImport(AVIFILE32)]
privatestaticexternvoidAVIFileExit();
[StructLayout(LayoutKind.Sequential,Pack=1)]
privatestructAVISTREAMINFOW
...{
publicUInt32fccType;
publicUInt32fccHandler;
publicUInt32dwFlags;
publicUInt32dwCaps;
publicUInt16wPriority;
publicUInt16wLanguage;
publicUInt32dwScale;
publicUInt32dwRate;
publicUInt32dwStart;
publicUInt32dwLength;
publicUInt32dwInitialFrames;
publicUInt32dwSuggestedBufferSize;
publicUInt32dwQuality;
publicUInt32dwSampleSize;
publicUInt32rect_left;
publicUInt32rect_top;
publicUInt32rect_right;
publicUInt32rect_bottom;
publicUInt32dwEditCount;
publicUInt32dwFormatChangeCount;
publicUInt16szName0;
publicUInt16szName1;
publicUInt16szName2;
publicUInt16szName3;
publicUInt16szName4;
publicUInt16szName5;
publicUInt16szName6;
publicUInt16szName7;
publicUInt16szName8;
publicUInt16szName9;
publicUInt16szName10;
publicUInt16szName11;
publicUInt16szName12;
publicUInt16szName13;
publicUInt16szName14;
publicUInt16szName15;
publicUInt16szName16;
publicUInt16szName17;
publicUInt16szName18;
publicUInt16szName19;
publicUInt16szName20;
publicUInt16szName21;
publicUInt16szName22;
publicUInt16szName23;
publicUInt16szName24;
publicUInt16szName25;
publicUInt16szName26;
publicUInt16szName27;
publicUInt16szName28;
publicUInt16szName29;
publicUInt16szName30;
publicUInt16szName31;
publicUInt16szName32;
publicUInt16szName33;
publicUInt16szName34;
publicUInt16szName35;
publicUInt16szName36;
publicUInt16szName37;
publicUInt16szName38;
publicUInt16szName39;
publicUInt16szName40;
publicUInt16szName41;
publicUInt16szName42;
publicUInt16szName43;
publicUInt16szName44;
publicUInt16szName45;
publicUInt16szName46;
publicUInt16szName47;
publicUInt16szName48;
publicUInt16szName49;
publicUInt16szName50;
publicUInt16szName51;
publicUInt16szName52;
publicUInt16szName53;
publicUInt16szName54;
publicUInt16szName55;
publicUInt16szName56;
publicUInt16szName57;
publicUInt16szName58;
publicUInt16szName59;
publicUInt16szName60;
publicUInt16szName61;
publicUInt16szName62;
publicUInt16szName63;
}
[StructLayout(LayoutKind.Sequential,Pack=1)]
privatestructAVICOMPRESSOPTIONS
...{
publicUInt32fccType;
publicUInt32fccHandler;
publicUInt32dwKeyFrameEvery;
publicUInt32dwQuality;
publicUInt32dwBytesPerSecond;
publicUInt32dwFlags;
publicIntPtrlpFormat;
publicUInt32cbFormat;
publicIntPtrlpParms;
publicUInt32cbParms;
publicUInt32dwInterleaveEvery;
}
[StructLayout(LayoutKind.Sequential,Pack=1)]
publicstructBITMAPINFOHEADER
...{
publicUInt32biSize;
publicInt32biWidth;
publicInt32biHeight;
publicInt16biPlanes;
publicInt16biBitCount;
publicUInt32biCompression;
publicUInt32biSizeImage;
publicInt32biXPelsPerMeter;
publicInt32biYPelsPerMeter;
publicUInt32biClrUsed;
publicUInt32biClrImportant;
}
publicclassAviException:ApplicationException
...{
publicAviException(strings):base(s)...{}
publicAviException(strings,Int32hr)
:base(s)
...{
if(hr==AVIERR_BADPARAM)
...{
err_msg="AVIERR_BADPARAM";
}
else
...{
err_msg="unknown";
}
}
publicstringErrMsg()
...{
returnerr_msg;
}
privateconstInt32AVIERR_BADPARAM=-2147205018;
privatestringerr_msg;
}
publicBitmapCreate(stringfileName,UInt32frameRate,intwidth,int
height)
...{
_frameRate=frameRate;
_width=(UInt32)width;
_height=(UInt32)height;
_bmp=newBitmap(width,height,PixelFormat.Format24bppRgb);
//锁定为24位位图
BitmapDatabmpDat=_bmp.LockBits(newRectangle(0,0,width,
height),ImageLockMode.ReadOnly,PixelFormat.Format24bppRgb);
_stride=(UInt32)bmpDat.Stride;
_bmp.UnlockBits(bmpDat);
AVIFileInit();
inthr=AVIFileOpenW(ref_pfile,fileName,4097,0);
if(hr!=0)
...{
thrownewAviException("Create错误!");
}
CreateStream();
SetOptions();
return_bmp;
}
publicvoidAddFrame()
...{
BitmapDatabmpDat=_bmp.LockBits(
newRectangle(0,0,(int)_width,(int)_height),
ImageLockMode.ReadOnly,PixelFormat.Format24bppRgb);
inthr=AVIStreamWrite(_psCompressed,_count,1,
bmpDat.Scan0,
(Int32)(_stride*_height),
0,
0,
0);
if(hr!=0)
...{
thrownewAviException("AVIStreamWrite");
}
_bmp.UnlockBits(bmpDat);
_count++;
}
publicvoidLoadFrame(Bitmapnextframe)
...{
_bmp=newBitmap(nextframe);
}
publicvoidClose()
...{
AVIStreamRelease(_ps);
AVIStreamRelease(_psCompressed);
AVIFileRelease(_pfile);
AVIFileExit();
}
/**////<summary>
///创建流文件
///</summary>
privatevoidCreateStream()
...{
AVISTREAMINFOWstrhdr=newAVISTREAMINFOW();
strhdr.fccType=_fccType;
strhdr.fccHandler=_fccHandler;
strhdr.dwFlags=0;
strhdr.dwCaps=0;
strhdr.wPriority=0;
strhdr.wLanguage=0;
strhdr.dwScale=1;
strhdr.dwRate=_frameRate;
strhdr.dwStart=0;
strhdr.dwLength=0;
strhdr.dwInitialFrames=0;
strhdr.dwSuggestedBufferSize=_height*_stride;
strhdr.dwQuality=0xffffffff;
strhdr.dwSampleSize=0;
strhdr.rect_top=0;
strhdr.rect_left=0;
strhdr.rect_bottom=_height;
strhdr.rect_right=_width;
strhdr.dwEditCount=0;
strhdr.dwFormatChangeCount=0;
strhdr.szName0=0;
strhdr.szName1=0;
inthr=AVIFileCreateStream(_pfile,out_ps,refstrhdr);
if(hr!=0)
...{
thrownewAviException("AVIFileCreateStream");
}
}
/**////<summary>
///设置参数
///</summary>
unsafeprivatevoidSetOptions()
...{
AVICOMPRESSOPTIONSopts=newAVICOMPRESSOPTIONS();
opts.fccType=_fccType;
opts.fccHandler=0;
opts.dwKeyFrameEvery=0;
opts.dwQuality=0;
opts.dwFlags=0;
opts.dwBytesPerSecond=0;
opts.lpFormat=newIntPtr(0);
opts.cbFormat=0;
opts.lpParms=newIntPtr(0);
opts.cbParms=0;
opts.dwInterleaveEvery=0;
AVICOMPRESSOPTIONS*p=&opts;
AVICOMPRESSOPTIONS**pp=&p;
IntPtrx=_ps;
IntPtr*ptr_ps=&x;
AVISaveOptions(0,0,1,ptr_ps,pp);
inthr=AVIMakeCompressedStream(out_psCompressed,_ps,ref
opts,0);
if(hr!=0)
...{
thrownewAviException("AVIMakeCompressedStream");
}
BITMAPINFOHEADERbi=newBITMAPINFOHEADER();
bi.biSize=40;
bi.biWidth=(Int32)_width;
bi.biHeight=(Int32)_height;
bi.biPlanes=1;
bi.biBitCount=24;
bi.biCompression=0;
bi.biSizeImage=_stride*_height;
bi.biXPelsPerMeter=0;
bi.biYPelsPerMeter=0;
bi.biClrUsed=0;
bi.biClrImportant=0;
hr=AVIStreamSetFormat(_psCompressed,0,refbi,40);
if(hr!=0)
...{
thrownewAviException("AVIStreamSetFormat",hr);
}
}
};
}
using System.Runtime.InteropServices;
using System.Drawing;
using System.Drawing.Imaging;
namespace org.loon.util
... {
/**////<summary>
///AVIWriter的摘要说明,chenpeng,Email:ceponline@yahoo.com.cn。
///</summary>
publicclassAVIWriter
...{
conststringAVIFILE32="AVIFIL32";
privateint_pfile=0;
privateIntPtr_ps=newIntPtr(0);
privateIntPtr_psCompressed=newIntPtr(0);
privateUInt32_frameRate=0;
privateint_count=0;
privateUInt32_width=0;
privateUInt32_stride=0;
privateUInt32_height=0;
//avi标识
privateUInt32_fccType=1935960438;//vids
privateUInt32_fccHandler=808810089;//IV50
privateBitmap_bmp;
[DllImport(AVIFILE32)]
privatestaticexternvoidAVIFileInit();
[DllImport(AVIFILE32)]
privatestaticexternintAVIFileOpenW(refintptr_pfile,[MarshalAs(UnmanagedType.LPWStr)]stringfileName,intflags,intdummy);
[DllImport(AVIFILE32)]
privatestaticexternintAVIFileCreateStream(intptr_pfile,outIntPtrptr_ptr_avi,refAVISTREAMINFOWptr_streaminfo);
[DllImport(AVIFILE32)]
privatestaticexternintAVIMakeCompressedStream(outIntPtrppsCompressed,IntPtraviStream,refAVICOMPRESSOPTIONSao,intdummy);
[DllImport(AVIFILE32)]
privatestaticexternintAVIStreamSetFormat(IntPtraviStream,Int32lPos,refBITMAPINFOHEADERlpFormat,Int32cbFormat);
[DllImport(AVIFILE32)]
unsafeprivatestaticexternintAVISaveOptions(inthwnd,UInt32flags,intnStreams,IntPtr*ptr_ptr_avi,AVICOMPRESSOPTIONS**ao);
[DllImport(AVIFILE32)]
privatestaticexternintAVIStreamWrite(IntPtraviStream,Int32lStart,Int32lSamples,IntPtrlpBuffer,Int32cbBuffer,Int32dwFlags,Int32dummy1,Int32dummy2);
[DllImport(AVIFILE32)]
privatestaticexternintAVIStreamRelease(IntPtraviStream);
[DllImport(AVIFILE32)]
privatestaticexternintAVIFileRelease(intpfile);
[DllImport(AVIFILE32)]
privatestaticexternvoidAVIFileExit();
[StructLayout(LayoutKind.Sequential,Pack=1)]
privatestructAVISTREAMINFOW
...{
publicUInt32fccType;
publicUInt32fccHandler;
publicUInt32dwFlags;
publicUInt32dwCaps;
publicUInt16wPriority;
publicUInt16wLanguage;
publicUInt32dwScale;
publicUInt32dwRate;
publicUInt32dwStart;
publicUInt32dwLength;
publicUInt32dwInitialFrames;
publicUInt32dwSuggestedBufferSize;
publicUInt32dwQuality;
publicUInt32dwSampleSize;
publicUInt32rect_left;
publicUInt32rect_top;
publicUInt32rect_right;
publicUInt32rect_bottom;
publicUInt32dwEditCount;
publicUInt32dwFormatChangeCount;
publicUInt16szName0;
publicUInt16szName1;
publicUInt16szName2;
publicUInt16szName3;
publicUInt16szName4;
publicUInt16szName5;
publicUInt16szName6;
publicUInt16szName7;
publicUInt16szName8;
publicUInt16szName9;
publicUInt16szName10;
publicUInt16szName11;
publicUInt16szName12;
publicUInt16szName13;
publicUInt16szName14;
publicUInt16szName15;
publicUInt16szName16;
publicUInt16szName17;
publicUInt16szName18;
publicUInt16szName19;
publicUInt16szName20;
publicUInt16szName21;
publicUInt16szName22;
publicUInt16szName23;
publicUInt16szName24;
publicUInt16szName25;
publicUInt16szName26;
publicUInt16szName27;
publicUInt16szName28;
publicUInt16szName29;
publicUInt16szName30;
publicUInt16szName31;
publicUInt16szName32;
publicUInt16szName33;
publicUInt16szName34;
publicUInt16szName35;
publicUInt16szName36;
publicUInt16szName37;
publicUInt16szName38;
publicUInt16szName39;
publicUInt16szName40;
publicUInt16szName41;
publicUInt16szName42;
publicUInt16szName43;
publicUInt16szName44;
publicUInt16szName45;
publicUInt16szName46;
publicUInt16szName47;
publicUInt16szName48;
publicUInt16szName49;
publicUInt16szName50;
publicUInt16szName51;
publicUInt16szName52;
publicUInt16szName53;
publicUInt16szName54;
publicUInt16szName55;
publicUInt16szName56;
publicUInt16szName57;
publicUInt16szName58;
publicUInt16szName59;
publicUInt16szName60;
publicUInt16szName61;
publicUInt16szName62;
publicUInt16szName63;
}
[StructLayout(LayoutKind.Sequential,Pack=1)]
privatestructAVICOMPRESSOPTIONS
...{
publicUInt32fccType;
publicUInt32fccHandler;
publicUInt32dwKeyFrameEvery;
publicUInt32dwQuality;
publicUInt32dwBytesPerSecond;
publicUInt32dwFlags;
publicIntPtrlpFormat;
publicUInt32cbFormat;
publicIntPtrlpParms;
publicUInt32cbParms;
publicUInt32dwInterleaveEvery;
}
[StructLayout(LayoutKind.Sequential,Pack=1)]
publicstructBITMAPINFOHEADER
...{
publicUInt32biSize;
publicInt32biWidth;
publicInt32biHeight;
publicInt16biPlanes;
publicInt16biBitCount;
publicUInt32biCompression;
publicUInt32biSizeImage;
publicInt32biXPelsPerMeter;
publicInt32biYPelsPerMeter;
publicUInt32biClrUsed;
publicUInt32biClrImportant;
}
publicclassAviException:ApplicationException
...{
publicAviException(strings):base(s)...{}
publicAviException(strings,Int32hr)
:base(s)
...{
if(hr==AVIERR_BADPARAM)
...{
err_msg="AVIERR_BADPARAM";
}
else
...{
err_msg="unknown";
}
}
publicstringErrMsg()
...{
returnerr_msg;
}
privateconstInt32AVIERR_BADPARAM=-2147205018;
privatestringerr_msg;
}
publicBitmapCreate(stringfileName,UInt32frameRate,intwidth,int
height)
...{
_frameRate=frameRate;
_width=(UInt32)width;
_height=(UInt32)height;
_bmp=newBitmap(width,height,PixelFormat.Format24bppRgb);
//锁定为24位位图
BitmapDatabmpDat=_bmp.LockBits(newRectangle(0,0,width,
height),ImageLockMode.ReadOnly,PixelFormat.Format24bppRgb);
_stride=(UInt32)bmpDat.Stride;
_bmp.UnlockBits(bmpDat);
AVIFileInit();
inthr=AVIFileOpenW(ref_pfile,fileName,4097,0);
if(hr!=0)
...{
thrownewAviException("Create错误!");
}
CreateStream();
SetOptions();
return_bmp;
}
publicvoidAddFrame()
...{
BitmapDatabmpDat=_bmp.LockBits(
newRectangle(0,0,(int)_width,(int)_height),
ImageLockMode.ReadOnly,PixelFormat.Format24bppRgb);
inthr=AVIStreamWrite(_psCompressed,_count,1,
bmpDat.Scan0,
(Int32)(_stride*_height),
0,
0,
0);
if(hr!=0)
...{
thrownewAviException("AVIStreamWrite");
}
_bmp.UnlockBits(bmpDat);
_count++;
}
publicvoidLoadFrame(Bitmapnextframe)
...{
_bmp=newBitmap(nextframe);
}
publicvoidClose()
...{
AVIStreamRelease(_ps);
AVIStreamRelease(_psCompressed);
AVIFileRelease(_pfile);
AVIFileExit();
}
/**////<summary>
///创建流文件
///</summary>
privatevoidCreateStream()
...{
AVISTREAMINFOWstrhdr=newAVISTREAMINFOW();
strhdr.fccType=_fccType;
strhdr.fccHandler=_fccHandler;
strhdr.dwFlags=0;
strhdr.dwCaps=0;
strhdr.wPriority=0;
strhdr.wLanguage=0;
strhdr.dwScale=1;
strhdr.dwRate=_frameRate;
strhdr.dwStart=0;
strhdr.dwLength=0;
strhdr.dwInitialFrames=0;
strhdr.dwSuggestedBufferSize=_height*_stride;
strhdr.dwQuality=0xffffffff;
strhdr.dwSampleSize=0;
strhdr.rect_top=0;
strhdr.rect_left=0;
strhdr.rect_bottom=_height;
strhdr.rect_right=_width;
strhdr.dwEditCount=0;
strhdr.dwFormatChangeCount=0;
strhdr.szName0=0;
strhdr.szName1=0;
inthr=AVIFileCreateStream(_pfile,out_ps,refstrhdr);
if(hr!=0)
...{
thrownewAviException("AVIFileCreateStream");
}
}
/**////<summary>
///设置参数
///</summary>
unsafeprivatevoidSetOptions()
...{
AVICOMPRESSOPTIONSopts=newAVICOMPRESSOPTIONS();
opts.fccType=_fccType;
opts.fccHandler=0;
opts.dwKeyFrameEvery=0;
opts.dwQuality=0;
opts.dwFlags=0;
opts.dwBytesPerSecond=0;
opts.lpFormat=newIntPtr(0);
opts.cbFormat=0;
opts.lpParms=newIntPtr(0);
opts.cbParms=0;
opts.dwInterleaveEvery=0;
AVICOMPRESSOPTIONS*p=&opts;
AVICOMPRESSOPTIONS**pp=&p;
IntPtrx=_ps;
IntPtr*ptr_ps=&x;
AVISaveOptions(0,0,1,ptr_ps,pp);
inthr=AVIMakeCompressedStream(out_psCompressed,_ps,ref
opts,0);
if(hr!=0)
...{
thrownewAviException("AVIMakeCompressedStream");
}
BITMAPINFOHEADERbi=newBITMAPINFOHEADER();
bi.biSize=40;
bi.biWidth=(Int32)_width;
bi.biHeight=(Int32)_height;
bi.biPlanes=1;
bi.biBitCount=24;
bi.biCompression=0;
bi.biSizeImage=_stride*_height;
bi.biXPelsPerMeter=0;
bi.biYPelsPerMeter=0;
bi.biClrUsed=0;
bi.biClrImportant=0;
hr=AVIStreamSetFormat(_psCompressed,0,refbi,40);
if(hr!=0)
...{
thrownewAviException("AVIStreamSetFormat",hr);
}
}
};
}
运行:
org.loon.util.FileUtilfile
=
new
org.loon.util.FileUtil();
org.loon.util.AVIWriteraviWriter = new org.loon.util.AVIWriter();
// ps:avi中所有图像皆不能小于width及height
Bitmapavi_frame = aviWriter.Create( " d:/mytest.avi " , 1 , 700 , 700 );
// 获得指定目录下文件列表的list
IListlist = file.ListFile( " D:/罗德岛战记/罗德岛战记1/ " );
foreach ( string s in list)
... {
//获得图像
Bitmapcache=newBitmap("D:/罗德岛战记/罗德岛战记1/"+s);
//由于转化为avi后呈现相反,所以翻转
cache.RotateFlip(RotateFlipType.Rotate180FlipX);
//载入图像
aviWriter.LoadFrame(cache);
aviWriter.AddFrame();
}
// 释放资源
aviWriter.Close();
avi_frame.Dispose();
org.loon.util.AVIWriteraviWriter = new org.loon.util.AVIWriter();
// ps:avi中所有图像皆不能小于width及height
Bitmapavi_frame = aviWriter.Create( " d:/mytest.avi " , 1 , 700 , 700 );
// 获得指定目录下文件列表的list
IListlist = file.ListFile( " D:/罗德岛战记/罗德岛战记1/ " );
foreach ( string s in list)
... {
//获得图像
Bitmapcache=newBitmap("D:/罗德岛战记/罗德岛战记1/"+s);
//由于转化为avi后呈现相反,所以翻转
cache.RotateFlip(RotateFlipType.Rotate180FlipX);
//载入图像
aviWriter.LoadFrame(cache);
aviWriter.AddFrame();
}
// 释放资源
aviWriter.Close();
avi_frame.Dispose();
播放画面如下:
生成的文件属性如下,与我们设定的参数相符:
是 不是很简单?实际上,借助于avifile32 api,我们甚至可以改变文件压缩格式,加入背景音乐,乃至植入病毒(咳,通常我们结合桌面截图及avi生成还有模拟键盘,就可以远程操作或者监控、记录 电脑操作……)总之,在windows下操作avi文件是一件再简单没有的事情了。
有兴趣的话可以这两篇博文为基础,将其修改为自己的字幕组工具、屏幕录像工具、乃至远程监控工具等。有疑问的话,可以发email到:ceponline@yahoo.com.cn