码迷,mamicode.com
首页 > Windows程序 > 详细

C#将图像文件压缩为AVI文件播放

时间:2015-05-15 13:23:36      阅读:195      评论:0      收藏:0      [点我收藏+]

标签:

using System;
using System.Runtime.InteropServices;
using System.Drawing;
using System.Drawing.Imaging;

namespace AVI
{
    /**//// <summary>
    /// AVIWriter 的摘要说明,chenpeng,Email:ceponline@yahoo.com.cn。
    /// </summary>
    public class AVIWriter
    {
        const string AVIFILE32 = "AVIFIL32";
        private int _pfile = 0;
        private IntPtr _ps = new IntPtr(0);
        private IntPtr _psCompressed = new IntPtr(0);
        private UInt32 _frameRate = 0;
        private int _count = 0;
        private UInt32 _width = 0;
        private UInt32 _stride = 0;
        private UInt32 _height = 0;
        //avi标识
        private UInt32 _fccType = 1935960438; // vids
        private UInt32 _fccHandler = 808810089;// IV50
    
        private Bitmap _bmp;

        [DllImport(AVIFILE32)]
        private static extern void AVIFileInit();

        [DllImport(AVIFILE32)]
        private static extern int AVIFileOpenW(ref int ptr_pfile, [MarshalAs(UnmanagedType.LPWStr)]string fileName, int flags, int dummy);

        [DllImport(AVIFILE32)]
        private static extern int AVIFileCreateStream(int ptr_pfile, out IntPtr ptr_ptr_avi, ref AVISTREAMINFOW ptr_streaminfo);
        [DllImport(AVIFILE32)]
        private static extern int AVIMakeCompressedStream(out IntPtr ppsCompressed, IntPtr aviStream, ref AVICOMPRESSOPTIONS ao, int dummy);

        [DllImport(AVIFILE32)]
        private static extern int AVIStreamSetFormat(IntPtr aviStream, Int32 lPos, ref BITMAPINFOHEADER lpFormat, Int32 cbFormat);

        [DllImport(AVIFILE32)]
        unsafe private static extern int AVISaveOptions(int hwnd, UInt32 flags,int nStreams, IntPtr* ptr_ptr_avi, AVICOMPRESSOPTIONS** ao);

        [DllImport(AVIFILE32)]
        private static extern int AVIStreamWrite(IntPtr aviStream, Int32 lStart,Int32 lSamples, IntPtr lpBuffer, Int32 cbBuffer, Int32 dwFlags, Int32 dummy1, Int32 dummy2);

        [DllImport(AVIFILE32)]
        private static extern int AVIStreamRelease(IntPtr aviStream);

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

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

        [StructLayout(LayoutKind.Sequential, Pack = 1)]
            private struct AVISTREAMINFOW
        ...{
            public UInt32 fccType;
            public UInt32 fccHandler;
            public UInt32 dwFlags;
            public UInt32 dwCaps;
            public UInt16 wPriority;
            public UInt16 wLanguage;
            public UInt32 dwScale;
            public UInt32 dwRate;
            public UInt32 dwStart;
            public UInt32 dwLength;
            public UInt32 dwInitialFrames;
            public UInt32 dwSuggestedBufferSize;
            public UInt32 dwQuality;
            public UInt32 dwSampleSize;
            public UInt32 rect_left;
            public UInt32 rect_top;
            public UInt32 rect_right;
            public UInt32 rect_bottom;
            public UInt32 dwEditCount;
            public UInt32 dwFormatChangeCount;
            public UInt16 szName0;
            public UInt16 szName1;
            public UInt16 szName2;
            public UInt16 szName3;
            public UInt16 szName4;
            public UInt16 szName5;
            public UInt16 szName6;
            public UInt16 szName7;
            public UInt16 szName8;
            public UInt16 szName9;
            public UInt16 szName10;
            public UInt16 szName11;
            public UInt16 szName12;
            public UInt16 szName13;
            public UInt16 szName14;
            public UInt16 szName15;
            public UInt16 szName16;
            public UInt16 szName17;
            public UInt16 szName18;
            public UInt16 szName19;
            public UInt16 szName20;
            public UInt16 szName21;
            public UInt16 szName22;
            public UInt16 szName23;
            public UInt16 szName24;
            public UInt16 szName25;
            public UInt16 szName26;
            public UInt16 szName27;
            public UInt16 szName28;
            public UInt16 szName29;
            public UInt16 szName30;
            public UInt16 szName31;
            public UInt16 szName32;
            public UInt16 szName33;
            public UInt16 szName34;
            public UInt16 szName35;
            public UInt16 szName36;
            public UInt16 szName37;
            public UInt16 szName38;
            public UInt16 szName39;
            public UInt16 szName40;
            public UInt16 szName41;
            public UInt16 szName42;
            public UInt16 szName43;
            public UInt16 szName44;
            public UInt16 szName45;
            public UInt16 szName46;
            public UInt16 szName47;
            public UInt16 szName48;
            public UInt16 szName49;
            public UInt16 szName50;
            public UInt16 szName51;
            public UInt16 szName52;
            public UInt16 szName53;
            public UInt16 szName54;
            public UInt16 szName55;
            public UInt16 szName56;
            public UInt16 szName57;
            public UInt16 szName58;
            public UInt16 szName59;
            public UInt16 szName60;
            public UInt16 szName61;
            public UInt16 szName62;
            public UInt16 szName63;
        }

