static void Main() { SetMaximumUpscale(200); Bitmap imgsrc = new Bitmap("icon.jpg"); var infosrc = new BITMAPINFOHEADER { biWidth = imgsrc.Width, biHeight = imgsrc.Height, biBitCount = (ushort)Image.GetPixelFormatSize(imgsrc.PixelFormat) }; var infodest = GetResizedImageInfo(imgsrc.Width, imgsrc.Height, 1600, 1200); Rectangle recsrc = new Rectangle(0, 0, imgsrc.Width, imgsrc.Height); BitmapData datasrc = imgsrc.LockBits(recsrc, ImageLockMode.WriteOnly, imgsrc.PixelFormat); Bitmap imgdest = new Bitmap(infodest.biWidth, infodest.biHeight, PixelFormat.Format24bppRgb); Rectangle recdest = new Rectangle(0, 0, imgdest.Width, imgdest.Height); BitmapData datadest = imgdest.LockBits(recdest, ImageLockMode.WriteOnly, imgdest.PixelFormat); infodest.biBitCount = (ushort)Image.GetPixelFormatSize(imgdest.PixelFormat); ResizeImage(datasrc.Scan0, infosrc, datadest.Scan0, infodest); imgsrc.UnlockBits(datasrc); imgdest.UnlockBits(datadest); imgdest.Save("icondest.png", ImageFormat.Png); Console.ReadKey(); }
/// <summary> /// Get FrameGrabber to grab frames from AVI. /// </summary> /// <returns> /// new FrameGrabber object. /// </returns> public FrameGrabber GetFrameGrabber() { int formatSize = 0; BITMAPINFOHEADER bmpHeader = new BITMAPINFOHEADER(); BITMAPINFOHEADER bmpHeaderOut = new BITMAPINFOHEADER(); AviFil32.AVIError error = AviFil32.AVIStreamReadFormat(_aviStream, 0, IntPtr.Zero, ref formatSize); if (error != AviFil32.AVIError.AVIERR_OK) throw new AviException("Unrecognised AVI exception (0x" + Convert.ToString((int)error, 16) + ")."); if (formatSize > Marshal.SizeOf(typeof(BITMAPINFOHEADER))) throw new AviException("Unknown format (too big)."); error = AviFil32.AVIStreamReadFormat(_aviStream, 0, ref bmpHeader, ref formatSize); if (error != AviFil32.AVIError.AVIERR_OK) throw new AviException("Unrecognised AVI exception (0x" + Convert.ToString((int)error, 16) + ")."); bmpHeaderOut.biSize = bmpHeader.biSize; bmpHeaderOut.biWidth = bmpHeader.biWidth; bmpHeaderOut.biHeight = bmpHeader.biHeight; bmpHeaderOut.biPlanes = 1; bmpHeaderOut.biBitCount = 24; bmpHeaderOut.biCompression = 0; // RGB bmpHeaderOut.biXPelsPerMeter = bmpHeader.biXPelsPerMeter; bmpHeaderOut.biYPelsPerMeter = bmpHeader.biYPelsPerMeter; IntPtr getFrameObject = AviFil32.AVIStreamGetFrameOpen(_aviStream, ref bmpHeaderOut); if (getFrameObject == IntPtr.Zero) throw new AviException("Can not find video decompressor."); return new FrameGrabber(getFrameObject, _streamInfo); }
/// <summary> /// 初始化视频画刷及显示控件 /// </summary> public void IniVideoRender(BITMAPINFOHEADER BITMAPINFOHEADER) { drawDib = new DrawDib(this.controlVideo); drawDib.BITMAPINFOHEADER = BITMAPINFOHEADER; //drawDib.BITMAPINFOHEADER.biCompression = BITMAPINFOHEADER.biCompression;// 已修改 原(int)BI.BI_RGB; //drawDib.BITMAPINFOHEADER.biBitCount = BITMAPINFOHEADER.biBitCount;//已修改 原24 drawDib.Open(); }
/******************************************* * �������ƣ�GetBitmap * �������ܣ��������������ݱ���ΪͼƬ * ������Σ�buffer---ͼƬ���� * nWidth---ͼƬ�Ŀ�� * nHeight---ͼƬ�ĸ߶� * �������Σ��� * �������أ��� *********************************************/ public static void GetBitmap(byte[] buffer, int nWidth, int nHeight, ref MemoryStream ms) { int ColorIndex = 0; ushort m_nBitCount = 8; int m_nColorTableEntries = 256; byte[] ResBuf = new byte[nWidth * nHeight]; try { BITMAPFILEHEADER BmpHeader = new BITMAPFILEHEADER(); BITMAPINFOHEADER BmpInfoHeader = new BITMAPINFOHEADER(); MASK[] ColorMask = new MASK[m_nColorTableEntries]; //ͼƬͷ��Ϣ BmpInfoHeader.biSize = Marshal.SizeOf(BmpInfoHeader); BmpInfoHeader.biWidth = nWidth; BmpInfoHeader.biHeight = nHeight; BmpInfoHeader.biPlanes = 1; BmpInfoHeader.biBitCount = m_nBitCount; BmpInfoHeader.biCompression = 0; BmpInfoHeader.biSizeImage = 0; BmpInfoHeader.biXPelsPerMeter = 0; BmpInfoHeader.biYPelsPerMeter = 0; BmpInfoHeader.biClrUsed = m_nColorTableEntries; BmpInfoHeader.biClrImportant = m_nColorTableEntries; //�ļ�ͷ��Ϣ BmpHeader.bfType = 0x4D42; BmpHeader.bfOffBits = 14 + Marshal.SizeOf(BmpInfoHeader) + BmpInfoHeader.biClrUsed * 4; BmpHeader.bfSize = BmpHeader.bfOffBits + ((((BmpInfoHeader.biWidth * BmpInfoHeader.biBitCount + 31) / 32) * 4) * BmpInfoHeader.biHeight); BmpHeader.bfReserved1 = 0; BmpHeader.bfReserved2 = 0; ms.Write(StructToBytes(BmpHeader, 14), 0, 14); ms.Write(StructToBytes(BmpInfoHeader, Marshal.SizeOf(BmpInfoHeader)), 0, Marshal.SizeOf(BmpInfoHeader)); //������Ϣ for (ColorIndex = 0; ColorIndex < m_nColorTableEntries; ColorIndex++) { ColorMask[ColorIndex].redmask = (byte)ColorIndex; ColorMask[ColorIndex].greenmask = (byte)ColorIndex; ColorMask[ColorIndex].bluemask = (byte)ColorIndex; ColorMask[ColorIndex].rgbReserved = 0; ms.Write(StructToBytes(ColorMask[ColorIndex], Marshal.SizeOf(ColorMask[ColorIndex])), 0, Marshal.SizeOf(ColorMask[ColorIndex])); } //ͼƬ��ת�����ָ��ͼƬ���������� RotatePic(buffer, nWidth, nHeight, ref ResBuf); ms.Write(ResBuf, 0, nWidth * nHeight); } catch (Exception ex) { // ZKCE.SysException.ZKCELogger logger = new ZKCE.SysException.ZKCELogger(ex); // logger.Append(); } }
private static BITMAPFILEHEADER createFileHeader(ref BITMAPINFOHEADER info) { BITMAPFILEHEADER header = new BITMAPFILEHEADER(); header.bfType = BFTYPE_BMP; int headerSize = Marshal.SizeOf(header) + Marshal.SizeOf(info); header.bfSize = (uint) headerSize + info.biSizeImage; header.bfOffBits = (uint) headerSize; return header; }
public InfoForm( BITMAPINFOHEADER bmi ) { InitializeComponent(); txtWidth.Text = bmi.biWidth.ToString(); txtHeight.Text = bmi.biHeight.ToString(); txtBitsPix.Text = bmi.biBitCount.ToString(); int skb = bmi.biSizeImage >> 10; txtSize.Text = skb.ToString(); }
/// <summary> /// 初始化视频编解码器 /// </summary> /// <param name="bitmapInfoHeader">图像头信息</param> /// <param name="isEncode">标识完成编码还是解码功能</param> public VideoEncoder(BITMAPINFOHEADER bitmapInfoHeader, bool isEncode) { #region //BITMAPINFOHEADER bmi = new BITMAPINFOHEADER (); //bmi.biWidth = bitmapInfoHeader.biWidth; //bmi.biHeight = bitmapInfoHeader.biHeight; //if (isEncode) //{ // bmi.biCompression =bitmapInfoHeader.biCompression; //} //else //{ // bmi.biCompression = FOURCC.MP42; //} //bmi.biSizeImage =bitmapInfoHeader.biSizeImage; //bmi.biPlanes = bitmapInfoHeader.biPlanes; //bmi.biBitCount = bitmapInfoHeader.biBitCount; //bmi.biXPelsPerMeter = bitmapInfoHeader.biXPelsPerMeter; //bmi.biYPelsPerMeter = bitmapInfoHeader.biYPelsPerMeter; //bmi.biClrUsed = bitmapInfoHeader.biClrUsed; //bmi.biClrImportant = bitmapInfoHeader.biClrImportant; //bmi.biSize = bitmapInfoHeader.biSize; //bitmapInfo.bmiHeader = bmi; #endregion BITMAPINFO bitmapInfo = new BITMAPINFO(); bitmapInfo.bmiHeader = bitmapInfoHeader; this.IsEncode = isEncode; if (isEncode) { COMPVARS compvars = new COMPVARS(); compvars.cbSize = Marshal.SizeOf(compvars); compvars.dwFlags = 1; compvars.fccHandler = FOURCC.MP42; compvars.fccType = FOURCC.ICTYPE_VIDEO; compvars.lDataRate = 780; compvars.lKey = 15; compvars.lQ = -1; compvars.lQ = 500; this.Compressor = new ICCompressor(compvars, bitmapInfo, FOURCC.MP42); this.Compressor.Open();//打开编码器 } else { bitmapInfo.bmiHeader.biCompression = FOURCC.MP42; this.Decompressor = new ICDecompressor(new COMPVARS(), bitmapInfo, FOURCC.MP42); this.Decompressor.Open(); } }
private static void Store(BinaryWriter bw, BITMAPINFOHEADER bm) { bw.Write(bm.biSize); bw.Write(bm.biWidth); bw.Write(bm.biHeight); bw.Write(bm.biPlanes); bw.Write(bm.biBitCount); bw.Write(bm.biCompression); bw.Write(bm.biSizeImage); bw.Write(bm.biXPelsPerMeter); bw.Write(bm.biYPelsPerMeter); bw.Write(bm.biClrUsed); bw.Write(bm.biClrImportant); }
public static Bitmap CreateDIB(int x, int y) { //Set up a BitmapHeader Int32 Depth = DetermineColorDepth.getdepth(); BITMAPINFOHEADER bmpInfo = new BITMAPINFOHEADER((short) Depth, x, y); BITMAPFILEHEADER bmpFile = new BITMAPFILEHEADER(bmpInfo); byte[] buffer = new byte[bmpFile.bfSize]; MemoryStream m = new MemoryStream(buffer); using (BinaryWriter writer = new BinaryWriter(m)) { bmpFile.Store(writer); bmpInfo.Store(writer, false); m.Seek(0, SeekOrigin.Begin); return new Bitmap(m); } }
/// <summary> /// This method will use User32 code to capture the specified captureBounds from the screen /// </summary> /// <param name="captureBounds">Rectangle with the bounds to capture</param> /// <returns>Bitmap which is captured from the screen at the location specified by the captureBounds</returns> public static Bitmap CaptureRectangle(Rectangle captureBounds) { Bitmap returnBitmap = null; if (captureBounds.Height <= 0 || captureBounds.Width <= 0) { LOG.Warn("Nothing to capture, ignoring!"); return(null); } LOG.Debug("CaptureRectangle Called!"); // .NET GDI+ Solution, according to some post this has a GDI+ leak... // See http://connect.microsoft.com/VisualStudio/feedback/details/344752/gdi-object-leak-when-calling-graphics-copyfromscreen // Bitmap capturedBitmap = new Bitmap(captureBounds.Width, captureBounds.Height); // using (Graphics graphics = Graphics.FromImage(capturedBitmap)) { // graphics.CopyFromScreen(captureBounds.Location, Point.Empty, captureBounds.Size, CopyPixelOperation.CaptureBlt); // } // capture.Image = capturedBitmap; // capture.Location = captureBounds.Location; using (SafeWindowDCHandle desktopDCHandle = SafeWindowDCHandle.fromDesktop()) { if (desktopDCHandle.IsInvalid) { // Get Exception before the error is lost Exception exceptionToThrow = CreateCaptureException("desktopDCHandle", captureBounds); // throw exception throw exceptionToThrow; } // create a device context we can copy to using (SafeCompatibleDCHandle safeCompatibleDCHandle = GDI32.CreateCompatibleDC(desktopDCHandle)) { // Check if the device context is there, if not throw an error with as much info as possible! if (safeCompatibleDCHandle.IsInvalid) { // Get Exception before the error is lost Exception exceptionToThrow = CreateCaptureException("CreateCompatibleDC", captureBounds); // throw exception throw exceptionToThrow; } // Create BITMAPINFOHEADER for CreateDIBSection BITMAPINFOHEADER bmi = new BITMAPINFOHEADER(captureBounds.Width, captureBounds.Height, 24); // Make sure the last error is set to 0 Win32.SetLastError(0); // create a bitmap we can copy it to, using GetDeviceCaps to get the width/height IntPtr bits0; // not used for our purposes. It returns a pointer to the raw bits that make up the bitmap. using (SafeDibSectionHandle safeDibSectionHandle = GDI32.CreateDIBSection(desktopDCHandle, ref bmi, BITMAPINFOHEADER.DIB_RGB_COLORS, out bits0, IntPtr.Zero, 0)) { if (safeDibSectionHandle.IsInvalid) { // Get Exception before the error is lost Exception exceptionToThrow = CreateCaptureException("CreateDIBSection", captureBounds); exceptionToThrow.Data.Add("hdcDest", safeCompatibleDCHandle.DangerousGetHandle().ToInt32()); exceptionToThrow.Data.Add("hdcSrc", desktopDCHandle.DangerousGetHandle().ToInt32()); // Throw so people can report the problem throw exceptionToThrow; } // select the bitmap object and store the old handle using (safeCompatibleDCHandle.SelectObject(safeDibSectionHandle)) { // bitblt over (make copy) GDI32.BitBlt(safeCompatibleDCHandle, 0, 0, captureBounds.Width, captureBounds.Height, desktopDCHandle, captureBounds.X, captureBounds.Y, CopyPixelOperation.SourceCopy | CopyPixelOperation.CaptureBlt); } // get a .NET image object for it // A suggestion for the "A generic error occurred in GDI+." E_FAIL/0×80004005 error is to re-try... bool success = false; ExternalException exception = null; for (int i = 0; i < 3; i++) { try { // Collect all screens inside this capture List <Screen> screensInsideCapture = new List <Screen>(); foreach (Screen screen in Screen.AllScreens) { if (screen.Bounds.IntersectsWith(captureBounds)) { screensInsideCapture.Add(screen); } } // Check all all screens are of an equal size bool offscreenContent; using (Region captureRegion = new Region(captureBounds)) { // Exclude every visible part foreach (Screen screen in screensInsideCapture) { captureRegion.Exclude(screen.Bounds); } // If the region is not empty, we have "offscreenContent" using (Graphics screenGraphics = Graphics.FromHwnd(User32.GetDesktopWindow())) { offscreenContent = !captureRegion.IsEmpty(screenGraphics); } } // Check if we need to have a transparent background, needed for offscreen content if (offscreenContent) { using (Bitmap tmpBitmap = Image.FromHbitmap(safeDibSectionHandle.DangerousGetHandle())) { // Create a new bitmap which has a transparent background returnBitmap = ImageHelper.CreateEmpty(tmpBitmap.Width, tmpBitmap.Height, PixelFormat.Format32bppArgb, Color.Transparent, tmpBitmap.HorizontalResolution, tmpBitmap.VerticalResolution); // Content will be copied here using (Graphics graphics = Graphics.FromImage(returnBitmap)) { // For all screens copy the content to the new bitmap foreach (Screen screen in Screen.AllScreens) { Rectangle screenBounds = screen.Bounds; // Make sure the bounds are offsetted to the capture bounds screenBounds.Offset(-captureBounds.X, -captureBounds.Y); graphics.DrawImage(tmpBitmap, screenBounds, screenBounds.X, screenBounds.Y, screenBounds.Width, screenBounds.Height, GraphicsUnit.Pixel); } } } } else { // All screens, which are inside the capture, are of equal size // assign image to Capture, the image will be disposed there.. returnBitmap = Image.FromHbitmap(safeDibSectionHandle.DangerousGetHandle()); } // We got through the capture without exception success = true; break; } catch (ExternalException ee) { LOG.Warn("Problem getting bitmap at try " + i + " : ", ee); exception = ee; } } if (!success) { LOG.Error("Still couldn't create Bitmap!"); if (exception != null) { throw exception; } } } } } return(returnBitmap); }
/// <summary> /// 指定したAVI_CONTAINER構造体にAVIファイルの情報を格納すると共に, /// ファイルにヘッダー情報を書き込みます. /// </summary> /// <param name="file">書き込み対象のファイル</param> /// <param name="scale"></param> /// <param name="rate"></param> /// <param name="compressed"></param> public unsafe bool Open(string file, uint scale, uint rate, int width, int height, bool compressed, bool transparent, IntPtr hWnd) { #if DEBUG Console.WriteLine("AviWriterEx.Open(string,uint,uint,bool,IntPtr)"); #endif m_stream = new BinaryWriter(new FileStream(file, FileMode.Create, FileAccess.Write)); float fps = (float)rate / (float)scale; m_main_header.dwMicroSecPerFrame = (uint)(1.0e6 / fps);// ! 1秒は10^6μ秒 m_main_header.dwReserved1 = 0; m_main_header.dwFlags = 2064; m_main_header.dwInitialFrames = 0; m_main_header.dwStreams = 0; m_main_header.dwScale = scale; m_main_header.dwRate = rate; m_main_header.dwStart = 0; m_main_header.dwLength = 0; m_rate = rate; m_scale = scale; Util.fwrite("RIFF", m_stream); Util.WriteDWORD(0, m_stream); Util.fwrite("AVI ", m_stream); Util.fwrite("LIST", m_stream); Util.WriteDWORD(0x9cc, m_stream); Util.fwrite("hdrl", m_stream); m_current_chunk = 0; m_position_in_chunk = 0L; m_std_index = new AVISTDINDEX(0L); m_super_index = new AVISUPERINDEX(0); m_riff_position = 0x4; m_compressed = compressed; m_is_transparent = transparent; m_stream_fcc_handler = 0; m_hwnd = hWnd; m_file = file; m_opened = true; if (m_is_first) { int stride = 0; using (Bitmap b = new Bitmap(width, height, m_is_transparent ? PixelFormat.Format32bppArgb : PixelFormat.Format24bppRgb)) { BitmapData bd = b.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, b.PixelFormat); stride = bd.Stride; b.UnlockBits(bd); } m_is_first = false; m_main_header.dwWidth = (uint)width; m_main_header.dwHeight = (uint)height; m_main_header.dwMaxBytesPerSec = (uint)(stride * height * frameRate); m_main_header.dwStreams = 1; m_main_header.dwSuggestedBufferSize = (uint)(stride * height); m_linesize = stride; m_stream_header.fccType = Util.mmioFOURCC("vids"); m_stream_header.fccHandler = 0; m_stream_header.dwFlags = 0; m_stream_header.dwReserved1 = 0; m_stream_header.dwInitialFrames = 0; m_stream_header.dwScale = m_scale; m_stream_header.dwRate = m_rate; m_stream_header.dwStart = 0; m_stream_header.dwSuggestedBufferSize = m_main_header.dwSuggestedBufferSize; m_stream_header.dwQuality = 0; m_stream_header.dwSampleSize = 0; Util.aviWriteMainHeader(m_main_header, m_stream); Util.fwrite("LIST", m_stream); Util.WriteDWORD(0x874, m_stream); Util.fwrite("strl", m_stream); Util.aviWriteStreamHeader(m_stream_header, m_main_header, m_stream); Util.fwrite("strf", m_stream); BITMAPINFOHEADER bih = new BITMAPINFOHEADER(); //(BITMAPINFOHEADER)Marshal.PtrToStructure( Marshal.AllocHGlobal( sizeof( BITMAPINFOHEADER ) ), typeof( BITMAPINFOHEADER ) ); bih.biSize = (uint)(Marshal.SizeOf(bih)); bih.biWidth = width; bih.biHeight = height; bih.biPlanes = 1; bih.biBitCount = m_is_transparent ? (short)32 : (short)24; bih.biCompression = 0;//BI_RGB bih.biSizeImage = (uint)(stride * height); bih.biXPelsPerMeter = 0; bih.biYPelsPerMeter = 0; bih.biClrUsed = 0; bih.biClrImportant = 0; if (m_compressed) { m_p_compvar = Marshal.AllocHGlobal(sizeof(COMPVARS)); m_compvar = (COMPVARS *)m_p_compvar.ToPointer(); byte[] buf = new byte[sizeof(COMPVARS)]; for (int i = 0; i < buf.Length; i++) { buf[i] = 0x0; } Marshal.Copy(buf, 0, m_p_compvar, buf.Length); m_compvar->cbSize = sizeof(COMPVARS); int ret = VCM.ICCompressorChoose(m_hwnd, 0, IntPtr.Zero, IntPtr.Zero, m_compvar, "Select Video Compressor"); if (ret == 0) { m_opened = false; Marshal.FreeHGlobal(m_p_compvar); m_stream.Close(); return(false); } if (m_compvar->hic != 0) { m_p_bitmapinfo_in = Marshal.AllocHGlobal(sizeof(BITMAPINFO)); m_bitmapinfo_in = (BITMAPINFO *)m_p_bitmapinfo_in.ToPointer(); buf = new byte[sizeof(BITMAPINFO)]; for (int i = 0; i < buf.Length; i++) { buf[i] = 0x0; } Marshal.Copy(buf, 0, m_p_bitmapinfo_in, buf.Length); m_bitmapinfo_in->bmiHeader = bih; uint dwSize = VCM.ICCompressGetFormatSize(m_compvar->hic, m_bitmapinfo_in); #if DEBUG Console.WriteLine("m_compvar->hic=" + m_compvar->hic); Console.WriteLine("ICCompressGetFormatSize=" + dwSize); #endif m_p_bitmapinfo_out = Marshal.AllocHGlobal((int)dwSize); m_bitmapinfo_out = (BITMAPINFO *)m_p_bitmapinfo_out.ToPointer(); buf = new byte[dwSize]; for (int i = 0; i < buf.Length; i++) { buf[i] = 0x0; } Marshal.Copy(buf, 0, m_p_bitmapinfo_out, buf.Length); VCM.ICCompressGetFormat(m_compvar->hic, m_bitmapinfo_in, m_bitmapinfo_out); m_bih_compression = m_bitmapinfo_out->bmiHeader.biCompression; #if DEBUG Console.WriteLine("AddFrame(Bitmap)"); Console.WriteLine(" biout.biSize=" + m_bitmapinfo_out->bmiHeader.biSize); #endif VCM.ICSeqCompressFrameStart(m_compvar, m_bitmapinfo_in); bih = m_bitmapinfo_out->bmiHeader; Util.WriteDWORD(bih.biSize, m_stream);// infoHeaderのサイズ m_bitmapinfo_out->Write(m_stream); } else { m_compressed = false; Util.WriteDWORD(bih.biSize, m_stream);// infoHeaderのサイズ bih.Write(m_stream); } } else { Util.WriteDWORD(bih.biSize, m_stream);// infoHeaderのサイズ bih.Write(m_stream); } m_super_index_position = m_stream.BaseStream.Position; Util.fwrite("indx", m_stream); //fcc Util.WriteDWORD(0x7f8, m_stream); // cb Util.WriteWORD((byte)0x4, m_stream); // wLongsPerEntry Util.WriteBYTE(0x0, m_stream); // bIndexSubType Util.WriteBYTE(Util.AVI_INDEX_OF_INDEXES, m_stream); // bIndexType Util.WriteDWORD(0x0, m_stream); // nEntriesInUse Util.fwrite("00db", m_stream); // dwChunkId Util.WriteDWORD(0x0, m_stream); Util.WriteDWORD(0x0, m_stream); Util.WriteDWORD(0x0, m_stream); for (int ii = 1; ii <= 126; ii++) { Util.WriteQWORD(0x0, m_stream); Util.WriteDWORD(0x0, m_stream); Util.WriteDWORD(0x0, m_stream); } Util.fwrite("LIST", m_stream); Util.WriteDWORD(0x104, m_stream); Util.fwrite("odml", m_stream); Util.fwrite("dmlh", m_stream); Util.WriteDWORD(0xf8, m_stream); Util.WriteDWORD(0x0, m_stream);//ここ後で更新するべき for (int ii = 1; ii <= 61; ii++) { Util.WriteDWORD(0x0, m_stream); } Util.fwrite("JUNK", m_stream); Util.WriteDWORD(0x60c, m_stream); Util.WriteDWORD(0, m_stream);//"This"が将来登録されたらやばいので string msg = "This file was generated by [email protected];VfwBugCompatible=" + VfwBugCompatible; const int tlen = 1544; int remain = tlen - msg.Length; Util.fwrite(msg, m_stream); for (int i = 1; i <= remain; i++) { m_stream.Write((byte)0); } m_junk_length = 0xff4; Util.fwrite("LIST", m_stream); m_movi_position = m_stream.BaseStream.Position; Util.WriteDWORD(0, m_stream);// call bmpQWordWrite( 0, avi%fp ) !// ******************ココの数字は一番最後に書き換える必要あり2040~2043あとdwTotalFrames(48~51)も Util.fwrite("movi", m_stream); m_next_framedata_position = m_stream.BaseStream.Position; m_std_index.SetBaseOffset((ulong)m_next_framedata_position); m_super_index.nEntriesInUse++; } return(true); }
/// <summary> /// Creates a BITMAPFILEHEADER class instance from the information provided /// by a BITMAPINFOHEADER instance. /// </summary> /// <param name="infoHdr">Filled in bitmap info header</param> public BITMAPFILEHEADER(BITMAPINFOHEADER infoHdr) { // These are constant for our example bfType = fBitmapFileDesignator; bfOffBits = fBitmapFileOffsetToData; bfReserved1 = 0; bfReserved2 = 0; // Determine the size of the pixel data given the bit depth, width, and // height of the bitmap. Note: Bitmap pixel data is always aligned to 4 byte // boundaries. uint bytesPerPixel = (uint)(infoHdr.biBitCount >> 3); uint extraBytes = ((uint)infoHdr.biWidth * bytesPerPixel) % 4; uint adjustedLineSize = bytesPerPixel * ((uint)infoHdr.biWidth + extraBytes); // Store the size of the pixel data sizeOfImageData = (uint)(infoHdr.biHeight) * adjustedLineSize; // Store the total file size bfSize = bfOffBits + sizeOfImageData; }
public static extern IntPtr ResizeImage(IntPtr buffer, BITMAPINFOHEADER bminfo, IntPtr newbuffer, BITMAPINFOHEADER newbminfo);
public static extern int AVIStreamSetFormat( IntPtr streamHandler, int position, ref BITMAPINFOHEADER format, int formatSize);
unsafe private void SetOptions() { AVICOMPRESSOPTIONS opts = new AVICOMPRESSOPTIONS(); opts.fccType = fccType_; opts.fccHandler = 0;//fccHandler_; opts.dwKeyFrameEvery = 0; opts.dwQuality = 0; // 0 .. 10000 opts.dwFlags = 0; // AVICOMRPESSF_KEYFRAMES = 4 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); // TODO: AVISaveOptionsFree(...) 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; // 0 = BI_RGB 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 UpdateVideoSettings() { _AMMediaType mt; object formatBlock; vc.CaptureGraph.Source.GetMediaType(out mt, out formatBlock); VIDEOINFOHEADER vih = new VIDEOINFOHEADER(); bool unknownFormat = false; if (formatBlock is VIDEOINFOHEADER) { vih = (VIDEOINFOHEADER)formatBlock; } else if (formatBlock is DVINFO) { DVCaptureGraph dvcg = vc.CaptureGraph as DVCaptureGraph; if (dvcg != null) { dvcg.GetVideoMediaType(out mt, out formatBlock); if (formatBlock is VIDEOINFOHEADER) { vih = (VIDEOINFOHEADER)formatBlock; } else { unknownFormat = true; } } else { unknownFormat = true; } } else { unknownFormat = true; } if (unknownFormat) { lblCurrentSettings.Text += "Unknown Video Format"; return; } BITMAPINFOHEADER bmih = vih.BitmapInfo; if (lblCurrentSettings.Text == String.Empty) { lblCurrentSettings.Text = Strings.VideoStream; } else { lblCurrentSettings.Text += "\r\n\r\n" + Strings.VideoStream; } lblCurrentSettings.Text += string.Format(CultureInfo.CurrentCulture, "\r\n" + Strings.AdvancedVideoSettingsStatus, TAB, bmih.Width, bmih.Height, vih.FrameRate.ToString("F2", CultureInfo.InvariantCulture), MediaType.SubType.GuidToString(mt.subtype), bmih.BitCount, (uint)(bmih.Width * bmih.Height * bmih.BitCount * vih.FrameRate) / 1000); }
/// <summary>Initialize the AviFile.</summary> /// <param name="path">The path to the output file.</param> /// <param name="frameRate">The frame rate for the video.</param> /// <param name="width">The width of the video.</param> /// <param name="height">The height of the video.</param> /// <param name="quality">Video quality 0 to 10000.</param> public AviWriter(string path, int frameRate, int width, int height, uint quality = 10000) { #region Validation if (path == null) { throw new ArgumentNullException(nameof(path)); } if (frameRate <= 0) { throw new ArgumentOutOfRangeException(nameof(frameRate), frameRate, "The frame rate must be at least 1 frame per second."); } if (width <= 0) { throw new ArgumentOutOfRangeException(nameof(width), width, "The width must be at least 1."); } if (height <= 0) { throw new ArgumentOutOfRangeException(nameof(height), height, "The height must be at least 1."); } #endregion //Store parameters var fccType = GetFourCc("vids"); _width = width; _height = height; _disposed = false; //Get the stride information by creating a new bitmap and querying it using (var bmp = new Bitmap(width, height, PixelFormat.Format24bppRgb)) { var bmpData = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); _stride = (uint)bmpData.Stride; bmp.UnlockBits(bmpData); } try { //Initialize the AVI library. AVIFileInit(); //Open the output AVI file. var rv = AVIFileOpenW(ref _aviFile, path, AVI_OPEN_MODE_CREATEWRITE, 0); if (rv != 0) { throw new Win32Exception(((AviErrors)rv).ToString()); } //Create a new stream in the avi file. var aviStreamInfo = new AVISTREAMINFOW { fccType = fccType, fccHandler = 0, dwScale = 1, dwRate = (uint)frameRate, dwSuggestedBufferSize = (uint)(_height * _stride), dwQuality = quality, //-1 default 0xffffffff, 0 to 10.000 rcFrame = new Native.Rect { Bottom = _height, Right = _width } }; rv = AVIFileCreateStream(_aviFile, out _aviStream, ref aviStreamInfo); if (rv != 0) { throw new Win32Exception(((AviErrors)rv).ToString()); } //Configure the compressed stream. var streamFormat = new BITMAPINFOHEADER { biSize = 40, biWidth = _width, biHeight = _height, biPlanes = 1, biBitCount = 24, biSizeImage = (uint)(_stride * _height) }; rv = AVIStreamSetFormat(_aviStream, 0, ref streamFormat, 40); if (rv != 0) { throw new Win32Exception(((AviErrors)rv).ToString()); //, "Unable to set the AVI stream format."); } } catch { // Clean up Dispose(false); try { if (File.Exists(path)) { File.Delete(path); } } catch { } throw; } }
static extern IntPtr CreateDIBitmap([In] IntPtr hdc, [In] ref BITMAPINFOHEADER lpbmih, uint fdwInit, byte[] lpbInit, [In] ref BITMAPINFO lpbmi, uint fuUsage);
public static extern IntPtr ICLocate( Int32 fccType, Int32 fccHandler, ref BITMAPINFOHEADER lpbiIn, IntPtr lpbiOut, Int16 wFlags);
public void CopyFrom(ImageEncoder encoder) { this.mHeader = encoder.mHeader; this.mColors = encoder.mColors; this.mXOR = encoder.mXOR; this.mAND = encoder.mAND; }
public static extern int ICSendMessage(IntPtr hic, uint Message, ref BITMAPINFOHEADER dw1, UIntPtr dw2);
private unsafe bool SetOptions() { int hr; AVICOMPRESSOPTIONS opts = new AVICOMPRESSOPTIONS(); AVICOMPRESSOPTIONS *pOpts = &opts; /* opts.fccType = mmioFOURCC('v','i','d','s'); opts.fccHandler = 0;//cvid? iv50? opts.dwQuality = 0; // 0 .. 10000 opts.dwFlags = 0; // AVICOMRPESSF_KEYFRAMES = 4 */ hr = AVISaveOptions( Engine.MainWindow.Handle, 3, 1, ref m_pStream, &pOpts ); if (hr != 1) return false; // TODO: AVISaveOptionsFree(...) hr = AVIMakeCompressedStream( out m_pCompStream, m_pStream, ref opts, 0 ); if (hr != 0) return false; BITMAPINFOHEADER bi = new BITMAPINFOHEADER(); bi.biSize = 40; bi.biWidth = m_Width; bi.biHeight = m_Height; bi.biPlanes = 1; bi.biBitCount = 24; bi.biCompression = 0; // 0 = BI_RGB bi.biSizeImage = (uint)(m_Width*m_Height*(bi.biBitCount/8)); hr = AVIStreamSetFormat( m_pCompStream, 0, ref bi, 40 ); return hr == 0; }
private static uint BitmapSize(BITMAPINFOHEADER bih) { uint bis = (uint)((((uint)bih.Width * (uint)bih.BitCount) + 31) & (~31)) / 8; return (uint)((uint)bih.Height * bis); }
public static extern bool DrawDibBegin( IntPtr hdd, IntPtr hdc, int dxDst, int dyDst, ref BITMAPINFOHEADER lpbi, int dxSrc, int dySrc, int wFlags );
public static extern int AVIStreamReadFormat( IntPtr aviStream, Int32 lPos, ref BITMAPINFOHEADER lpFormat, ref Int32 cbFormat );
public static extern bool DrawDibDraw( IntPtr hdd, IntPtr hdc, int xDst, int yDst, int dxDst, int dyDst, ref BITMAPINFOHEADER lpbi, byte[] lpBits, int xSrc, int ySrc, int dxSrc, int dySrc, uint wFlags );
private static byte[] GetScreenBitmapArray() { IntPtr hDC = GetDC(IntPtr.Zero); IntPtr hMemoryDC = CreateCompatibleDC(hDC); BITMAPINFOHEADER bih = new BITMAPINFOHEADER(); bih.biSize = Marshal.SizeOf(bih); bih.biBitCount = 24; bih.biClrUsed = 0; bih.biClrImportant = 0; bih.biCompression = 0; bih.biHeight = Screen.PrimaryScreen.Bounds.Height; bih.biWidth = Screen.PrimaryScreen.Bounds.Width; bih.biPlanes = 1; int cb = (int)(bih.biHeight * bih.biWidth * bih.biBitCount / 8); bih.biSizeImage = cb; bih.biXPelsPerMeter = PelsPerMeter; bih.biYPelsPerMeter = PelsPerMeter; IntPtr pBits = IntPtr.Zero; IntPtr pBIH = LocalAlloc(GPTR, bih.biSize); Marshal.StructureToPtr(bih, pBIH, false); IntPtr hBitmap = CreateDIBSection(hDC, pBIH, 0, ref pBits, IntPtr.Zero, 0); BITMAPINFOHEADER bihMem = (BITMAPINFOHEADER)Marshal.PtrToStructure(pBIH, typeof(BITMAPINFOHEADER)); IntPtr hPreviousBitmap = SelectObject(hMemoryDC, hBitmap); BitBlt(hMemoryDC, 0, 0, bih.biWidth, bih.biHeight, hDC, 0, 0, SRCCOPY); byte[] bits = new byte[cb]; Marshal.Copy(pBits, bits, 0, cb); BITMAPFILEHEADER bfh = new BITMAPFILEHEADER(); bfh.bfSize = (uint)cb + 0x36; bfh.bfType = 0x4d42; bfh.bfOffBits = 0x36; int headerSize = 14; byte[] header = new byte[headerSize]; BitConverter.GetBytes(bfh.bfType).CopyTo(header, 0); BitConverter.GetBytes(bfh.bfSize).CopyTo(header, 2); BitConverter.GetBytes(bfh.bfOffBits).CopyTo(header, 10); byte[] data = new byte[cb + bfh.bfOffBits]; header.CopyTo(data, 0); header = new byte[Marshal.SizeOf(bih)]; IntPtr pHeader = LocalAlloc(GPTR, Marshal.SizeOf(bih)); Marshal.StructureToPtr(bihMem, pHeader, false); Marshal.Copy(pHeader, header, 0, Marshal.SizeOf(bih)); LocalFree(pHeader); header.CopyTo(data, headerSize); bits.CopyTo(data, (int)bfh.bfOffBits); DeleteObject(SelectObject(hMemoryDC, hPreviousBitmap)); DeleteDC(hMemoryDC); ReleaseDC(hDC); return(data); }
public static extern int ICSendMessage(IntPtr hic, uint Message, ref BITMAPINFOHEADER dw1, UIntPtr dw2);
/** * Sets the recording options of the AVI stream * @return void * @private */ unsafe private void SetOptions() { string[] codecs = GetSortedCodecs(); if (codecs.Length < 1) { throw new Exception("No codecs found."); } string usefourcc; //Check for more efficient lossy codecs //Just a note: There is probably a better way to handle this if (Array.IndexOf(codecs, "XVID") > -1) { usefourcc = codecs[Array.IndexOf(codecs, "XVID")]; //Great codec! } else if (Array.IndexOf(codecs, "DIVX") > -1) { usefourcc = codecs[Array.IndexOf(codecs, "XVID")]; //Another good one! } else if (Array.IndexOf(codecs, "UYVY") > -1) { usefourcc = codecs[Array.IndexOf(codecs, "UYVY")]; //used for hd } else if (Array.IndexOf(codecs, "mrle") > -1) { usefourcc = codecs[Array.IndexOf(codecs, "mrle")]; //poor quality } else if (Array.IndexOf(codecs, "msvc") > -1) { usefourcc = codecs[Array.IndexOf(codecs, "msvc")]; //Shipped with windows (let's default to this) } else { usefourcc = codecs[0]; //Could find any in the list, let's just default to the first one. } //UnityEngine.Debug.Log("Chose codec: "+usefourcc); //Here let's create the FourCC FourCC.FourCC fcc = new FourCC.FourCC(usefourcc); AVICOMPRESSOPTIONS opts = new AVICOMPRESSOPTIONS(); opts.fccType = 0; //fccType_; opts.fccHandler = 541215044; //fccHandler_; opts.dwKeyFrameEvery = 0; opts.dwQuality = 0; // 0 .. 10000 opts.dwFlags = 8; //0; // AVICOMRPESSF_KEYFRAMES = 4 opts.dwBytesPerSecond = 0; opts.lpFormat = (System.IntPtr) 0; //new IntPtr(0); opts.cbFormat = 0; opts.lpParms = (System.IntPtr) 0; //new IntPtr(0); opts.cbParms = 0; opts.dwInterleaveEvery = 0; AVICOMPRESSOPTIONS * p = &opts; AVICOMPRESSOPTIONS **pp = &p; IntPtr x = ps_; IntPtr *ptr_ps = &x; 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; // 0 = BI_RGB 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); } }
public ICONIMAGE(int width, int height, byte[] colors) { this.Header = new BITMAPINFOHEADER(width, height << 1, (8 * colors.Length) / (width * height)); this.Colors = colors; MaskSize = (width * height) >> 3; }
public static extern int AVIStreamGetFrameOpen( IntPtr pAVIStream, ref BITMAPINFOHEADER bih);
private byte[] GetBitmapFileHeader(int imgWidth, int imgHeight, System.Drawing.Imaging.ColorPalette colorPalette = null) { var rgbSize = Marshal.SizeOf(typeof(RGBQUAD)); //height is < 0 since image is flipped var bmpInfoHeader = new BITMAPINFOHEADER(imgWidth, -imgHeight, (uint)(imgHeight * imgWidth)); var headerSize = Marshal.SizeOf(bmpInfoHeader) + Marshal.SizeOf(typeof(BITMAPFILEHEADER)) + rgbSize * 256; var bmpFileHeader = new BITMAPFILEHEADER((uint)(imgWidth * imgHeight + headerSize), (uint)headerSize); List<byte> palette = new List<byte>(256); //if palete is not provided if (colorPalette == null) { //fill palette with shades of gray for (int i = 0; i < 256; i++) { palette.AddRange(RlViewer.Behaviors.Converters.StructIO.WriteStruct<RGBQUAD>(new RGBQUAD((byte)i, (byte)i, (byte)i))); } } else { for (int i = 0; i < 256; i++) { var color = colorPalette.Entries[i]; palette.AddRange(RlViewer.Behaviors.Converters.StructIO.WriteStruct<RGBQUAD>(new RGBQUAD((byte)color.R, (byte)color.G, (byte)color.B))); } } List<byte> bmpHeader = new List<byte>(); bmpHeader.AddRange(RlViewer.Behaviors.Converters.StructIO.WriteStruct<BITMAPFILEHEADER>(bmpFileHeader)); bmpHeader.AddRange(RlViewer.Behaviors.Converters.StructIO.WriteStruct<BITMAPINFOHEADER>(bmpInfoHeader)); bmpHeader.AddRange(palette); return bmpHeader.ToArray(); }
public static extern AVIError AVIStreamReadFormat(IntPtr pavi, int lPos, ref BITMAPINFOHEADER lpFormat, ref int lpcbFormat);
public bool CanCompress(BITMAPINFOHEADER format) { return(this == Find(format, this)); }
static extern int SetDIBits(IntPtr hDC, IntPtr hBitmap, uint start, uint clines, byte[] lpvBits, ref BITMAPINFOHEADER lpbmi, uint colorUse);
/// <summary>Initialize the AviFile.</summary> /// <param name="path">The path to the output file.</param> /// <param name="frameRate">The frame rate for the video.</param> /// <param name="width">The width of the video.</param> /// <param name="height">The height of the video.</param> /// <param name="fourcc">The FOURCC compression value to use. A value of null means no compression is used.</param> public AviImageWriter(string path, int frameRate, int width, int height) { // Validate parameters if (path == null) { throw new ArgumentNullException("path"); } if (frameRate <= 0) { throw new ArgumentOutOfRangeException("frameRate", frameRate, "The frame rate must be at least 1 frame per second."); } if (width <= 0) { throw new ArgumentOutOfRangeException("width", width, "The width must be at least 1."); } if (height <= 0) { throw new ArgumentOutOfRangeException("height", height, "The height must be at least 1."); } // Store parameters uint fccType = GetFourCc("vids"); _width = width; _height = height; _disposed = false; // Get the stride information by creating a new bitmap and querying it using (Bitmap bmp = new Bitmap(width, height, PixelFormat.Format24bppRgb)) { BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); _stride = (uint)bmpData.Stride; bmp.UnlockBits(bmpData); } try { // Initialize the AVI library AVIFileInit(); // Open the output AVI file int rv = AVIFileOpenW(ref _aviFile, path, AVI_OPEN_MODE_CREATEWRITE, 0); if (rv != 0) { throw new Win32Exception(((AviErrors)rv).ToString()); } // Create a new stream in the avi file AVISTREAMINFOW aviStreamInfo = new AVISTREAMINFOW(); aviStreamInfo.fccType = fccType; aviStreamInfo.fccHandler = 0; aviStreamInfo.dwScale = 1; aviStreamInfo.dwRate = (uint)frameRate; aviStreamInfo.dwSuggestedBufferSize = (uint)(_height * _stride); aviStreamInfo.dwQuality = 0xffffffff; aviStreamInfo.rcFrame = new RECT(); aviStreamInfo.rcFrame.bottom = _height; aviStreamInfo.rcFrame.right = _width; rv = AVIFileCreateStream(_aviFile, out _aviStream, ref aviStreamInfo); if (rv != 0) { throw new Win32Exception(((AviErrors)rv).ToString()); } // Configure the compressed stream BITMAPINFOHEADER streamFormat = new BITMAPINFOHEADER(); streamFormat.biSize = 40; streamFormat.biWidth = _width; streamFormat.biHeight = _height; streamFormat.biPlanes = 1; streamFormat.biBitCount = 24; streamFormat.biSizeImage = (uint)(_stride * _height); rv = AVIStreamSetFormat(_aviStream, 0, ref streamFormat, 40); if (rv != 0) { throw new Win32Exception(((AviErrors)rv).ToString()); //, "Unable to set the AVI stream format."); } } catch { // Clean up Dispose(false); try { if (path != null && File.Exists(path)) { File.Delete(path); } } catch {} throw; } }
public static byte[] WriteToBMP(ref BITMAP_WRITE_REQUEST info, byte *sourceBufferStart, BITMASKS masks, ushort nbits, uint bcwFlags) { bool skipFileHeader = (bcwFlags & BC_WRITE_SKIP_FH) > 0; bool forceV5 = (bcwFlags & BC_WRITE_V5) > 0; bool forceInfo = (bcwFlags & BC_WRITE_VINFO) > 0; if (forceV5 && forceInfo) { throw new ArgumentException("ForceV5 and ForceInfo flags can not be used at the same time."); } // NOT SUPPORTED RIGHT NOW bool iccEmbed = false; byte[] iccProfileData = new byte[0]; var hasAlpha = masks.maskAlpha != 0; if (nbits < 16 && (info.imgColorTable == null || info.imgColorTable.Length == 0)) { throw new InvalidOperationException("A indexed bitmap must have a color table / palette."); } //int dpiToPelsPM(double dpi) //{ // if (Math.Round(dpi) == 96d) return 0; // return (int)Math.Round(dpi / 0.0254d); //} uint paletteSize = info.imgColorTable == null ? 0 : (uint)info.imgColorTable.Length; var fhSize = (uint)Marshal.SizeOf <BITMAPFILEHEADER>(); var quadSize = (uint)Marshal.SizeOf <RGBQUAD>(); byte[] buffer; uint pxOffset, pxSize; // BI_BITFIELDS is not valid for 24bpp, so if the masks are not RGB we need to use a V5 header. //var nonStandard24bpp = nbits == 24 && !BitmapCorePixelFormat2.Bgr24.IsMatch(24, masks); BitmapCompressionMode compr = BitmapCompressionMode.BI_RGB; // some parsers do not respect the v5 header masks unless BI_BITFIELDS is used... // this is true of Chrome (only for 16bpp) and is also true of FireFox (16 and 32bpp) if (nbits == 16 || nbits == 32) { compr = BitmapCompressionMode.BI_BITFIELDS; } // write V5 header if embedded color profile or has alpha data if (forceV5 || hasAlpha || iccEmbed) { var v5Size = (uint)Marshal.SizeOf <BITMAPV5HEADER>(); // Typical structure: // - BITMAPFILEHEADER (Optional) // - BITMAPV5HEADER // - * Note, never write BI_BITFIELDS at the end of a V5 header, these masks are contained within the header itself // - Color Table (Optional) // - Pixel Data // - Embedded Color Profile (Optional) var fh = new BITMAPFILEHEADER { bfType = BFH_BM, }; var v5 = new BITMAPV5HEADER { bV5Size = v5Size, bV5Planes = 1, bV5BitCount = nbits, bV5Height = info.imgTopDown ? -info.imgHeight : info.imgHeight, bV5Width = info.imgWidth, bV5Compression = compr, bV5XPelsPerMeter = 0, bV5YPelsPerMeter = 0, bV5RedMask = masks.maskRed, bV5GreenMask = masks.maskGreen, bV5BlueMask = masks.maskBlue, bV5AlphaMask = masks.maskAlpha, bV5ClrImportant = paletteSize, bV5ClrUsed = paletteSize, bV5SizeImage = (uint)(info.imgStride * info.imgHeight), bV5CSType = ColorSpaceType.LCS_sRGB, bV5Intent = Bv5Intent.LCS_GM_IMAGES, }; uint offset = skipFileHeader ? 0 : fhSize; offset += v5Size; offset += paletteSize * quadSize; // fh offset points to beginning of pixel data fh.bfOffBits = pxOffset = offset; pxSize = v5.bV5SizeImage; offset += v5.bV5SizeImage; if (iccEmbed) { v5.bV5CSType = ColorSpaceType.PROFILE_EMBEDDED; v5.bV5ProfileData = offset; v5.bV5ProfileSize = (uint)iccProfileData.Length; offset += v5.bV5ProfileSize; } // fh size must be total file size fh.bfSize = offset; buffer = new byte[offset]; offset = 0; if (!skipFileHeader) { StructUtil.SerializeTo(fh, buffer, ref offset); } StructUtil.SerializeTo(v5, buffer, ref offset); if (info.imgColorTable != null) { foreach (var p in info.imgColorTable) { StructUtil.SerializeTo(p, buffer, ref offset); } } Marshal.Copy((IntPtr)sourceBufferStart, buffer, (int)offset, (int)v5.bV5SizeImage); offset += v5.bV5SizeImage; if (iccEmbed) { Buffer.BlockCopy(iccProfileData, 0, buffer, (int)offset, iccProfileData.Length); } } else { var infoSize = (uint)Marshal.SizeOf <BITMAPINFOHEADER>(); // Typical structure: // - BITMAPFILEHEADER (Optional) // - BITMAPINFOHEADER // - BI_BITFIELDS (Optional) // - Color Table (Optional) // - Pixel Data // this would be ideal, we can specify transparency in VINFO headers... but many applications incl FireFox do not support this. // if (hasAlpha) compr = BitmapCompressionMode.BI_ALPHABITFIELDS; var fh = new BITMAPFILEHEADER { bfType = BFH_BM, }; var vinfo = new BITMAPINFOHEADER { bV5Size = infoSize, bV5Planes = 1, bV5BitCount = nbits, bV5Height = info.imgTopDown ? -info.imgHeight : info.imgHeight, bV5Width = info.imgWidth, bV5Compression = compr, bV5XPelsPerMeter = 0, bV5YPelsPerMeter = 0, bV5ClrImportant = paletteSize, bV5ClrUsed = paletteSize, bV5SizeImage = (uint)(info.imgStride * info.imgHeight), }; uint offset = skipFileHeader ? 0 : fhSize; offset += infoSize; if (compr == BitmapCompressionMode.BI_BITFIELDS) { offset += sizeof(uint) * 3; } offset += paletteSize * quadSize; // fh offset points to beginning of pixel data fh.bfOffBits = pxOffset = offset; pxSize = vinfo.bV5SizeImage; offset += vinfo.bV5SizeImage; // fh size must be total file size fh.bfSize = offset; buffer = new byte[offset]; offset = 0; if (!skipFileHeader) { StructUtil.SerializeTo(fh, buffer, ref offset); } StructUtil.SerializeTo(vinfo, buffer, ref offset); if (compr == BitmapCompressionMode.BI_BITFIELDS) { Buffer.BlockCopy(masks.BITFIELDS(), 0, buffer, (int)offset, sizeof(uint) * 3); offset += sizeof(uint) * 3; } if (info.imgColorTable != null) { foreach (var p in info.imgColorTable) { StructUtil.SerializeTo(p, buffer, ref offset); } } Marshal.Copy((IntPtr)sourceBufferStart, buffer, (int)offset, (int)vinfo.bV5SizeImage); } return(buffer); }
public static extern IntPtr CreateDIBSection(IntPtr hdc, [In] ref BITMAPINFOHEADER pbmi, uint pila, out IntPtr ppvBits, IntPtr hSection, uint dwOffset);
/******************************************* * 函数名称:WriteBitmap * 函数功能:将传进来的数据保存为图片 * 函数入参:buffer---图片数据 * nWidth---图片的宽度 * nHeight---图片的高度 * 函数出参:无 * 函数返回:无 *********************************************/ public static void WriteBitmap(byte[] buffer, int nWidth, int nHeight) { int ColorIndex = 0; ushort m_nBitCount = 8; int m_nColorTableEntries = 256; byte[] ResBuf = new byte[nWidth * nHeight]; try { BITMAPFILEHEADER BmpHeader = new BITMAPFILEHEADER(); BITMAPINFOHEADER BmpInfoHeader = new BITMAPINFOHEADER(); MASK[] ColorMask = new MASK[m_nColorTableEntries]; int w = (((nWidth + 3) / 4) * 4); //图片头信息 BmpInfoHeader.biSize = Marshal.SizeOf(BmpInfoHeader); BmpInfoHeader.biWidth = nWidth; BmpInfoHeader.biHeight = nHeight; BmpInfoHeader.biPlanes = 1; BmpInfoHeader.biBitCount = m_nBitCount; BmpInfoHeader.biCompression = 0; BmpInfoHeader.biSizeImage = 0; BmpInfoHeader.biXPelsPerMeter = 0; BmpInfoHeader.biYPelsPerMeter = 0; BmpInfoHeader.biClrUsed = m_nColorTableEntries; BmpInfoHeader.biClrImportant = m_nColorTableEntries; //文件头信息 BmpHeader.bfType = 0x4D42; BmpHeader.bfOffBits = 14 + Marshal.SizeOf(BmpInfoHeader) + BmpInfoHeader.biClrUsed * 4; BmpHeader.bfSize = BmpHeader.bfOffBits + ((((w * BmpInfoHeader.biBitCount + 31) / 32) * 4) * BmpInfoHeader.biHeight); BmpHeader.bfReserved1 = 0; BmpHeader.bfReserved2 = 0; Stream FileStream = File.Open("finger.bmp", FileMode.Create, FileAccess.Write); BinaryWriter TmpBinaryWriter = new BinaryWriter(FileStream); TmpBinaryWriter.Write(StructToBytes(BmpHeader, 14)); TmpBinaryWriter.Write(StructToBytes(BmpInfoHeader, Marshal.SizeOf(BmpInfoHeader))); //调试板信息 for (ColorIndex = 0; ColorIndex < m_nColorTableEntries; ColorIndex++) { ColorMask[ColorIndex].redmask = (byte)ColorIndex; ColorMask[ColorIndex].greenmask = (byte)ColorIndex; ColorMask[ColorIndex].bluemask = (byte)ColorIndex; ColorMask[ColorIndex].rgbReserved = 0; TmpBinaryWriter.Write(StructToBytes(ColorMask[ColorIndex], Marshal.SizeOf(ColorMask[ColorIndex]))); } //图片旋转,解决指纹图片倒立的问题 RotatePic(buffer, nWidth, nHeight, ref ResBuf); //写图片 //TmpBinaryWriter.Write(ResBuf); byte[] filter = null; if (w - nWidth > 0) { filter = new byte[w - nWidth]; } for (int i = 0; i < nHeight; i++) { TmpBinaryWriter.Write(ResBuf, i * nWidth, nWidth); if (w - nWidth > 0) { TmpBinaryWriter.Write(ResBuf, 0, w - nWidth); } } FileStream.Close(); TmpBinaryWriter.Close(); } catch (Exception ex) { //ZKCE.SysException.ZKCELogger logger = new ZKCE.SysException.ZKCELogger(ex); //logger.Append(); } }
/// <summary> /// Helper method to try to get an image in the specified format from the dataObject /// the DIB readed should solve the issue reported here: https://sourceforge.net/projects/greenshot/forums/forum/676083/topic/6354353/index/page/1 /// It also supports Format17/DibV5, by using the following information: http://stackoverflow.com/a/14335591 /// </summary> /// <param name="format">string with the format</param> /// <param name="dataObject">IDataObject</param> /// <returns>Image or null</returns> private static Image GetImageForFormat(string format, IDataObject dataObject) { object clipboardObject = GetFromDataObject(dataObject, format); MemoryStream imageStream = clipboardObject as MemoryStream; if (!isValidStream(imageStream)) { // add "HTML Format" support here... return(clipboardObject as Image); } else { if (config.EnableSpecialDIBClipboardReader) { if (format == FORMAT_17 || format == DataFormats.Dib) { LOG.Info("Found DIB stream, trying to process it."); try { byte[] dibBuffer = new byte[imageStream.Length]; imageStream.Read(dibBuffer, 0, dibBuffer.Length); BITMAPINFOHEADER infoHeader = BinaryStructHelper.FromByteArray <BITMAPINFOHEADER>(dibBuffer); if (!infoHeader.IsDibV5) { LOG.InfoFormat("Using special DIB <v5 format reader with biCompression {0}", infoHeader.biCompression); int fileHeaderSize = Marshal.SizeOf(typeof(BITMAPFILEHEADER)); uint infoHeaderSize = infoHeader.biSize; int fileSize = (int)(fileHeaderSize + infoHeader.biSize + infoHeader.biSizeImage); BITMAPFILEHEADER fileHeader = new BITMAPFILEHEADER(); fileHeader.bfType = BITMAPFILEHEADER.BM; fileHeader.bfSize = fileSize; fileHeader.bfReserved1 = 0; fileHeader.bfReserved2 = 0; fileHeader.bfOffBits = (int)(fileHeaderSize + infoHeaderSize + infoHeader.biClrUsed * 4); byte[] fileHeaderBytes = BinaryStructHelper.ToByteArray <BITMAPFILEHEADER>(fileHeader); using (MemoryStream bitmapStream = new MemoryStream()) { bitmapStream.Write(fileHeaderBytes, 0, fileHeaderSize); bitmapStream.Write(dibBuffer, 0, dibBuffer.Length); bitmapStream.Seek(0, SeekOrigin.Begin); using (Image tmpImage = Image.FromStream(bitmapStream)) { if (tmpImage != null) { return(ImageHelper.Clone(tmpImage)); } } } } else { LOG.Info("Using special DIBV5 / Format17 format reader"); // CF_DIBV5 IntPtr gcHandle = IntPtr.Zero; try { GCHandle handle = GCHandle.Alloc(dibBuffer, GCHandleType.Pinned); gcHandle = GCHandle.ToIntPtr(handle); return(new Bitmap(infoHeader.biWidth, infoHeader.biHeight, -(int)(infoHeader.biSizeImage / infoHeader.biHeight), infoHeader.biBitCount == 32 ? PixelFormat.Format32bppArgb : PixelFormat.Format24bppRgb, new IntPtr(handle.AddrOfPinnedObject().ToInt32() + infoHeader.OffsetToPixels + (infoHeader.biHeight - 1) * (int)(infoHeader.biSizeImage / infoHeader.biHeight)))); } catch (Exception ex) { LOG.Error("Problem retrieving Format17 from clipboard.", ex); } finally { if (gcHandle == IntPtr.Zero) { GCHandle.FromIntPtr(gcHandle).Free(); } } } } catch (Exception dibEx) { LOG.Error("Problem retrieving DIB from clipboard.", dibEx); } } } else { LOG.Info("Skipping special DIB format reader as it's disabled in the configuration."); } try { imageStream.Seek(0, SeekOrigin.Begin); using (Image tmpImage = Image.FromStream(imageStream, true, true)) { if (tmpImage != null) { LOG.InfoFormat("Got image with clipboard format {0} from the clipboard.", format); return(ImageHelper.Clone(tmpImage)); } } } catch (Exception streamImageEx) { LOG.Error(string.Format("Problem retrieving {0} from clipboard.", format), streamImageEx); } } return(null); }
public static extern int AVIStreamGetFrameOpen( IntPtr pAVIStream, ref BITMAPINFOHEADER bih);
public static void SetClipboardData(ISurface surface) { DataObject dataObject = new DataObject(); // This will work for Office and most other applications //ido.SetData(DataFormats.Bitmap, true, image); MemoryStream dibStream = null; MemoryStream dibV5Stream = null; MemoryStream pngStream = null; Image imageToSave = null; bool disposeImage = false; try { SurfaceOutputSettings outputSettings = new SurfaceOutputSettings(OutputFormat.png, 100, false); // Create the image which is going to be saved so we don't create it multiple times disposeImage = ImageOutput.CreateImageFromSurface(surface, outputSettings, out imageToSave); try { // Create PNG stream if (config.ClipboardFormats.Contains(ClipboardFormat.PNG)) { pngStream = new MemoryStream(); // PNG works for e.g. Powerpoint SurfaceOutputSettings pngOutputSettings = new SurfaceOutputSettings(OutputFormat.png, 100, false); ImageOutput.SaveToStream(imageToSave, null, pngStream, pngOutputSettings); pngStream.Seek(0, SeekOrigin.Begin); // Set the PNG stream dataObject.SetData(FORMAT_PNG, false, pngStream); } } catch (Exception pngEX) { LOG.Error("Error creating PNG for the Clipboard.", pngEX); } try { if (config.ClipboardFormats.Contains(ClipboardFormat.DIB)) { using (MemoryStream tmpBmpStream = new MemoryStream()) { // Save image as BMP SurfaceOutputSettings bmpOutputSettings = new SurfaceOutputSettings(OutputFormat.bmp, 100, false); ImageOutput.SaveToStream(imageToSave, null, tmpBmpStream, bmpOutputSettings); dibStream = new MemoryStream(); // Copy the source, but skip the "BITMAPFILEHEADER" which has a size of 14 dibStream.Write(tmpBmpStream.GetBuffer(), BITMAPFILEHEADER_LENGTH, (int)tmpBmpStream.Length - BITMAPFILEHEADER_LENGTH); } // Set the DIB to the clipboard DataObject dataObject.SetData(DataFormats.Dib, true, dibStream); } } catch (Exception dibEx) { LOG.Error("Error creating DIB for the Clipboard.", dibEx); } // CF_DibV5 try { if (config.ClipboardFormats.Contains(ClipboardFormat.DIBV5)) { // Create the stream for the clipboard dibV5Stream = new MemoryStream(); // Create the BITMAPINFOHEADER BITMAPINFOHEADER header = new BITMAPINFOHEADER(imageToSave.Width, imageToSave.Height, 32); // Make sure we have BI_BITFIELDS, this seems to be normal for Format17? header.biCompression = BI_COMPRESSION.BI_BITFIELDS; // Create a byte[] to write byte[] headerBytes = BinaryStructHelper.ToByteArray <BITMAPINFOHEADER>(header); // Write the BITMAPINFOHEADER to the stream dibV5Stream.Write(headerBytes, 0, headerBytes.Length); // As we have specified BI_COMPRESSION.BI_BITFIELDS, the BitfieldColorMask needs to be added BitfieldColorMask colorMask = new BitfieldColorMask(); // Make sure the values are set colorMask.InitValues(); // Create the byte[] from the struct byte[] colorMaskBytes = BinaryStructHelper.ToByteArray <BitfieldColorMask>(colorMask); Array.Reverse(colorMaskBytes); // Write to the stream dibV5Stream.Write(colorMaskBytes, 0, colorMaskBytes.Length); // Create the raw bytes for the pixels only byte[] bitmapBytes = BitmapToByteArray((Bitmap)imageToSave); // Write to the stream dibV5Stream.Write(bitmapBytes, 0, bitmapBytes.Length); // Set the DIBv5 to the clipboard DataObject dataObject.SetData(FORMAT_17, true, dibV5Stream); } } catch (Exception dibEx) { LOG.Error("Error creating DIB for the Clipboard.", dibEx); } // Set the HTML if (config.ClipboardFormats.Contains(ClipboardFormat.HTML)) { string tmpFile = ImageOutput.SaveToTmpFile(surface, new SurfaceOutputSettings(OutputFormat.png, 100, false), null); string html = getHTMLString(surface, tmpFile); dataObject.SetText(html, TextDataFormat.Html); } else if (config.ClipboardFormats.Contains(ClipboardFormat.HTMLDATAURL)) { string html; using (MemoryStream tmpPNGStream = new MemoryStream()) { SurfaceOutputSettings pngOutputSettings = new SurfaceOutputSettings(OutputFormat.png, 100, false); // Do not allow to reduce the colors, some applications dislike 256 color images // reported with bug #3594681 pngOutputSettings.DisableReduceColors = true; // Check if we can use the previously used image if (imageToSave.PixelFormat != PixelFormat.Format8bppIndexed) { ImageOutput.SaveToStream(imageToSave, surface, tmpPNGStream, pngOutputSettings); } else { ImageOutput.SaveToStream(surface, tmpPNGStream, pngOutputSettings); } html = getHTMLDataURLString(surface, tmpPNGStream); } dataObject.SetText(html, TextDataFormat.Html); } } finally { // we need to use the SetDataOject before the streams are closed otherwise the buffer will be gone! // Check if Bitmap is wanted if (config.ClipboardFormats.Contains(ClipboardFormat.BITMAP)) { dataObject.SetImage(imageToSave); // Place the DataObject to the clipboard SetDataObject(dataObject, true); } else { // Place the DataObject to the clipboard SetDataObject(dataObject, true); } if (pngStream != null) { pngStream.Dispose(); pngStream = null; } if (dibStream != null) { dibStream.Dispose(); dibStream = null; } if (dibV5Stream != null) { dibV5Stream.Dispose(); dibV5Stream = null; } // cleanup if needed if (disposeImage && imageToSave != null) { imageToSave.Dispose(); } } }
public bool AddFrame(Bitmap bmp) { if (bmp.PixelFormat != m_pix_fmt) { return(false); } BitmapData bdat = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, bmp.PixelFormat); BinaryWriter bw = new BinaryWriter(new MemoryStream()); if (!m_header_written) { m_bitmapsize = (uint)(bdat.Stride * bdat.Height); //m_stream.SetLength( (long)(0xdc + (m_bitmapsize + 0x8) * m_frames) ); /*m_main_avi_header.dwWidth = (uint)bdat.Width; * m_main_avi_header.dwHeight = (uint)bdat.Height;// bmp%infoHeader%Height * m_main_avi_header.dwMaxBytesPerSec = (uint)((float)bdat.Stride * (float)bdat.Height * (float)m_rate / (float)m_scale); * m_main_avi_header.dwStreams = 1; * m_main_avi_header.dwSuggestedBufferSize = (uint)(bdat.Stride * bdat.Height); * * AVIStreamHeader stream_header = new AVIStreamHeader(); * stream_header.fccType = Util.mmioFOURCC( "vids" ); * stream_header.fccHandler = 0; * stream_header.dwFlags = 0; * stream_header.dwReserved1 = 0; * stream_header.dwInitialFrames = 0; * stream_header.dwScale = m_scale; * stream_header.dwRate = m_rate; * stream_header.dwStart = 0; * stream_header.dwSuggestedBufferSize = m_main_avi_header.dwSuggestedBufferSize; * stream_header.dwQuality = 0; * stream_header.dwSampleSize = 0; * * BITMAPINFOHEADER bih = new BITMAPINFOHEADER(); //(BITMAPINFOHEADER)Marshal.PtrToStructure( Marshal.AllocHGlobal( sizeof( BITMAPINFOHEADER ) ), typeof( BITMAPINFOHEADER ) ); * bih.biSize = (uint)(Marshal.SizeOf( bih )); * bih.biWidth = bdat.Width; * bih.biHeight = bdat.Height; * bih.biPlanes = 1; * bih.biBitCount = m_pix_fmt == PixelFormat.Format24bppRgb ? (short)24 : (short)32; * bih.biCompression = 0;//BI_RGB * bih.biSizeImage = (uint)(bdat.Stride * bdat.Height); * bih.biXPelsPerMeter = 0; * bih.biYPelsPerMeter = 0; * bih.biClrUsed = 0; * bih.biClrImportant = 0; * * bw.Write( "RIFF".ToCharArray() ); * bw.Write( (uint)(0xdc + (m_bitmapsize + 0x8) * m_frames) ); * bw.Write( "AVI ".ToCharArray() ); * bw.Write( "LIST".ToCharArray() ); * bw.Write( (uint)0xc0 ); * bw.Write( "hdrl".ToCharArray() ); * bw.Write( "avih".ToCharArray() ); * bw.Write( (uint)0x38 ); * m_main_avi_header.Write( bw.BaseStream ); * bw.Write( "LIST".ToCharArray() ); * bw.Write( (uint)0x7C ); * bw.Write( "strl".ToCharArray() ); * bw.Write( "strh".ToCharArray() ); * bw.Write( (uint)0x38 ); * stream_header.Write( bw.BaseStream ); * bw.Write( (uint)0x0 ); * bw.Write( (uint)0x0 ); * bw.Write( "strf".ToCharArray() ); * bw.Write( (uint)0x28 ); * bih.Write( bw.BaseStream ); * bw.Write( "LIST".ToCharArray() ); * bw.Write( (uint)((m_bitmapsize + 0x8) * m_frames) ); * bw.Write( "movi".ToCharArray() );*/ m_header_written = true; } //bw.Write( "00db" ); //bw.Write( (uint)m_bitmapsize ); int address = bdat.Scan0.ToInt32(); byte[] bitmapData = new byte[bdat.Stride * bdat.Height]; Marshal.Copy(new IntPtr(address), bitmapData, 0, bitmapData.Length); //bw.Write( (uint)m_main_avi_header.dwSuggestedBufferSize ); bw.Write("BM".ToCharArray()); bw.Write(m_bitmapsize); bw.Write((uint)0x0); bw.Write((uint)0x36); BITMAPINFOHEADER bih = new BITMAPINFOHEADER(); //(BITMAPINFOHEADER)Marshal.PtrToStructure( Marshal.AllocHGlobal( sizeof( BITMAPINFOHEADER ) ), typeof( BITMAPINFOHEADER ) ); bih.biSize = (uint)(Marshal.SizeOf(bih)); bih.biWidth = bdat.Width; bih.biHeight = bdat.Height; bih.biPlanes = 1; bih.biBitCount = m_pix_fmt == PixelFormat.Format24bppRgb ? (short)24 : (short)32; bih.biCompression = 0;//BI_RGB bih.biSizeImage = (uint)(bdat.Stride * bdat.Height); bih.biXPelsPerMeter = 0; bih.biYPelsPerMeter = 0; bih.biClrUsed = 0; bih.biClrImportant = 0; bih.Write(bw); bw.Write(bitmapData, 0, bitmapData.Length); //const int _BUF_LEN = 512; byte[] buf = new byte[m_bitmapsize + 6]; bw.BaseStream.Seek(0, SeekOrigin.Begin); int len = bw.BaseStream.Read(buf, 0, (int)(m_bitmapsize + 6)); if (len > 0) { m_stream.BeginWrite(buf, 0, len, null, null); } m_stream.Flush(); bw.Close(); bmp.UnlockBits(bdat); return(true); }
/******************************************* * *********************************************/ public static void GetBitmap(byte[] buffer, int nWidth, int nHeight, ref MemoryStream ms) { int ColorIndex = 0; ushort m_nBitCount = 8; int m_nColorTableEntries = 256; byte[] ResBuf = new byte[nWidth * nHeight * 2]; try { BITMAPFILEHEADER BmpHeader = new BITMAPFILEHEADER(); BITMAPINFOHEADER BmpInfoHeader = new BITMAPINFOHEADER(); MASK[] ColorMask = new MASK[m_nColorTableEntries]; int w = (((nWidth + 3) / 4) * 4); BmpInfoHeader.biSize = Marshal.SizeOf(BmpInfoHeader); BmpInfoHeader.biWidth = nWidth; BmpInfoHeader.biHeight = nHeight; BmpInfoHeader.biPlanes = 1; BmpInfoHeader.biBitCount = m_nBitCount; BmpInfoHeader.biCompression = 0; BmpInfoHeader.biSizeImage = 0; BmpInfoHeader.biXPelsPerMeter = 0; BmpInfoHeader.biYPelsPerMeter = 0; BmpInfoHeader.biClrUsed = m_nColorTableEntries; BmpInfoHeader.biClrImportant = m_nColorTableEntries; BmpHeader.bfType = 0x4D42; BmpHeader.bfOffBits = 14 + Marshal.SizeOf(BmpInfoHeader) + BmpInfoHeader.biClrUsed * 4; BmpHeader.bfSize = BmpHeader.bfOffBits + ((((w * BmpInfoHeader.biBitCount + 31) / 32) * 4) * BmpInfoHeader.biHeight); BmpHeader.bfReserved1 = 0; BmpHeader.bfReserved2 = 0; ms.Write(StructToBytes(BmpHeader, 14), 0, 14); ms.Write(StructToBytes(BmpInfoHeader, Marshal.SizeOf(BmpInfoHeader)), 0, Marshal.SizeOf(BmpInfoHeader)); //µ÷ÊÔ°åÐÅÏ¢ for (ColorIndex = 0; ColorIndex < m_nColorTableEntries; ColorIndex++) { ColorMask[ColorIndex].redmask = (byte)ColorIndex; ColorMask[ColorIndex].greenmask = (byte)ColorIndex; ColorMask[ColorIndex].bluemask = (byte)ColorIndex; ColorMask[ColorIndex].rgbReserved = 0; ms.Write(StructToBytes(ColorMask[ColorIndex], Marshal.SizeOf(ColorMask[ColorIndex])), 0, Marshal.SizeOf(ColorMask[ColorIndex])); } //ͼƬÐýת£¬½â¾öÖ¸ÎÆͼƬµ¹Á¢µÄÎÊÌâ RotatePic(buffer, nWidth, nHeight, ref ResBuf); byte[] filter = null; if (w - nWidth > 0) { filter = new byte[w - nWidth]; } for (int i = 0; i < nHeight; i++) { ms.Write(ResBuf, i * nWidth, nWidth); if (w - nWidth > 0) { ms.Write(ResBuf, 0, w - nWidth); } } } catch (Exception) { throw; // ZKCE.SysException.ZKCELogger logger = new ZKCE.SysException.ZKCELogger(ex); // logger.Append(); } }
private static extern int AVIStreamSetFormat(IntPtr pavi, int lPos, ref BITMAPINFOHEADER lpFormat, int cbFormat);
/// <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); 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); 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); } }
public ICONIMAGE(int width, int height, byte[] colors) { Header = new BITMAPINFOHEADER(width, height << 1, (8 * colors.Length) / (width * height)); Colors = colors; MaskSize = (width * height) >> 3; }
protected IntPtr GetPixelInfo( IntPtr bmpptr ) { bmi = new BITMAPINFOHEADER(); Marshal.PtrToStructure( bmpptr, bmi ); bmprect.X = bmprect.Y = 0; bmprect.Width = bmi.biWidth; bmprect.Height = bmi.biHeight; if( bmi.biSizeImage == 0 ) bmi.biSizeImage = ((((bmi.biWidth * bmi.biBitCount) + 31) & ~31) >> 3) * bmi.biHeight; int p = bmi.biClrUsed; if( (p == 0) && (bmi.biBitCount <= 8) ) p = 1 << bmi.biBitCount; p = (p * 4) + bmi.biSize + (int) bmpptr; return (IntPtr) p; }
public static extern IntPtr AVIStreamGetFrameOpen( IntPtr streamHandler, ref BITMAPINFOHEADER wantedFormat);
public byte[] CreateIconGroupData(uint iconBaseID) { // This will store the memory version of the icon. int sizeOfIconGroupData = Marshal.SizeOf(typeof(ICONDIR)) + Marshal.SizeOf(typeof(GRPICONDIRENTRY)) * ImageCount; byte[] data = new byte[sizeOfIconGroupData]; var pinnedData = GCHandle.Alloc(data, GCHandleType.Pinned); Marshal.StructureToPtr(iconDir, pinnedData.AddrOfPinnedObject(), false); var offset = Marshal.SizeOf(iconDir); for (int i = 0; i <= ImageCount - 1; i++) { GRPICONDIRENTRY grpEntry = new GRPICONDIRENTRY(); BITMAPINFOHEADER bitmapheader = new BITMAPINFOHEADER(); var pinnedBitmapInfoHeader = GCHandle.Alloc(bitmapheader, GCHandleType.Pinned); Marshal.Copy(ImageData(i), 0, pinnedBitmapInfoHeader.AddrOfPinnedObject(), Marshal.SizeOf(typeof(BITMAPINFOHEADER))); pinnedBitmapInfoHeader.Free(); grpEntry.Width = iconEntry[i].Width; grpEntry.Height = iconEntry[i].Height; grpEntry.ColorCount = iconEntry[i].ColorCount; grpEntry.Reserved = iconEntry[i].Reserved; grpEntry.Planes = bitmapheader.Planes; grpEntry.BitCount = bitmapheader.BitCount; grpEntry.BytesInRes = iconEntry[i].BytesInRes; grpEntry.ID = Convert.ToUInt16(iconBaseID + i); Marshal.StructureToPtr(grpEntry, new IntPtr(pinnedData.AddrOfPinnedObject().ToInt64() + offset), false); offset += Marshal.SizeOf(typeof(GRPICONDIRENTRY)); } pinnedData.Free(); return data; }
private static extern int AVIStreamSetFormat( IntPtr aviStream, Int32 lPos, ref BITMAPINFOHEADER lpFormat, Int32 cbFormat);
public static extern IntPtr ResizeImage(IntPtr buffer, BITMAPINFOHEADER bminfo, IntPtr newbuffer, BITMAPINFOHEADER newbminfo);
private static extern int AVIStreamSetFormat(IntPtr aviStream, Int32 lPos, ref BITMAPINFOHEADER lpFormat, Int32 cbFormat);
/// <summary> /// aviファイルにフレームを1つ追加します. /// </summary> /// <param name="bmp"></param> public void AddFrame( Bitmap bmp ) { int i, width, height, lineSize; if ( bmp.Width != m_width || bmp.Height != m_height ) { throw new Exception( "bitmap size mismatch" ); } // BitmapDataからビットマップデータと、BITMPAINFOHEADERを取り出す BitmapData bmpDat = bmp.LockBits( new Rectangle( 0, 0, (int)bmp.Width, (int)bmp.Height ), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb ); int address = bmpDat.Scan0.ToInt32(); byte[] bitmapData = new byte[bmpDat.Stride * bmpDat.Height]; Marshal.Copy( new IntPtr( address ), bitmapData, 0, bitmapData.Length ); if ( m_is_first ) {//then m_is_first = false; this.m_main_header.dwWidth = (uint)m_width; this.m_main_header.dwHeight = (uint)m_height; this.m_main_header.dwMaxBytesPerSec = (uint)(bmpDat.Stride * bmpDat.Height * this.frameRate);// bmp%infoHeader%SizeImage * avi%frameRate this.m_main_header.dwStreams = 1; this.m_main_header.dwSuggestedBufferSize = (uint)(bmpDat.Stride * bmpDat.Height);// bmp.infoHeader%SizeImage m_linesize = bmpDat.Stride; this.m_stream_header.fccType = Util.mmioFOURCC( "vids" ); this.m_stream_header.fccHandler = 0; this.m_stream_header.dwFlags = 0; this.m_stream_header.dwReserved1 = 0; this.m_stream_header.dwInitialFrames = 0; this.m_stream_header.dwScale = m_scale; this.m_stream_header.dwRate = m_rate; this.m_stream_header.dwStart = 0; this.m_stream_header.dwSuggestedBufferSize = this.m_main_header.dwSuggestedBufferSize; this.m_stream_header.dwQuality = 0; this.m_stream_header.dwSampleSize = 0; Util.aviWriteMainHeader( m_main_header, m_stream ); Util.fwrite( "LIST", this.m_stream );// i = fwrite( 'LIST', 1, 4, avi%fp ) Util.WriteDWORD( 0x874, this.m_stream );// call bmpQWordWrite( 130, avi%fp ) Util.fwrite( "strl", this.m_stream );// i = fwrite( 'strl', 1, 4, avi%fp ) Util.aviWriteStreamHeader( m_stream_header, m_main_header, m_stream );// avi ) Util.fwrite( "strf", this.m_stream );// i = fwrite( 'strf', 1, 4, avi%fp ) Util.WriteDWORD( 0x28, this.m_stream ); //call bmpQWordWrite( 40, avi%fp ) !// infoHeaderのサイズ BITMAPINFOHEADER bih = new BITMAPINFOHEADER(); bih.biSize = (uint)(Marshal.SizeOf( bih )); bih.biWidth = bmpDat.Width; bih.biHeight = bmpDat.Height; bih.biPlanes = 1; bih.biBitCount = 24; bih.biCompression = 0;//BI_RGB bih.biSizeImage = (uint)(bmpDat.Stride * bmpDat.Height); bih.biXPelsPerMeter = 0; bih.biYPelsPerMeter = 0; bih.biClrUsed = 0; bih.biClrImportant = 0; bih.Write( m_stream ); /*fwrite( "strn", this.fp ); WriteDWORD( 6, this.fp ); fwrite( "VIDEO", this.fp ); WriteBYTE( 0, this.fp );*/ Util.fwrite( "indx", this.m_stream ); //fcc Util.WriteDWORD( 0x7f8, this.m_stream ); // cb Util.WriteWORD( (byte)0x4, this.m_stream ); // wLongsPerEntry Util.WriteBYTE( 0x0, this.m_stream ); // bIndexSubType Util.WriteBYTE( Util.AVI_INDEX_OF_INDEXES, this.m_stream );// bIndexType Util.WriteDWORD( 0x0, this.m_stream ); // nEntriesInUse Util.fwrite( "00db", this.m_stream ); // dwChunkId Util.WriteDWORD( 0x0, this.m_stream ); Util.WriteDWORD( 0x0, this.m_stream ); Util.WriteDWORD( 0x0, this.m_stream ); for ( int ii = 1; ii <= 126; ii++ ) { Util.WriteQWORD( 0x0, this.m_stream ); Util.WriteDWORD( 0x0, this.m_stream ); Util.WriteDWORD( 0x0, this.m_stream ); } Util.fwrite( "LIST", this.m_stream ); Util.WriteDWORD( 0x104, m_stream ); Util.fwrite( "odml", this.m_stream ); Util.fwrite( "dmlh", m_stream ); Util.WriteDWORD( 0xf8, m_stream ); Util.WriteDWORD( 0x0, m_stream );//ここ後で更新するべき for ( int ii = 1; ii <= 61; ii++ ) { Util.WriteDWORD( 0x0, m_stream ); } Util.fwrite( "JUNK", this.m_stream );// i = fwrite( 'JUNK', 1, 4, avi%fp ) Util.WriteDWORD( 0x60c, m_stream ); Util.WriteDWORD( 0, m_stream );//"This"が将来登録されたらやばいので Util.fwrite( "This file was generated by RawAvi@LipSync", this.m_stream ); //WriteDWORD( 1503, this.fp );// call bmpQWordWrite( 1802, avi%fp ) for ( i = 1; i <= 1503; i++ ) {//do i = 1, 1802 this.m_stream.Write( (byte)0 );// call fputc( 0, avi%fp ) }//end do m_junk_length = 0xff4; Util.fwrite( "LIST", this.m_stream );// i = fwrite( 'LIST', 1, 4, avi%fp ) m_movi_position = m_stream.BaseStream.Position; Util.WriteDWORD( 0, this.m_stream );// call bmpQWordWrite( 0, avi%fp ) !// ******************ココの数字は一番最後に書き換える必要あり2040~2043あとdwTotalFrames(48~51)も Util.fwrite( "movi", this.m_stream );// i = fwrite( 'movi', 1, 4, avi%fp ) m_next_framedata_position = m_stream.BaseStream.Position; m_std_index.SetBaseOffset( (ulong)m_next_framedata_position ); m_super_index.nEntriesInUse++; }//end if if ( m_next_framedata_position != m_stream.BaseStream.Position ) { m_stream.BaseStream.Seek( m_next_framedata_position, SeekOrigin.Begin ); } long chunk_size = m_next_framedata_position - m_riff_position; #if DEBUG // MessageBox.Show( "chunk_size=" + chunk_size ); #endif if ( (m_current_chunk == 0 && chunk_size > m_split_sreshold) || (m_current_chunk > 0 && chunk_size > SRESHOLD )) { // AVIXリストへの書き込みに移行 UpdateIndex(); m_stream.BaseStream.Seek( m_avix_position, SeekOrigin.Begin ); Util.fwrite( "RIFF", m_stream ); m_riff_position = m_stream.BaseStream.Position; #if DEBUG // fp.Flush(); // MessageBox.Show( "m_riff_position=" + m_riff_position ); #endif Util.WriteDWORD( 0, m_stream ); Util.fwrite( "AVIX", m_stream ); long current = m_stream.BaseStream.Position; if ( (current + 12) % 0x800 != 0 ) { long additional = (current + 20) % 0x800; additional = 0x800 - ((current + 20) % 0x800); m_junk_length = (int)additional + 20; Util.fwrite( "JUNK", m_stream ); Util.WriteDWORD( (uint)additional, m_stream ); for ( long ii = 0; ii < additional; ii++ ) { Util.WriteBYTE( (byte)0, m_stream ); } } else { m_junk_length = 0; } m_junk_length = 0; Util.fwrite( "LIST", m_stream ); m_movi_position = m_stream.BaseStream.Position; Util.WriteDWORD( 0, m_stream );//後で更新するべき Util.fwrite( "movi", m_stream ); m_next_framedata_position = m_stream.BaseStream.Position; m_std_index.aIndex.Clear(); m_std_index.SetBaseOffset( (ulong)m_next_framedata_position ); m_current_chunk++; m_super_index.nEntriesInUse++; } // フレームを書き込む処理 width = (int)this.m_main_header.dwWidth; height = (int)this.m_main_header.dwHeight; if ( width != bmpDat.Width ) {//then //aviAddFrame = -1 return; }//end if if ( height != bmpDat.Height ) {//then //aviAddframe = -1 return; }//end if lineSize = bmpDat.Stride;// int( (width * 24 + 31) / 32 ) * 4 m_std_index.AddIndex( (uint)((ulong)m_stream.BaseStream.Position - m_std_index.qwBaseOffset) + 8, (uint)(lineSize * height) ); Util.fwrite( "00db", this.m_stream );// i = fwrite( '00db', 1, 4, avi%fp ) Util.WriteDWORD( m_main_header.dwSuggestedBufferSize, m_stream );// call bmpQWordWrite( avi%mainHeader%dwSuggestedBufferSize, avi%fp ) m_stream.Write( bitmapData ); m_next_framedata_position = m_stream.BaseStream.Position; _avisuperindex_entry entry = m_super_index.aIndex[m_current_chunk]; entry.dwDuration++; m_super_index.aIndex[m_current_chunk] = entry;// avi%noOfFrame = avi%noOfFrame + 1 this.m_stream.Flush();// aviAddFrame = fflush( avi%fp ) bmp.UnlockBits( bmpDat ); }// end function
public static extern int AVIStreamReadFormat( IntPtr aviStream, Int32 lPos, ref BITMAPINFOHEADER lpFormat, ref Int32 cbFormat );
public static void SetClipboardData(ISurface surface) { DataObject dataObject = new DataObject(); // This will work for Office and most other applications //ido.SetData(DataFormats.Bitmap, true, image); MemoryStream dibStream = null; MemoryStream dibV5Stream = null; MemoryStream pngStream = null; Image imageToSave = null; bool disposeImage = false; try { SurfaceOutputSettings outputSettings = new SurfaceOutputSettings(OutputFormat.png, 100, false); // Create the image which is going to be saved so we don't create it multiple times disposeImage = ImageOutput.CreateImageFromSurface(surface, outputSettings, out imageToSave); try { // Create PNG stream if (config.ClipboardFormats.Contains(ClipboardFormat.PNG)) { pngStream = new MemoryStream(); // PNG works for e.g. Powerpoint SurfaceOutputSettings pngOutputSettings = new SurfaceOutputSettings(OutputFormat.png, 100, false); ImageOutput.SaveToStream(imageToSave, null, pngStream, pngOutputSettings); pngStream.Seek(0, SeekOrigin.Begin); // Set the PNG stream dataObject.SetData(FORMAT_PNG, false, pngStream); } } catch (Exception pngEX) { LOG.Error("Error creating PNG for the Clipboard.", pngEX); } try { if (config.ClipboardFormats.Contains(ClipboardFormat.DIB)) { using (MemoryStream tmpBmpStream = new MemoryStream()) { // Save image as BMP SurfaceOutputSettings bmpOutputSettings = new SurfaceOutputSettings(OutputFormat.bmp, 100, false); ImageOutput.SaveToStream(imageToSave, null, tmpBmpStream, bmpOutputSettings); dibStream = new MemoryStream(); // Copy the source, but skip the "BITMAPFILEHEADER" which has a size of 14 dibStream.Write(tmpBmpStream.GetBuffer(), BITMAPFILEHEADER_LENGTH, (int)tmpBmpStream.Length - BITMAPFILEHEADER_LENGTH); } // Set the DIB to the clipboard DataObject dataObject.SetData(DataFormats.Dib, true, dibStream); } } catch (Exception dibEx) { LOG.Error("Error creating DIB for the Clipboard.", dibEx); } // CF_DibV5 try { if (config.ClipboardFormats.Contains(ClipboardFormat.DIBV5)) { // Create the stream for the clipboard dibV5Stream = new MemoryStream(); // Create the BITMAPINFOHEADER BITMAPINFOHEADER header = new BITMAPINFOHEADER(imageToSave.Width, imageToSave.Height, 32); // Make sure we have BI_BITFIELDS, this seems to be normal for Format17? header.biCompression = BI_COMPRESSION.BI_BITFIELDS; // Create a byte[] to write byte[] headerBytes = BinaryStructHelper.ToByteArray<BITMAPINFOHEADER>(header); // Write the BITMAPINFOHEADER to the stream dibV5Stream.Write(headerBytes, 0, headerBytes.Length); // As we have specified BI_COMPRESSION.BI_BITFIELDS, the BitfieldColorMask needs to be added BitfieldColorMask colorMask = new BitfieldColorMask(); // Make sure the values are set colorMask.InitValues(); // Create the byte[] from the struct byte[] colorMaskBytes = BinaryStructHelper.ToByteArray<BitfieldColorMask>(colorMask); Array.Reverse(colorMaskBytes); // Write to the stream dibV5Stream.Write(colorMaskBytes, 0, colorMaskBytes.Length); // Create the raw bytes for the pixels only byte[] bitmapBytes = BitmapToByteArray((Bitmap)imageToSave); // Write to the stream dibV5Stream.Write(bitmapBytes, 0, bitmapBytes.Length); // Set the DIBv5 to the clipboard DataObject dataObject.SetData(FORMAT_17, true, dibV5Stream); } } catch (Exception dibEx) { LOG.Error("Error creating DIB for the Clipboard.", dibEx); } // Set the HTML if (config.ClipboardFormats.Contains(ClipboardFormat.HTML)) { string tmpFile = ImageOutput.SaveToTmpFile(surface, new SurfaceOutputSettings(OutputFormat.png, 100, false), null); string html = getHTMLString(surface, tmpFile); dataObject.SetText(html, TextDataFormat.Html); } else if (config.ClipboardFormats.Contains(ClipboardFormat.HTMLDATAURL)) { string html; using (MemoryStream tmpPNGStream = new MemoryStream()) { SurfaceOutputSettings pngOutputSettings = new SurfaceOutputSettings(OutputFormat.png, 100, false); // Do not allow to reduce the colors, some applications dislike 256 color images // reported with bug #3594681 pngOutputSettings.DisableReduceColors = true; // Check if we can use the previously used image if (imageToSave.PixelFormat != PixelFormat.Format8bppIndexed) { ImageOutput.SaveToStream(imageToSave, surface, tmpPNGStream, pngOutputSettings); } else { ImageOutput.SaveToStream(surface, tmpPNGStream, pngOutputSettings); } html = getHTMLDataURLString(surface, tmpPNGStream); } dataObject.SetText(html, TextDataFormat.Html); } } finally { // we need to use the SetDataOject before the streams are closed otherwise the buffer will be gone! // Check if Bitmap is wanted if (config.ClipboardFormats.Contains(ClipboardFormat.BITMAP)) { dataObject.SetImage(imageToSave); // Place the DataObject to the clipboard SetDataObject(dataObject, true); } else { // Place the DataObject to the clipboard SetDataObject(dataObject, true); } if (pngStream != null) { pngStream.Dispose(); pngStream = null; } if (dibStream != null) { dibStream.Dispose(); dibStream = null; } if (dibV5Stream != null) { dibV5Stream.Dispose(); dibV5Stream = null; } // cleanup if needed if (disposeImage && imageToSave != null) { imageToSave.Dispose(); } } }
/// <summary>Initialize the AviFile.</summary> /// <param name="path">The path to the output file.</param> /// <param name="frameRate">The frame rate for the video.</param> /// <param name="width">The width of the video.</param> /// <param name="height">The height of the video.</param> /// <param name="quality">Video quality 0 to 10000.</param> public AviWriter(string path, int frameRate, int width, int height, uint quality = 10000) { #region Validation if (path == null) { throw new ArgumentNullException(nameof(path)); } if (frameRate <= 0) { throw new ArgumentOutOfRangeException(nameof(frameRate), frameRate, "The frame rate must be at least 1 frame per second."); } if (width <= 0) { throw new ArgumentOutOfRangeException(nameof(width), width, "The width must be at least 1."); } if (height <= 0) { throw new ArgumentOutOfRangeException(nameof(height), height, "The height must be at least 1."); } #endregion //Store parameters. _width = width; _height = height; _disposed = false; //Get the stride information by creating a new bitmap and querying it using (var bmp = new Bitmap(width, height, PixelFormat.Format24bppRgb)) { var bmpData = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); _stride = (uint)bmpData.Stride; bmp.UnlockBits(bmpData); } try { //Initialize the AVI library. AVIFileInit(); //Open the output AVI file. var rv = AVIFileOpen(out _aviFile, path, AVI_OPEN_MODE_CREATEWRITE, IntPtr.Zero); if (rv != 0) { throw new Win32Exception(((AviErrors)rv).ToString()); } //Create a new stream in the avi file. var aviStreamInfo = new AVISTREAMINFOW { fccType = GetFourCc("vids"), fccHandler = GetFourCc("CVID"), //CVID// 808810089, //IV50 //'DIB '//MJPG dwScale = 1, dwRate = (uint)frameRate, dwSuggestedBufferSize = (uint)(_height * _stride), dwQuality = quality, //-1 default 0xffffffff, 0 to 10.000 rcFrame = new Native.Rect { Bottom = _height, Right = _width } }; rv = AVIFileCreateStream(_aviFile, out _aviStream, ref aviStreamInfo); if (rv != 0) { throw new Win32Exception(((AviErrors)rv).ToString()); } //Set compress options. var options = new AVICOMPRESSOPTIONS { fccType = GetFourCc("vids"), lpParms = IntPtr.Zero, lpFormat = IntPtr.Zero }; var mem = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(AVICOMPRESSOPTIONS))); Marshal.StructureToPtr(options, mem, false); var streams = new[] { _aviStream }; var infPtrs = new[] { mem }; var ok = AVISaveOptions(IntPtr.Zero, ICMF_CHOOSE_KEYFRAME | ICMF_CHOOSE_DATARATE, 1, streams, infPtrs); if (ok) { options = (AVICOMPRESSOPTIONS)Marshal.PtrToStructure(mem, typeof(AVICOMPRESSOPTIONS)); } Marshal.FreeHGlobal(mem); if (!ok) { throw new Exception("User cancelled the operation."); } rv = AVIMakeCompressedStream(out _compStream, _aviStream, ref options, 0); if (rv != 0) { throw new Win32Exception(((AviErrors)rv).ToString()); } //Configure the compressed stream. var streamFormat = new BITMAPINFOHEADER { biSize = 40, biWidth = _width, biHeight = _height, biPlanes = 1, biBitCount = 24, biSizeImage = (uint)(_stride * _height), biCompression = 0 //BI_RGB }; rv = AVIStreamSetFormat(_compStream, 0, ref streamFormat, 40); if (rv != 0) { throw new Win32Exception(((AviErrors)rv).ToString()); } } catch { //Clean up. Dispose(false); try { if (File.Exists(path)) { File.Delete(path); } } catch { } throw; } }
public static extern IntPtr AVIStreamGetFrameOpen(IntPtr pavi, ref BITMAPINFOHEADER lpbiWanted);
/// <summary> /// This method will use User32 code to capture the specified captureBounds from the screen /// </summary> /// <param name="captureBounds">Rectangle with the bounds to capture</param> /// <returns>Bitmap which is captured from the screen at the location specified by the captureBounds</returns> public static Bitmap CaptureRectangle(Rectangle captureBounds) { Bitmap returnBitmap = null; if (captureBounds.Height <= 0 || captureBounds.Width <= 0) { LOG.Warn("Nothing to capture, ignoring!"); return null; } LOG.Debug("CaptureRectangle Called!"); // .NET GDI+ Solution, according to some post this has a GDI+ leak... // See http://connect.microsoft.com/VisualStudio/feedback/details/344752/gdi-object-leak-when-calling-graphics-copyfromscreen // Bitmap capturedBitmap = new Bitmap(captureBounds.Width, captureBounds.Height); // using (Graphics graphics = Graphics.FromImage(capturedBitmap)) { // graphics.CopyFromScreen(captureBounds.Location, Point.Empty, captureBounds.Size, CopyPixelOperation.CaptureBlt); // } // capture.Image = capturedBitmap; // capture.Location = captureBounds.Location; using (SafeWindowDCHandle desktopDCHandle = SafeWindowDCHandle.fromDesktop()) { if (desktopDCHandle.IsInvalid) { // Get Exception before the error is lost Exception exceptionToThrow = CreateCaptureException("desktopDCHandle", captureBounds); // throw exception throw exceptionToThrow; } // create a device context we can copy to using (SafeCompatibleDCHandle safeCompatibleDCHandle = GDI32.CreateCompatibleDC(desktopDCHandle)) { // Check if the device context is there, if not throw an error with as much info as possible! if (safeCompatibleDCHandle.IsInvalid) { // Get Exception before the error is lost Exception exceptionToThrow = CreateCaptureException("CreateCompatibleDC", captureBounds); // throw exception throw exceptionToThrow; } // Create BITMAPINFOHEADER for CreateDIBSection BITMAPINFOHEADER bmi = new BITMAPINFOHEADER(captureBounds.Width, captureBounds.Height, 24); // Make sure the last error is set to 0 Win32.SetLastError(0); // create a bitmap we can copy it to, using GetDeviceCaps to get the width/height IntPtr bits0; // not used for our purposes. It returns a pointer to the raw bits that make up the bitmap. using (SafeDibSectionHandle safeDibSectionHandle = GDI32.CreateDIBSection(desktopDCHandle, ref bmi, BITMAPINFOHEADER.DIB_RGB_COLORS, out bits0, IntPtr.Zero, 0)) { if (safeDibSectionHandle.IsInvalid) { // Get Exception before the error is lost Exception exceptionToThrow = CreateCaptureException("CreateDIBSection", captureBounds); exceptionToThrow.Data.Add("hdcDest", safeCompatibleDCHandle.DangerousGetHandle().ToInt32()); exceptionToThrow.Data.Add("hdcSrc", desktopDCHandle.DangerousGetHandle().ToInt32()); // Throw so people can report the problem throw exceptionToThrow; } // select the bitmap object and store the old handle using (safeCompatibleDCHandle.SelectObject(safeDibSectionHandle)) { // bitblt over (make copy) GDI32.BitBlt(safeCompatibleDCHandle, 0, 0, captureBounds.Width, captureBounds.Height, desktopDCHandle, captureBounds.X, captureBounds.Y, CopyPixelOperation.SourceCopy | CopyPixelOperation.CaptureBlt); } // get a .NET image object for it // A suggestion for the "A generic error occurred in GDI+." E_FAIL/0×80004005 error is to re-try... bool success = false; ExternalException exception = null; for (int i = 0; i < 3; i++) { try { // Collect all screens inside this capture List<Screen> screensInsideCapture = new List<Screen>(); foreach (Screen screen in Screen.AllScreens) { if (screen.Bounds.IntersectsWith(captureBounds)) { screensInsideCapture.Add(screen); } } // Check all all screens are of an equal size bool offscreenContent; using (Region captureRegion = new Region(captureBounds)) { // Exclude every visible part foreach (Screen screen in screensInsideCapture) { captureRegion.Exclude(screen.Bounds); } // If the region is not empty, we have "offscreenContent" using (Graphics screenGraphics = Graphics.FromHwnd(User32.GetDesktopWindow())) { offscreenContent = !captureRegion.IsEmpty(screenGraphics); } } // Check if we need to have a transparent background, needed for offscreen content if (offscreenContent) { using (Bitmap tmpBitmap = Image.FromHbitmap(safeDibSectionHandle.DangerousGetHandle())) { // Create a new bitmap which has a transparent background returnBitmap = ImageHelper.CreateEmpty(tmpBitmap.Width, tmpBitmap.Height, PixelFormat.Format32bppArgb, Color.Transparent, tmpBitmap.HorizontalResolution, tmpBitmap.VerticalResolution); // Content will be copied here using (Graphics graphics = Graphics.FromImage(returnBitmap)) { // For all screens copy the content to the new bitmap foreach (Screen screen in Screen.AllScreens) { Rectangle screenBounds = screen.Bounds; // Make sure the bounds are offsetted to the capture bounds screenBounds.Offset(-captureBounds.X, -captureBounds.Y); graphics.DrawImage(tmpBitmap, screenBounds, screenBounds.X, screenBounds.Y, screenBounds.Width, screenBounds.Height, GraphicsUnit.Pixel); } } } } else { // All screens, which are inside the capture, are of equal size // assign image to Capture, the image will be disposed there.. returnBitmap = Image.FromHbitmap(safeDibSectionHandle.DangerousGetHandle()); } // We got through the capture without exception success = true; break; } catch (ExternalException ee) { LOG.Warn("Problem getting bitmap at try " + i + " : ", ee); exception = ee; } } if (!success) { LOG.Error("Still couldn't create Bitmap!"); if (exception != null) { throw exception; } } } } } return returnBitmap; }
/// <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(); } } }