C#转换AVI文件为BMP文件

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>

 public class AVIUtil{
                   [StructLayout(LayoutKind.Sequential, Pack 
= 1)]
                       
struct BITMAPFILEHEADER
                   
{
                       
public ushort bfType;
                       
public uint bfSize;
                       
public ushort bfReserved1;
                       
public ushort bfReserved2;
                       
public uint bfOffBits;
                   }


                   [StructLayout(LayoutKind.Sequential, Pack 
= 1)]
                       
struct BITMAPINFOHEADER
                   
{
                       
public uint biSize;
                       
public int biWidth;
                       
public int biHeight;
                       
public ushort biPlanes;
                       
public ushort biBitCount;
                       
public uint biCompression;
                       
public uint biSizeImage;
                       
public int biXPelsPerMeter;
                       
public int biYPelsPerMeter;
                       
public uint biClrUsed;
                       
public uint biClrImportant;
                       
public const int BI_RGB = 0;
                   }


                   
const uint DIB_RGB_COLORS = 0;

                   
const uint DIB_PAL_COLORS = 1

            
/// <summary>
            
/// 对象转换
            
/// </summary>
            
/// <param name="pBITMAPINFOHEADER"></param>
            
/// <returns></returns>

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

                           MemoryStream stream 
= new MemoryStream();
                           BinaryWriter bw 
= new BinaryWriter(stream);
                           
byte[] data = new byte[sizeof(BITMAPFILEHEADER)];
                           Marshal.Copy((IntPtr)(
&pbmfi), data, 0, data.Length);
                           bw.Write(data);

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

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

                           
return new Bitmap(bw.BaseStream);
                       }

                   }

               }


        
/// <summary>
        
/// AviFile,用于AVI文件处理
        
/// </summary>

        public class AviFile : IDisposable
        
{
            
const string AVIFILE32 = "AVIFIL32";
            
const int AVIGETFRAMEF_BESTDISPLAYFMT = 1;

            
internal enum OpenFileFlags : 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)]
            
extern internal static void AVIFileInit();

            [DllImport(AVIFILE32)]
            
extern internal static void AVIFileExit();

            [DllImport(AVIFILE32)]
            
extern internal static uint AVIFileOpen(out IntPtr ppfile, string szFile, OpenFileFlags mode, IntPtr pclsidHandler);

            [DllImport(AVIFILE32)]
            
extern internal static int AVIFileRelease(IntPtr pfile);

            [DllImport(AVIFILE32)]
            
extern internal static uint AVIFileGetStream(IntPtr pfile, out IntPtr ppavi, uint fccType, int lParam);

            [DllImport(AVIFILE32)]
            
extern internal static int AVIStreamRelease(IntPtr pavi);

            [DllImport(AVIFILE32)]
            
extern internal static IntPtr AVIStreamGetFrameOpen(IntPtr pavi, int lpbiWanted);

            [DllImport(AVIFILE32)]
            
extern internal static IntPtr AVIStreamGetFrame(IntPtr pgf, int lPos);

            [DllImport(AVIFILE32)]
            
extern internal static int AVIStreamLength(IntPtr pavi);

            [DllImport(AVIFILE32)]
            
extern internal static uint AVIStreamGetFrameClose(IntPtr pget);


            
static uint mmioFOURCC(char c0, char c1, char c2, char c3)
            
{
                
return (uint)c3 << 24 | (uint)c2 << 16 | (uint)c1 << 8 | (uint)c0;
            }


            
static readonly uint streamtypeVIDEO = mmioFOURCC('v''i''d''s');
            
static readonly uint streamtypeAUDIO = mmioFOURCC('a''u''d''s');
            
static readonly uint streamtypeMIDI = mmioFOURCC('m''i''d''s');
            
static readonly uint streamtypeTEXT = mmioFOURCC('t''x''t''s');

            IntPtr aviFile 
= IntPtr.Zero;
            IntPtr aviStream 
= IntPtr.Zero;
            
bool disposed = false;

            
public static void Initialize()
            
{
                AVIFileInit();
            }


            
public static void Terminate()
            
{
                AVIFileExit();
            }


            
public AviFile(string filename)
            
{
                
uint result;
                result 
= AVIFileOpen(out aviFile, filename, OpenFileFlags.OF_READ, IntPtr.Zero);
                
if (result != 0)
                
{
                    Release();
                    
throw new Exception("AVIFileOpen failure.");
                }


                result 
= AVIFileGetStream(aviFile, out aviStream, streamtypeVIDEO, 0);
                
if (result != 0)
                
{
                    Release();
                    
throw new Exception("AVIFileGetStream failure.");
                }

            }


            
~AviFile()
            
{
                Dispose(
false);
            }


            
void Release()
            
{
                
if (aviStream != IntPtr.Zero)
                
{
                    AVIStreamRelease(aviStream);
                    aviStream 
= IntPtr.Zero;
                }


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

            }


            
public int GetMaxFrameCount()
            
{
                
if (aviStream == IntPtr.Zero)
                    
throw new InvalidOperationException();
                
return AVIStreamLength(aviStream);
            }


            
public Bitmap GetFrame(int no)
            
{
                
if (aviStream == IntPtr.Zero)
                    
throw new InvalidOperationException();

                IntPtr frame 
= IntPtr.Zero;
                
try
                
{
                    frame 
= AVIStreamGetFrameOpen(aviStream, AVIGETFRAMEF_BESTDISPLAYFMT);
                    IntPtr pbmi 
= AVIStreamGetFrame(frame, no);
                    
return org.loon.util.AVIUtil.ToBitmap(pbmi);

                }

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

            }


            
protected void Dispose(bool disposing)
            
{
                
if (disposed)
                    
return;
                disposed 
= true;
                Release();
            }


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


        }

    
}


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

                
using  (org.loon.util.AviFile avi  =   new  org.loon.util.AviFile(filename))
                
{
                    
int max = avi.GetMaxFrameCount();
                    
for (int i = 0; i < max; ++i)
                    
{
                        Bitmap bmp 
= avi.GetFrame(i);
                        bmp.Save(
"d:/test/"++ ".bmp");
                        bmp.Dispose();
                    }

                }

                                
// 完成
                org.loon.util.AviFile.Terminate();

你可能感兴趣的:(C#)