        [StructLayout(LayoutKind.Sequential, Pack = 1)]
            private struct AVICOMPRESSOPTIONS
        ...{
            public UInt32 fccType;
            public UInt32 fccHandler;
            public UInt32 dwKeyFrameEvery;
   
            public UInt32 dwQuality;
            public UInt32 dwBytesPerSecond;
       
            public UInt32 dwFlags;
            public IntPtr lpFormat;
            public UInt32 cbFormat;
            public IntPtr lpParms;
            public UInt32 cbParms;
            public UInt32 dwInterleaveEvery;
        }

        [StructLayout(LayoutKind.Sequential, Pack = 1)]
            public struct BITMAPINFOHEADER
           {
            public UInt32 biSize;
            public Int32 biWidth;
            public Int32 biHeight;
            public Int16 biPlanes;
            public Int16 biBitCount;
            public UInt32 biCompression;
            public UInt32 biSizeImage;
            public Int32 biXPelsPerMeter;
            public Int32 biYPelsPerMeter;
            public UInt32 biClrUsed;
            public UInt32 biClrImportant;
        }

        public class AviException : ApplicationException
        {
            public AviException(string s) : base(s) ...{ }
            public AviException(string s, Int32 hr)
                : base(s)
            {

                if (hr == AVIERR_BADPARAM)
                {
                    err_msg = "AVIERR_BADPARAM";
                }
                else
                {
                    err_msg = "unknown";
                }
            }

            public string ErrMsg()
            {
                return err_msg;
            }
            private const Int32 AVIERR_BADPARAM = -2147205018;
            private string err_msg;
        }

        public Bitmap Create(string fileName, UInt32 frameRate, int width, int
            height)
        {
            _frameRate = frameRate;
            _width = (UInt32)width;
            _height = (UInt32)height;
            _bmp = new Bitmap(width, height, PixelFormat.Format24bppRgb);
            //锁定为24位位图
            BitmapData bmpDat = _bmp.LockBits(new Rectangle(0, 0, width,
                height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
            _stride = (UInt32)bmpDat.Stride;
            _bmp.UnlockBits(bmpDat);
            AVIFileInit();
            int hr = AVIFileOpenW(ref _pfile, fileName, 4097, 0);
            if (hr != 0)
            {
                throw new AviException("Create错误!");
            }

            CreateStream();
            SetOptions();

            return _bmp;
        }

        public void AddFrame()
        {

            BitmapData bmpDat = _bmp.LockBits(
                new Rectangle(0, 0, (int)_width, (int)_height),
                ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);

            int hr = AVIStreamWrite(_psCompressed, _count, 1,
                bmpDat.Scan0,
                (Int32)(_stride * _height),
                0,
                0,
                0);

            if (hr != 0)
            {
                throw new AviException("AVIStreamWrite");
            }

            _bmp.UnlockBits(bmpDat);

            _count++;
        }

        public void LoadFrame(Bitmap nextframe)
        {

            _bmp = new Bitmap(nextframe);
        }

        public void Close()
        {
            AVIStreamRelease(_ps);
            AVIStreamRelease(_psCompressed);

            AVIFileRelease(_pfile);
            AVIFileExit();
        }

        /**//// <summary>
        /// 创建流文件
        /// </summary>
        private void CreateStream()
        {
            AVISTREAMINFOW strhdr = new AVISTREAMINFOW();
            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;

            int hr = AVIFileCreateStream(_pfile, out _ps, ref strhdr);

            if (hr != 0)
            {
                throw new AviException("AVIFileCreateStream");
            }
        }

        /**//// <summary>
        /// 设置参数
        /// </summary>
        unsafe private void SetOptions()
        {
            AVICOMPRESSOPTIONS opts = new AVICOMPRESSOPTIONS();
            opts.fccType = _fccType;
            opts.fccHandler = 0;
            opts.dwKeyFrameEvery = 0;
            opts.dwQuality = 0;
            opts.dwFlags = 0;
            opts.dwBytesPerSecond = 0;
            opts.lpFormat = new IntPtr(0);
            opts.cbFormat = 0;
            opts.lpParms = new IntPtr(0);
            opts.cbParms = 0;
            opts.dwInterleaveEvery = 0;

            AVICOMPRESSOPTIONS* p = &opts;
            AVICOMPRESSOPTIONS** pp = &p;

            IntPtr x = _ps;
            IntPtr* ptr_ps = &x;

            AVISaveOptions(0, 0, 1, ptr_ps, pp);

            int hr = AVIMakeCompressedStream(out _psCompressed, _ps, ref
                opts, 0);
            if (hr != 0)
            ...{
                throw new AviException("AVIMakeCompressedStream");
            }

            BITMAPINFOHEADER bi = new BITMAPINFOHEADER();
            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, ref bi, 40);
            if (hr != 0)
            {
                throw new AviException("AVIStreamSetFormat", hr);
            }
        }
    }
}

 

---------------------------------------------------------------------------------

 

