示例#1
0
文件: VfW.cs 项目: johnsewell/APE
        public static Bitmap Open(string fileName, int width, int height, PixelFormat format)
        {
            // Make sure any previous file is closed
            Close();

            bool   success   = false;
            Bitmap theBitmap = new Bitmap(width, height, format);

            // Get the actual stride
            BitmapData bmpData = theBitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, theBitmap.PixelFormat);

            m_Stride = bmpData.Stride;
            theBitmap.UnlockBits(bmpData);

            try
            {
                // create new file
                if (NM.AVIFileOpen(out m_File, fileName, NM.OpenFileMode.Create | NM.OpenFileMode.Write, IntPtr.Zero) != 0)
                {
                    throw new Exception("Failed to create the file");
                }

                m_Width  = width;
                m_Height = height;

                // describe new stream
                NM.AVISTREAMINFO info = new NM.AVISTREAMINFO();

                info.fccType               = mmioFOURCC("vids");
                info.fccHandler            = mmioFOURCC(m_Codec);
                info.dwScale               = 1;
                info.dwRate                = FrameRate;
                info.dwSuggestedBufferSize = m_Stride * height;

                // create stream
                if (NM.AVIFileCreateStream(m_File, out m_Stream, ref info) != 0)
                {
                    throw new Exception("Failed to create the stream");
                }

                // describe compression options
                NM.AVICOMPRESSOPTIONS options = new NM.AVICOMPRESSOPTIONS();

                options.fccHandler      = mmioFOURCC(m_Codec);
                options.dwQuality       = Quality * 100;
                options.dwKeyFrameEvery = KeyFrameEvery;
                if (options.dwKeyFrameEvery == 0)
                {
                    options.dwFlags = NM.AviCompression.AVICOMPRESSF_VALID;
                }
                else
                {
                    options.dwFlags = NM.AviCompression.AVICOMPRESSF_KEYFRAMES | NM.AviCompression.AVICOMPRESSF_VALID;
                }

                // Create the compressed stream
                if (NM.AVIMakeCompressedStream(out m_StreamCompressed, m_Stream, ref options, IntPtr.Zero) != 0)
                {
                    throw new Exception("Failed  to create the compressed stream");
                }

                // Create the header for the frame format
                NM.BITMAPINFOHEADER bitmapInfoHeader = new NM.BITMAPINFOHEADER();

                bitmapInfoHeader.biSize        = Marshal.SizeOf(typeof(NM.BITMAPINFOHEADER));
                bitmapInfoHeader.biWidth       = width;
                bitmapInfoHeader.biHeight      = height;
                bitmapInfoHeader.biPlanes      = 1;
                bitmapInfoHeader.biBitCount    = (short)Image.GetPixelFormatSize(format);
                bitmapInfoHeader.biSizeImage   = 0;
                bitmapInfoHeader.biCompression = 0; // BI_RGB

                // Write the header
                if (NM.AVIStreamSetFormat(m_StreamCompressed, 0, ref bitmapInfoHeader, bitmapInfoHeader.biSize) != 0)
                {
                    throw new Exception("Failed to set the compressed stream format");
                }

                // alloc unmanaged memory for the flipped frame buffer
                m_FlippedFrameBuffer = Marshal.AllocHGlobal(m_Stride * height);

                if (m_FlippedFrameBuffer == IntPtr.Zero)
                {
                    throw new Exception("Failed to allocate memory for the flipped frame buffer");
                }

                m_CurrentFrame = 0;
                success        = true;
            }
            finally
            {
                if (!success)
                {
                    Close();
                }
            }

            return(theBitmap);
        }