public void GetFrameOpen() { //Open frames Avi.BITMAPINFOHEADER bih = new Avi.BITMAPINFOHEADER { biBitCount = BitsPerPixel, biClrImportant = 0, biClrUsed = 0, biCompression = 0, biPlanes = 1, biXPelsPerMeter = 0, biYPelsPerMeter = 0, biHeight = 0, biWidth = 0 }; bih.biSize = Marshal.SizeOf(bih); getFrameObject = NativeMethods.AVIStreamGetFrameOpen(StreamPointer, ref bih); if (getFrameObject == IntPtr.Zero) { throw new AviFileException("Exception in VideoStreamGetFrameOpen! Cannot find a decompressor."); } }
/// <summary>Prepare for decompressing frames</summary> /// <remarks> /// This method has to be called before GetBitmap and ExportBitmap. /// Release ressources with GetFrameClose. /// </remarks> public void GetFrameOpen() { Avi.AVISTREAMINFO streamInfo = GetStreamInfo(aviStream); //Open frames Avi.BITMAPINFOHEADER bih = new Avi.BITMAPINFOHEADER(); bih.biBitCount = countBitsPerPixel; bih.biClrImportant = 0; bih.biClrUsed = 0; bih.biCompression = 0; bih.biHeight = (Int32)streamInfo.rcFrame.bottom; bih.biWidth = (Int32)streamInfo.rcFrame.right; bih.biPlanes = 1; bih.biSize = Marshal.SizeOf(bih); bih.biXPelsPerMeter = 0; bih.biYPelsPerMeter = 0; getFrameObject = Avi.AVIStreamGetFrameOpen(aviStream, ref bih); if (getFrameObject == 0) { throw new Exception("Exception in VideoStreamGetFrameOpen!"); } }
/* * /// <summary>Export a frame into a bitmap</summary> * /// <param name="position">Position of the frame</param> * public Bitmap GetBitmap(int position){ * if(position > countFrames){ * throw new Exception("Invalid frame position: "+position); * } * * Avi.AVISTREAMINFO streamInfo = GetStreamInfo(StreamPointer); * * //Decompress the frame and return a pointer to the DIB * int dib = Avi.AVIStreamGetFrame(getFrameObject, firstFrame + position); * //Copy the bitmap header into a managed struct * Avi.BITMAPINFOHEADER bih = new Avi.BITMAPINFOHEADER(); * bih = (Avi.BITMAPINFOHEADER)Marshal.PtrToStructure(new IntPtr(dib), bih.GetType()); * * if(bih.biSizeImage < 1){ * throw new Exception("Exception in VideoStreamGetFrame"); * } * * //copy the image * * byte[] bitmapData; * int address = dib + Marshal.SizeOf(bih); * if(bih.biBitCount < 16){ * //copy palette and pixels * bitmapData = new byte[bih.biSizeImage + Avi.PALETTE_SIZE]; * }else{ * //copy only pixels * bitmapData = new byte[bih.biSizeImage]; * } * * Marshal.Copy(new IntPtr(address), bitmapData, 0, bitmapData.Length); * * //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(); * Marshal.Copy(new IntPtr(address), bitmapInfo, 0, bitmapInfo.Length); * * Marshal.FreeHGlobal(ptr); * * //create file header * Avi.BITMAPFILEHEADER bfh = new Avi.BITMAPFILEHEADER(); * bfh.bfType = Avi.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); * if(bih.biBitCount < 16){ * //There is a palette between header and pixel data * bfh.bfOffBits += Avi.PALETTE_SIZE; * } * * //write a bitmap stream * BinaryWriter bw = new BinaryWriter( new MemoryStream() ); * * //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); * * Bitmap bmp = (Bitmap)Image.FromStream(bw.BaseStream); * Bitmap saveableBitmap = new Bitmap(bmp.Width, bmp.Height); * Graphics g = Graphics.FromImage(saveableBitmap); * g.DrawImage(bmp, 0,0); * g.Dispose(); * bmp.Dispose(); * * bw.Close(); * return saveableBitmap; * }*/ public Bitmap GetBitmap(int position) { if (position > countFrames) { throw new Exception("Invalid frame position: " + position); } Avi.AVISTREAMINFO streamInfo = GetStreamInfo(aviStream); // Get the pointer to the BITMAPINFOHEADER int firstFrame = Avi.AVIStreamStart(aviStream.ToInt32()); IntPtr bitmapPtr = new IntPtr(Avi.AVIStreamGetFrame(getFrameObject, firstFrame + position)); // Copy into a BITMAPINFOHEADER structure Avi.BITMAPINFOHEADER bitmapInfo = (Avi.BITMAPINFOHEADER)Marshal.PtrToStructure(bitmapPtr, typeof(Avi.BITMAPINFOHEADER)); // Find the offset of the raw image data IntPtr imagePtr = new IntPtr(bitmapPtr.ToInt32() + bitmapInfo.biSize); // Determine the stride int stride = bitmapInfo.biSizeImage / bitmapInfo.biHeight; // Determine the pixel format PixelFormat pixelFormat = ConvertBitCountToPixelFormat(bitmapInfo.biBitCount); // Create a bitmap from the raw image data Bitmap bmp = new Bitmap(bitmapInfo.biWidth, bitmapInfo.biHeight, stride, pixelFormat, imagePtr); // Flip the bitmap vertically bmp.RotateFlip(RotateFlipType.RotateNoneFlipY); return(bmp); }
/// <summary>Prepare for decompressing frames</summary> /// <remarks> /// This method has to be called before GetBitmap and ExportBitmap. /// Release ressources with GetFrameClose. /// </remarks> public void GetFrameOpen() { Avi.AVISTREAMINFO streamInfo = GetStreamInfo(StreamPointer); //Open frames Avi.BITMAPINFOHEADER bih = new Avi.BITMAPINFOHEADER(); // bih.biBitCount = countBitsPerPixel; bih.biBitCount = 24; bih.biClrImportant = 0; bih.biClrUsed = 0; bih.biCompression = 0; bih.biPlanes = 1; bih.biSize = Marshal.SizeOf(bih); bih.biXPelsPerMeter = 0; bih.biYPelsPerMeter = 0; // Corrections by M. Covington: // If these are pre-set, interlaced video is not handled correctly. // Better to give zeroes and let Windows fill them in. bih.biHeight = 0; // was (Int32)streamInfo.rcFrame.bottom; bih.biWidth = 0; // was (Int32)streamInfo.rcFrame.right; // Corrections by M. Covington: // Validate the bit count, because some AVI files give a bit count // that is not one of the allowed values in a BitmapInfoHeader. // Here 0 means for Windows to figure it out from other information. if (bih.biBitCount > 24) { bih.biBitCount = 32; } else if (bih.biBitCount > 16) { bih.biBitCount = 24; } else if (bih.biBitCount > 8) { bih.biBitCount = 16; } else if (bih.biBitCount > 4) { bih.biBitCount = 8; } else if (bih.biBitCount > 0) { bih.biBitCount = 4; } getFrameObject = Avi.AVIStreamGetFrameOpen(StreamPointer, ref bih); if (getFrameObject == 0) { throw new Exception("Exception in VideoStreamGetFrameOpen!"); } }
public byte[] GetFrameData(int position) { if (position > FramesCount) { throw new AviFileException("Invalid frame position: " + position); } //Decompress the frame and return a pointer to the DIB IntPtr dib = NativeMethods.AVIStreamGetFrame(getFrameObject, FirstFrame + position); if (dib == IntPtr.Zero) { return(null); } //Copy the bitmap header into a managed struct Avi.BITMAPINFOHEADER bih = (Avi.BITMAPINFOHEADER)Marshal.PtrToStructure(dib, typeof(Avi.BITMAPINFOHEADER)); if (bih.biSizeImage < 1) { throw new AviFileException("Exception in VideoStreamGetFrame"); } //copy the image int framePaletteSize = bih.biClrUsed * Avi.RGBQUAD_SIZE; byte[] bitmapData = new byte[bih.biSizeImage]; IntPtr dibPointer = IntPtr.Add(dib, Marshal.SizeOf(bih) + framePaletteSize); Marshal.Copy(dibPointer, bitmapData, 0, bih.biSizeImage); // flip vertical int stride = this.Width * this.BitsPerPixel / 8; int length = stride * (this.Height - 1); int length2 = stride * this.Height / 2; for (int row = 0; row < length2; row += stride) { for (int i = 0; i < stride; i++) { byte b = bitmapData[row + i]; bitmapData[row + i] = bitmapData[length - row + i]; bitmapData[length - row + i] = b; } } return(bitmapData); }
/// <summary>Apply a format to a new stream</summary> /// <param name="aviStream">The IAVISTREAM</param> /// <remarks> /// The format must be set before the first frame can be written, /// and it cannot be changed later. /// </remarks> private void SetFormat(IntPtr aviStream) { Avi.BITMAPINFOHEADER bi = new Avi.BITMAPINFOHEADER(); bi.biSize = Marshal.SizeOf(bi); bi.biWidth = this.width; bi.biHeight = this.height; bi.biPlanes = 1; bi.biBitCount = this.countBitsPerPixel; bi.biSizeImage = this.frameSize; int result = Avi.AVIStreamSetFormat(aviStream, 0, ref bi, bi.biSize); if (result != 0) { throw new Exception("Error in VideoStreamSetFormat: " + result.ToString()); } }
/// <summary>Initialize a VideoStream for an existing stream</summary> /// <param name="aviFile">The file that contains the stream</param> /// <param name="aviStream">An IAVISTREAM from [aviFile]</param> public VideoStream(int aviFile, IntPtr aviStream) { this.aviFile = aviFile; this.aviStream = aviStream; Avi.BITMAPINFOHEADER bih = new Avi.BITMAPINFOHEADER(); int size = Marshal.SizeOf(bih); Avi.AVIStreamReadFormat(aviStream, 0, ref bih, ref size); Avi.AVISTREAMINFO streamInfo = this.GetStreamInfo(aviStream); this.frameRate = (float)streamInfo.dwRate / (float)streamInfo.dwScale; this.width = (int)streamInfo.rcFrame.right; this.height = (int)streamInfo.rcFrame.bottom; this.frameSize = bih.biSizeImage; this.countBitsPerPixel = bih.biBitCount; this.firstFrame = Avi.AVIStreamStart(aviStream.ToInt32()); this.countFrames = Avi.AVIStreamLength(aviStream.ToInt32()); }
/// <summary>Apply a format to a new stream</summary> /// <param name="aviStream">The IAVISTREAM</param> /// <remarks> /// The format must be set before the first frame can be written, /// and it cannot be changed later. /// </remarks> private void SetFormat(IntPtr aviStream) { Avi.BITMAPINFOHEADER bi = new Avi.BITMAPINFOHEADER(); bi.biSize = Marshal.SizeOf(bi); bi.biWidth = width; bi.biHeight = height; bi.biPlanes = 1; bi.biBitCount = countBitsPerPixel; bi.biSizeImage = frameSize; int result = Avi.AVIStreamSetFormat(aviStream, 0, ref bi, bi.biSize); if(result != 0){ throw new Exception("Error in VideoStreamSetFormat: "+result.ToString()); } }
/// <summary>Prepare for decompressing frames</summary> /// <remarks> /// This method has to be called before GetBitmap and ExportBitmap. /// Release ressources with GetFrameClose. /// </remarks> public void GetFrameOpen() { Avi.AVISTREAMINFO streamInfo = GetStreamInfo(StreamPointer); //Open frames Avi.BITMAPINFOHEADER bih = new Avi.BITMAPINFOHEADER(); bih.biBitCount = countBitsPerPixel; bih.biClrImportant = 0; bih.biClrUsed = 0; bih.biCompression = 0; bih.biPlanes = 1; bih.biSize = Marshal.SizeOf(bih); bih.biXPelsPerMeter = 0; bih.biYPelsPerMeter = 0; // Corrections by M. Covington: // If these are pre-set, interlaced video is not handled correctly. // Better to give zeroes and let Windows fill them in. bih.biHeight = 0; // was (Int32)streamInfo.rcFrame.bottom; bih.biWidth = 0; // was (Int32)streamInfo.rcFrame.right; // Corrections by M. Covington: // Validate the bit count, because some AVI files give a bit count // that is not one of the allowed values in a BitmapInfoHeader. // Here 0 means for Windows to figure it out from other information. if (bih.biBitCount > 24) { bih.biBitCount = 32; } else if (bih.biBitCount > 16) { bih.biBitCount = 24; } else if (bih.biBitCount > 8) { bih.biBitCount = 16; } else if (bih.biBitCount > 4) { bih.biBitCount = 8; } else if (bih.biBitCount > 0) { bih.biBitCount = 4; } getFrameObject = Avi.AVIStreamGetFrameOpen(StreamPointer, ref bih); if(getFrameObject == 0){ throw new Exception("Exception in VideoStreamGetFrameOpen!"); } }
/// <summary>Initialize a VideoStream for an existing stream</summary> /// <param name="aviFile">The file that contains the stream</param> /// <param name="aviStream">An IAVISTREAM from [aviFile]</param> public VideoStream(int aviFile, IntPtr aviStream) { this.aviFile = aviFile; this.aviStream = aviStream; Avi.BITMAPINFOHEADER bih = new Avi.BITMAPINFOHEADER(); int size = Marshal.SizeOf(bih); Avi.AVIStreamReadFormat(aviStream, 0, ref bih, ref size); Avi.AVISTREAMINFO streamInfo = GetStreamInfo(aviStream); this.frameRate = (float)streamInfo.dwRate / (float)streamInfo.dwScale; this.width = (int)streamInfo.rcFrame.right; this.height = (int)streamInfo.rcFrame.bottom; this.frameSize = bih.biSizeImage; this.countBitsPerPixel = bih.biBitCount; this.firstFrame = Avi.AVIStreamStart(aviStream.ToInt32()); this.countFrames = Avi.AVIStreamLength(aviStream.ToInt32()); }
/// <summary>Export a frame into a bitmap</summary> /// <param name="position">Position of the frame</param> public Bitmap GetBitmap(int position){ if(position > countFrames){ throw new Exception("Invalid frame position: "+position); } Avi.AVISTREAMINFO streamInfo = GetStreamInfo(StreamPointer); //Decompress the frame and return a pointer to the DIB int dib = Avi.NativeMethods.AVIStreamGetFrame(getFrameObject, firstFrame + position); //Copy the bitmap header into a managed struct Avi.BITMAPINFOHEADER bih = new Avi.BITMAPINFOHEADER(); bih = (Avi.BITMAPINFOHEADER)Marshal.PtrToStructure(new IntPtr(dib), bih.GetType()); if(bih.biSizeImage < 1){ throw new Exception("Exception in VideoStreamGetFrame"); } //copy the image byte[] bitmapData; int address = dib + Marshal.SizeOf(bih); if(bih.biBitCount < 16){ //copy palette and pixels bitmapData = new byte[bih.biSizeImage + Avi.PALETTE_SIZE]; }else{ //copy only pixels bitmapData = new byte[bih.biSizeImage]; } Marshal.Copy(new IntPtr(address), bitmapData, 0, bitmapData.Length); //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(); Marshal.Copy(new IntPtr(address), bitmapInfo, 0, bitmapInfo.Length); Marshal.FreeHGlobal(ptr); //create file header Avi.BITMAPFILEHEADER bfh = new Avi.BITMAPFILEHEADER(); bfh.bfType = Avi.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); if(bih.biBitCount < 16){ //There is a palette between header and pixel data bfh.bfOffBits += Avi.PALETTE_SIZE; } //write a bitmap stream BinaryWriter bw = new BinaryWriter( new MemoryStream() ); //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); Bitmap bmp = (Bitmap)Image.FromStream(bw.BaseStream); Bitmap saveableBitmap = new Bitmap(bmp.Width, bmp.Height); Graphics g = Graphics.FromImage(saveableBitmap); g.DrawImage(bmp, 0,0); g.Dispose(); bmp.Dispose(); bw.Close(); return saveableBitmap; }
public static extern IntPtr AVIStreamGetFrameOpen( IntPtr pAVIStream, ref Avi.BITMAPINFOHEADER bih);
/// <summary>Export a frame into a bitmap</summary> /// <param name="position">Position of the frame</param> public Bitmap GetBitmap(int position) { if (position > this.countFrames) { throw new Exception("Invalid frame position: " + position); } Avi.AVISTREAMINFO streamInfo = this.GetStreamInfo(this.StreamPointer); //Decompress the frame and return a pointer to the DIB int dib = Avi.AVIStreamGetFrame(this.getFrameObject, this.firstFrame + position); //Copy the bitmap header into a managed struct Avi.BITMAPINFOHEADER bih = new Avi.BITMAPINFOHEADER(); bih = (Avi.BITMAPINFOHEADER)Marshal.PtrToStructure(new IntPtr(dib), bih.GetType()); if (bih.biSizeImage < 1) { throw new Exception("Exception in VideoStreamGetFrame"); } //copy the image byte[] bitmapData; int address = dib + Marshal.SizeOf(bih); if (bih.biBitCount < 16) { //copy palette and pixels bitmapData = new byte[bih.biSizeImage + Avi.PALETTE_SIZE]; } else { //copy only pixels bitmapData = new byte[bih.biSizeImage]; } Marshal.Copy(new IntPtr(address), bitmapData, 0, bitmapData.Length); //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(); Marshal.Copy(new IntPtr(address), bitmapInfo, 0, bitmapInfo.Length); Marshal.FreeHGlobal(ptr); //create file header Avi.BITMAPFILEHEADER bfh = new Avi.BITMAPFILEHEADER(); bfh.bfType = Avi.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); if (bih.biBitCount < 16) { //There is a palette between header and pixel data bfh.bfOffBits += Avi.PALETTE_SIZE; } //write a bitmap stream BinaryWriter bw = new BinaryWriter(new MemoryStream()); //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); Bitmap bmp = (Bitmap)Image.FromStream(bw.BaseStream); Bitmap saveableBitmap = new Bitmap(bmp.Width, bmp.Height); Graphics g = Graphics.FromImage(saveableBitmap); g.DrawImage(bmp, 0, 0); g.Dispose(); bmp.Dispose(); bw.Close(); return(saveableBitmap); }