public void ExportToArray(int position, out byte[] bitmapData, out int width, out int height, out int bit_count) { if (position > countFrames) { throw new Exception("Invalid frame position"); } //Decompress the frame and return a pointer to the DIB int pDib = VFW.AVIStreamGetFrame(getFrameObject, firstFrame + position); //Copy the bitmap header into a managed struct BITMAPINFOHEADER bih = new BITMAPINFOHEADER(); bih = (BITMAPINFOHEADER)Marshal.PtrToStructure(new IntPtr(pDib), bih.GetType()); if (bih.biSizeImage < 1) { throw new Exception("Exception in AVIStreamGetFrame: Not bitmap decompressed."); } //Copy the image bitmapData = new byte[bih.biSizeImage]; int address = pDib + Marshal.SizeOf(bih); Marshal.Copy(new IntPtr(address), bitmapData, 0, bitmapData.Length); width = bih.biWidth; height = bih.biHeight; bit_count = bih.biBitCount; }
public Bitmap Export(int position) { if (position > countFrames) { throw new Exception("Invalid frame position"); } //Decompress the frame and return a pointer to the DIB int pDib = VFW.AVIStreamGetFrame(getFrameObject, firstFrame + position); if (pDib == 0) { //throw new Exception( "AVIStreamGetFrame; failed" ); return(null); } //Copy the bitmap header into a managed struct BITMAPINFOHEADER bih = new BITMAPINFOHEADER(); bih = (BITMAPINFOHEADER)Marshal.PtrToStructure(new IntPtr(pDib), bih.GetType()); if (bih.biSizeImage < 1) { throw new Exception("Exception in AVIStreamGetFrame: Not bitmap decompressed."); } Bitmap result = new Bitmap(bih.biWidth, bih.biHeight); BitmapData dat = result.LockBits( new Rectangle(0, 0, bih.biWidth, bih.biHeight), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); //Copy the image int address = pDib + Marshal.SizeOf(bih); int length = dat.Stride * dat.Height; byte[] target = new byte[length]; Marshal.Copy(new IntPtr(address), target, 0, length); Marshal.Copy(target, 0, dat.Scan0, length); result.UnlockBits(dat); result.RotateFlip(RotateFlipType.RotateNoneFlipY); return(result); }
/// <summary> /// Create new AVI file and open it for writing. /// </summary> /// /// <param name="fileName">AVI file name to create.</param> /// <param name="width">Video width.</param> /// <param name="height">Video height.</param> /// /// <remarks><para>The method opens (creates) a video files, configure video codec and prepares /// the stream for saving video frames with a help of <see cref="AddFrame"/> method.</para></remarks> /// /// <exception cref="System.IO.IOException">Failed opening the specified file.</exception> /// <exception cref="VideoException">A error occurred while creating new video file. See exception message.</exception> /// <exception cref="OutOfMemoryException">Insufficient memory for internal buffer.</exception> /// <exception cref="ArgumentException">Video file resolution must be a multiple of two.</exception> public void Open() { // close previous file Close(); this.width = Options.CaptureArea.Width; this.height = Options.CaptureArea.Height; // check width and height if (((width & 1) != 0) || ((height & 1) != 0)) { throw new ArgumentException("Video file resolution must be a multiple of two."); } bool success = false; try { lock (sync) { // calculate stride stride = width * 3; if ((stride % 4) != 0) { stride += (4 - stride % 4); } // create new file if (NativeMethods.AVIFileOpen(out file, Options.OutputPath, OpenFileMode.Create | OpenFileMode.Write, IntPtr.Zero) != 0) { throw new IOException("Failed opening the specified file."); } this.rate = Options.ScreenRecordFPS; // describe new stream AVISTREAMINFO info = new AVISTREAMINFO(); info.type = NativeMethods.mmioFOURCC("vids"); info.handler = NativeMethods.mmioFOURCC("DIB "); info.scale = 1; info.rate = rate; info.suggestedBufferSize = stride * height; // create stream if (NativeMethods.AVIFileCreateStream(file, out stream, ref info) != 0) { throw new Exception("Failed creating stream."); } if (Options.AVI.CompressOptions.handler == 0) { // describe compression options Options.AVI.CompressOptions.handler = NativeMethods.mmioFOURCC("DIB "); } if (Options.ShowAVIOptionsDialog) { AVICOMPRESSOPTIONS options = new AVICOMPRESSOPTIONS(); options.handler = Options.AVI.CompressOptions.handler; options.quality = Options.AVI.CompressOptions.quality; options.flags = 8; // AVICOMPRESSF_VALID int result = NativeMethods.AVISaveOptions(stream, ref options, Options.ParentWindow); if (result == 1) { Options.AVI.CompressOptions = options; } } // create compressed stream if (NativeMethods.AVIMakeCompressedStream(out streamCompressed, stream, ref Options.AVI.CompressOptions, IntPtr.Zero) != 0) { throw new Exception("Failed creating compressed stream."); } // describe frame format BITMAPINFOHEADER bitmapInfoHeader = new BITMAPINFOHEADER(width, height, 24); // set frame format if (NativeMethods.AVIStreamSetFormat(streamCompressed, 0, ref bitmapInfoHeader, Marshal.SizeOf(bitmapInfoHeader.GetType())) != 0) { throw new Exception("Failed setting format of the compressed stream."); } // alloc unmanaged memory for frame buffer = Marshal.AllocHGlobal(stride * height); if (buffer == IntPtr.Zero) { throw new OutOfMemoryException("Insufficient memory for internal buffer."); } position = 0; success = true; } } finally { if (!success) { Close(); } } }
/// <summary>Exports a frame into a bitmap file</summary> /// <param name="position">Position of the frame</param> /// <param name="dstFileName">Name ofthe file to store the bitmap</param> public void ExportBitmap(int position, String dstFileName) { if (position > countFrames) { throw new Exception("Invalid frame position"); } //Decompress the frame and return a pointer to the DIB int pDib = VFW.AVIStreamGetFrame(getFrameObject, firstFrame + position); //Copy the bitmap header into a managed struct BITMAPINFOHEADER bih = new BITMAPINFOHEADER(); bih = (BITMAPINFOHEADER)Marshal.PtrToStructure(new IntPtr(pDib), bih.GetType()); /*if(bih.biBitCount < 24){ * throw new Exception("Not enough colors! DIB color depth is less than 24 bit."); * }else */ if (bih.biSizeImage < 1) { throw new Exception("Exception in AVIStreamGetFrame: Not bitmap decompressed."); } //Copy the image byte[] bitmapData = new byte[bih.biSizeImage]; int address = pDib + Marshal.SizeOf(bih); for (int offset = 0; offset < bitmapData.Length; offset++) { bitmapData[offset] = Marshal.ReadByte(new IntPtr(address)); address++; } //Copy bitmap info byte[] bitmapInfo = new byte[Marshal.SizeOf(bih)]; IntPtr ptr; ptr = Marshal.AllocHGlobal(bitmapInfo.Length); Marshal.StructureToPtr(bih, ptr, false); address = ptr.ToInt32(); for (int offset = 0; offset < bitmapInfo.Length; offset++) { bitmapInfo[offset] = Marshal.ReadByte(new IntPtr(address)); address++; } //Create file header BITMAPFILEHEADER bfh = new BITMAPFILEHEADER(); bfh.bfType = Util.BMP_MAGIC_COOKIE; bfh.bfSize = (Int32)(55 + bih.biSizeImage); //size of file as written to disk bfh.bfReserved1 = 0; bfh.bfReserved2 = 0; bfh.bfOffBits = Marshal.SizeOf(bih) + Marshal.SizeOf(bfh); //Create or overwrite the destination file FileStream fs = new FileStream(dstFileName, System.IO.FileMode.Create); BinaryWriter bw = new BinaryWriter(fs); //Write header bw.Write(bfh.bfType); bw.Write(bfh.bfSize); bw.Write(bfh.bfReserved1); bw.Write(bfh.bfReserved2); bw.Write(bfh.bfOffBits); //Write bitmap info bw.Write(bitmapInfo); //Write bitmap data bw.Write(bitmapData); bw.Close(); fs.Close(); }
/// <summary>Exports a frame into a bitmap file</summary> /// <param name="position">Position of the frame</param> /// <param name="dstFileName">Name ofthe file to store the bitmap</param> public void ExportBitmap( int position, String dstFileName ) { if ( position > countFrames ) { throw new Exception( "Invalid frame position" ); } //Decompress the frame and return a pointer to the DIB int pDib = VFW.AVIStreamGetFrame( getFrameObject, firstFrame + position ); //Copy the bitmap header into a managed struct BITMAPINFOHEADER bih = new BITMAPINFOHEADER(); bih = (BITMAPINFOHEADER)Marshal.PtrToStructure( new IntPtr( pDib ), bih.GetType() ); /*if(bih.biBitCount < 24){ throw new Exception("Not enough colors! DIB color depth is less than 24 bit."); }else */ if ( bih.biSizeImage < 1 ) { throw new Exception( "Exception in AVIStreamGetFrame: Not bitmap decompressed." ); } //Copy the image byte[] bitmapData = new byte[bih.biSizeImage]; int address = pDib + Marshal.SizeOf( bih ); for ( int offset = 0; offset < bitmapData.Length; offset++ ) { bitmapData[offset] = Marshal.ReadByte( new IntPtr( address ) ); address++; } //Copy bitmap info byte[] bitmapInfo = new byte[Marshal.SizeOf( bih )]; IntPtr ptr; ptr = Marshal.AllocHGlobal( bitmapInfo.Length ); Marshal.StructureToPtr( bih, ptr, false ); address = ptr.ToInt32(); for ( int offset = 0; offset < bitmapInfo.Length; offset++ ) { bitmapInfo[offset] = Marshal.ReadByte( new IntPtr( address ) ); address++; } //Create file header BITMAPFILEHEADER bfh = new BITMAPFILEHEADER(); bfh.bfType = Util.BMP_MAGIC_COOKIE; bfh.bfSize = (Int32)(55 + bih.biSizeImage); //size of file as written to disk bfh.bfReserved1 = 0; bfh.bfReserved2 = 0; bfh.bfOffBits = Marshal.SizeOf( bih ) + Marshal.SizeOf( bfh ); //Create or overwrite the destination file FileStream fs = new FileStream( dstFileName, System.IO.FileMode.Create ); BinaryWriter bw = new BinaryWriter( fs ); //Write header bw.Write( bfh.bfType ); bw.Write( bfh.bfSize ); bw.Write( bfh.bfReserved1 ); bw.Write( bfh.bfReserved2 ); bw.Write( bfh.bfOffBits ); //Write bitmap info bw.Write( bitmapInfo ); //Write bitmap data bw.Write( bitmapData ); bw.Close(); fs.Close(); }
public unsafe void Export( Bitmap bmp, int position ) { if ( position > countFrames ) { throw new Exception( "Invalid frame position" ); } //Decompress the frame and return a pointer to the DIB int pDib = VFW.AVIStreamGetFrame( getFrameObject, firstFrame + position ); if ( pDib == 0 ) { //throw new Exception( "AVIStreamGetFrame; failed" ); return; } //Copy the bitmap header into a managed struct BITMAPINFOHEADER bih = new BITMAPINFOHEADER(); bih = (BITMAPINFOHEADER)Marshal.PtrToStructure( new IntPtr( pDib ), bih.GetType() ); if ( bih.biSizeImage < 1 ) { throw new Exception( "Exception in AVIStreamGetFrame: Not bitmap decompressed." ); } BitmapData dat = bmp.LockBits( new Rectangle( 0, 0, bih.biWidth, bih.biHeight ), ImageLockMode.WriteOnly, bmp.PixelFormat ); //Copy the image int address = pDib + Marshal.SizeOf( bih ); int length = dat.Stride * dat.Height; byte[] target = new byte[length]; Marshal.Copy( new IntPtr( address ), target, 0, length ); Marshal.Copy( target, 0, dat.Scan0, length ); bmp.UnlockBits( dat ); bmp.RotateFlip( RotateFlipType.RotateNoneFlipY ); }
public void ExportToArray( int position, out byte[] bitmapData, out int width, out int height, out int bit_count ) { if ( position > countFrames ) { throw new Exception( "Invalid frame position" ); } //Decompress the frame and return a pointer to the DIB int pDib = VFW.AVIStreamGetFrame( getFrameObject, firstFrame + position ); //Copy the bitmap header into a managed struct BITMAPINFOHEADER bih = new BITMAPINFOHEADER(); bih = (BITMAPINFOHEADER)Marshal.PtrToStructure( new IntPtr( pDib ), bih.GetType() ); if ( bih.biSizeImage < 1 ) { throw new Exception( "Exception in AVIStreamGetFrame: Not bitmap decompressed." ); } //Copy the image bitmapData = new byte[bih.biSizeImage]; int address = pDib + Marshal.SizeOf( bih ); Marshal.Copy( new IntPtr( address ), bitmapData, 0, bitmapData.Length ); width = bih.biWidth; height = bih.biHeight; bit_count = bih.biBitCount; }