        private void button1_Click(object sender, EventArgs e)

        {

            //FileUtil file = new FileUtil();

            AviFile_Library.AVIWriter aviWriter = new AviFile_Library.AVIWriter();

            Bitmap avi_frame = aviWriter.Create(@"d:\mytest.avi",1, 700, 700);

            /*

            //获得指定目录下文件列表的list

            IList list=file.ListFile(@"D:\pic\");

            foreach(string s in list)

            {

                //获得图像

                Bitmap cache=new Bitmap(@"D:\pic\"+s);

                //由于转化为avi后呈现相反,所以翻转

                cache.RotateFlip(RotateFlipType.Rotate180FlipX);

                //载入图像

                aviWriter.LoadFrame(cache);

                aviWriter.AddFrame();

            }

             */

            //获得图像

            Bitmap cache = new Bitmap(@"D:\pic\0502344516.jpg");

            //由于转化为avi后呈现相反,所以翻转

            cache.RotateFlip(RotateFlipType.Rotate180FlipX);

            //载入图像

            aviWriter.LoadFrame(cache);

            aviWriter.AddFrame();

            //释放资源

            aviWriter.Close();

            avi_frame.Dispose();

        }

    }

-------------------------------------------------------------

c#生成AVI自动设置压缩格式,不调用AVISaveOptions

最开始的代码:

 

 
AVICOMPRESSOPTIONS opts = new AVICOMPRESSOPTIONS();
opts.fccType = _fccType;
opts.fccHandler = 0;
opts.dwKeyFrameEvery = 0;
opts.dwQuality = 0;
opts.dwFlags = 0;
opts.dwBytesPerSecond = 0;
opts.lpFormat = new IntPtr(0);
opts.cbFormat = 0;
opts.lpParms = new IntPtr(0);
opts.cbParms = 0;
opts.dwInterleaveEvery = 0;
AVICOMPRESSOPTIONS* p = &opts;
AVICOMPRESSOPTIONS** pp = &p;
IntPtr x = _ps;
IntPtr* ptr_ps = &x;
AVISaveOptions(0, 0, 1, ptr_ps, pp);
int hr = AVIMakeCompressedStream(out _psCompressed, _ps, ref opts, 0);

修改后的代码

  opts.fccType = 0;

           opts.fccHandler = (int)0x6376736d;
           opts.dwKeyFrameEvery = 0;
           opts.dwQuality = 10000;
           opts.dwFlags = 8;
           opts.dwBytesPerSecond = 0;
           opts.lpFormat = new IntPtr(0);
           opts.cbFormat = 0;
           opts.lpParms = new IntPtr(0);
           opts.cbParms = 4;
           opts.dwInterleaveEvery = 0;
           AVICOMPRESSOPTIONS* p = &opts;
           AVICOMPRESSOPTIONS** pp = &p;
           IntPtr x = _ps;
           IntPtr* ptr_ps = &x;
           opts.lpParms = Marshal.AllocHGlobal(sizeof(int));
           //AVISaveOptions(0, 0, 1, ptr_ps, pp);
           int hr = AVIMakeCompressedStream(out _psCompressed, _ps, ref opts, 0);  

 

 

思路就是,Debug模式下,跟踪设置完压缩格式后
AVICOMPRESSOPTIONS结构体中各元素的值,其中lpParms需要利用
Marshal.AllocHGlobal(sizeof(int))来获取,其余根据监视的值设定即可
 
         

C#将图像文件压缩为AVI文件播放

标签:

原文地址:http://www.cnblogs.com/leewl/p/4505669.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!