// Add new frame to the AVI file public void AddFrame(System.Drawing.Bitmap bmp) { // check image dimension if ((bmp.Width != width) || (bmp.Height != height)) { throw new ApplicationException("Invalid image dimension"); } // lock bitmap data BitmapData bmData = bmp.LockBits( new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); // copy image data int srcStride = bmData.Stride; int dstStride = stride; int src = bmData.Scan0.ToInt32() + srcStride * (height - 1); int dst = buf.ToInt32(); for (int y = 0; y < height; y++) { Win32.memcpy(dst, src, dstStride); dst += dstStride; src -= srcStride; } // unlock bitmap data bmp.UnlockBits(bmData); // write to stream if (Win32.AVIStreamWrite(streamCompressed, position, 1, buf, stride * height, 0, IntPtr.Zero, IntPtr.Zero) != 0) { throw new ApplicationException("Failed adding frame"); } position++; //Graphics g = Graphics.FromImage(bmp); //g.DrawString("录像中", new Font("宋体", 60), Brushes.Red, new PointF(20, 150)); }
// 把新的一帧加入到AVI public void AddFrame(System.Drawing.Bitmap bmp) { // 检查图像尺寸 if ((bmp.Width != width) || (bmp.Height != height)) { throw new ApplicationException("Invalid image dimension"); } // 锁定图像 BitmapData bmData = bmp.LockBits( new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); // 拷贝图像数据 int srcStride = bmData.Stride; int dstStride = stride; int src = bmData.Scan0.ToInt32() + srcStride * (height - 1); int dst = buf.ToInt32(); for (int y = 0; y < height; y++) { Win32.memcpy(dst, src, dstStride); dst += dstStride; src -= srcStride; } // 解锁图像 bmp.UnlockBits(bmData); // 把图像写入流 if (Win32.AVIStreamWrite(streamCompressed, position, 1, buf, stride * height, 0, IntPtr.Zero, IntPtr.Zero) != 0) { throw new ApplicationException("添加帧失败!"); } position++; }
// Get next video frame public Bitmap GetNextFrame() { // get frame at specified position IntPtr pdib = Win32.AVIStreamGetFrame(getFrame, position); if (pdib == IntPtr.Zero) { throw new ApplicationException("Failed getting frame"); } Win32.BITMAPINFOHEADER bih; // copy BITMAPINFOHEADER from unmanaged memory bih = (Win32.BITMAPINFOHEADER)Marshal.PtrToStructure(pdib, typeof(Win32.BITMAPINFOHEADER)); // create new bitmap Bitmap bmp = new Bitmap(width, height, PixelFormat.Format24bppRgb); // lock bitmap data BitmapData bmData = bmp.LockBits( new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); // copy image data int srcStride = bmData.Stride; // width * 3; int dstStride = bmData.Stride; // check image direction if (bih.biHeight > 0) { // it`s a bottom-top image int dst = bmData.Scan0.ToInt32() + dstStride * (height - 1); int src = pdib.ToInt32() + Marshal.SizeOf(typeof(Win32.BITMAPINFOHEADER)); for (int y = 0; y < height; y++) { Win32.memcpy(dst, src, srcStride); dst -= dstStride; src += srcStride; } } else { // it`s a top bootom image int dst = bmData.Scan0.ToInt32(); int src = pdib.ToInt32() + Marshal.SizeOf(typeof(Win32.BITMAPINFOHEADER)); if (srcStride != dstStride) { // copy line by line for (int y = 0; y < height; y++) { Win32.memcpy(dst, src, srcStride); dst += dstStride; src += srcStride; } } else { // copy the whole image Win32.memcpy(dst, src, srcStride * height); } } // unlock bitmap data bmp.UnlockBits(bmData); position++; return(bmp); }