コード例 #1
0
ファイル: CachedCapture.cs プロジェクト: zyjj/ScreenToGif
        public override void Start(int delay, int left, int top, int width, int height, double scale, ProjectInfo project)
        {
            base.Start(delay, left, top, width, height, scale, project);

            _infoHeader                = new Native.BitmapInfoHeader();
            _infoHeader.biSize         = (uint)Marshal.SizeOf(_infoHeader);
            _infoHeader.biBitCount     = 24; //Without alpha channel.
            _infoHeader.biClrUsed      = 0;
            _infoHeader.biClrImportant = 0;
            _infoHeader.biCompression  = 0;
            _infoHeader.biHeight       = -StartHeight; //Negative, so the Y-axis will be positioned correctly.
            _infoHeader.biWidth        = StartWidth;
            _infoHeader.biPlanes       = 1;

            //This was working with 32 bits: 3L * Width * Height;
            _byteLength = (StartWidth * _infoHeader.biBitCount + 31) / 32 * 4 * StartHeight;

            //Due to a strange behavior with the GetDiBits method while the cursor is IBeam, it's best to use 24 bits, to ignore the alpha values.
            //This capture mode ignores the alpha value.
            project.BitDepth = 24;

            _fileStream     = new FileStream(project.CachePath, FileMode.Create, FileAccess.Write, FileShare.None);
            _bufferedStream = new BufferedStream(_fileStream, UserSettings.All.MemoryCacheSize * 1048576); //Each 1 MB has 1_048_576 bytes.
            _compressStream = new DeflateStream(_bufferedStream, UserSettings.All.CaptureCompression, true);
        }
コード例 #2
0
        /// <summary>
        /// Changes the icon of the file to the specified icon.
        /// </summary>
        /// <param name="icon">The <see cref="Icon" /> to be applied to the file.</param>
        public unsafe void ChangeIcon(Icon icon)
        {
            Check.FileNotFound(Path);
            Check.ArgumentNull(icon, nameof(icon));

            Native.IconDir             iconDir   = new Native.IconDir();
            List <Native.IconDirEntry> iconEntry = new List <Native.IconDirEntry>();
            List <byte[]> iconData = new List <byte[]>();

            using (BinaryReader reader = new BinaryReader(new MemoryStream(icon.ToArray())))
            {
                Marshal.Copy(reader.ReadBytes(sizeof(Native.IconDir)), 0, (IntPtr)(&iconDir), sizeof(Native.IconDir));

                for (int i = 0; i < iconDir.Count; i++)
                {
                    Native.IconDirEntry entry = new Native.IconDirEntry();
                    Marshal.Copy(reader.ReadBytes(sizeof(Native.IconDirEntry)), 0, (IntPtr)(&entry), sizeof(Native.IconDirEntry));
                    iconEntry.Add(entry);
                }
                for (int i = 0; i < iconDir.Count; i++)
                {
                    iconData.Add(reader.ReadBytes((int)iconEntry[i].BytesInRes));
                }
            }

            IntPtr update = Native.BeginUpdateResource(Path, false);

            byte[] data = new byte[sizeof(Native.IconDir) + sizeof(Native.GroupIconDirEntry) * iconDir.Count];
            Marshal.Copy((IntPtr)(&iconDir), data, 0, sizeof(Native.IconDir));

            for (int i = 0, offset = sizeof(Native.IconDir); i < iconDir.Count; i++, offset += sizeof(Native.GroupIconDirEntry))
            {
                Native.BitmapInfoHeader header = new Native.BitmapInfoHeader();
                Marshal.Copy(iconData[i], 0, (IntPtr)(&header), sizeof(Native.BitmapInfoHeader));

                Native.GroupIconDirEntry groupEntry = new Native.GroupIconDirEntry
                {
                    Width      = iconEntry[i].Width,
                    Height     = iconEntry[i].Height,
                    ColorCount = iconEntry[i].ColorCount,
                    Reserved   = iconEntry[i].Reserved,
                    Planes     = header.Planes,
                    BitCount   = header.BitCount,
                    BytesInRes = iconEntry[i].BytesInRes,
                    Id         = (ushort)(i + 10)
                };

                Marshal.Copy((IntPtr)(&groupEntry), data, offset, Marshal.SizeOf(groupEntry));
            }

            Native.UpdateResource(update, (uint)ResourceType.GroupIcon, 1, 0, data, (uint)data.Length);
            for (int i = 0; i < iconDir.Count; i++)
            {
                Native.UpdateResource(update, (uint)ResourceType.Icon, (uint)(10 + i), 0, iconData[i], (uint)iconData[i].Length);
            }
            Native.EndUpdateResource(update, false);
        }
コード例 #3
0
        private void CursorCapture(FrameInfo frame)
        {
            //if (_justStarted && (CursorShapeBuffer?.Length ?? 0) == 0)
            {
                //_justStarted = false;

                //https://stackoverflow.com/a/6374151/1735672
                //Bitmap struct, is used to get the cursor shape when SharpDX fails to do so.
                var _infoHeader = new Native.BitmapInfoHeader();
                _infoHeader.biSize         = (uint)Marshal.SizeOf(_infoHeader);
                _infoHeader.biBitCount     = 32;
                _infoHeader.biClrUsed      = 0;
                _infoHeader.biClrImportant = 0;
                _infoHeader.biCompression  = 0;
                _infoHeader.biHeight       = -Height; //Negative, so the Y-axis will be positioned correctly.
                _infoHeader.biWidth        = Width;
                _infoHeader.biPlanes       = 1;

                try
                {
                    var cursorInfo = new Native.CursorInfo();
                    cursorInfo.cbSize = Marshal.SizeOf(cursorInfo);

                    if (Native.GetCursorInfo(out cursorInfo))
                    {
                        if (cursorInfo.flags == Native.CursorShowing)
                        {
                            var hicon = Native.CopyIcon(cursorInfo.hCursor);

                            if (hicon != IntPtr.Zero)
                            {
                                if (Native.GetIconInfo(hicon, out var iconInfo))
                                {
                                    frame.CursorX = cursorInfo.ptScreenPos.X - Left;
                                    frame.CursorY = cursorInfo.ptScreenPos.Y - Top;

                                    var bitmap      = new Native.Bitmap();
                                    var hndl        = GCHandle.Alloc(bitmap, GCHandleType.Pinned);
                                    var ptrToBitmap = hndl.AddrOfPinnedObject();
                                    Native.GetObject(iconInfo.hbmColor, Marshal.SizeOf <Native.Bitmap>(), ptrToBitmap);
                                    bitmap = Marshal.PtrToStructure <Native.Bitmap>(ptrToBitmap);
                                    hndl.Free();

                                    //https://microsoft.public.vc.mfc.narkive.com/H1CZeqUk/how-can-i-get-bitmapinfo-object-from-bitmap-or-hbitmap
                                    _infoHeader.biHeight   = bitmap.bmHeight;
                                    _infoHeader.biWidth    = bitmap.bmWidth;
                                    _infoHeader.biBitCount = (ushort)bitmap.bmBitsPixel;

                                    var w = (bitmap.bmWidth * bitmap.bmBitsPixel + 31) / 8;
                                    CursorShapeBuffer = new byte[w * bitmap.bmHeight];

                                    var windowDeviceContext = Native.GetWindowDC(IntPtr.Zero);
                                    var compatibleBitmap    = Native.CreateCompatibleBitmap(windowDeviceContext, Width, Height);

                                    Native.GetDIBits(windowDeviceContext, compatibleBitmap, 0, (uint)_infoHeader.biHeight, CursorShapeBuffer, ref _infoHeader, Native.DibColorMode.DibRgbColors);

                                    //if (frame.CursorX > 0 && frame.CursorY > 0)
                                    //    Native.DrawIconEx(_compatibleDeviceContext, frame.CursorX - iconInfo.xHotspot, frame.CursorY - iconInfo.yHotspot, cursorInfo.hCursor, 0, 0, 0, IntPtr.Zero, 0x0003);

                                    //Clean objects here.
                                }

                                Native.DeleteObject(iconInfo.hbmColor);
                                Native.DeleteObject(iconInfo.hbmMask);
                            }

                            Native.DestroyIcon(hicon);
                        }

                        Native.DeleteObject(cursorInfo.hCursor);
                    }
                }
                catch (Exception e)
                {
                    LogWriter.Log(e, "Impossible to get the cursor");
                }
            }
        }
コード例 #4
0
ファイル: CachedCapture.cs プロジェクト: zmf1314/ScreenToGif
        public void Other()
        {
            var hDC    = Native.GetWindowDC(IntPtr.Zero);
            var hMemDC = Native.CreateCompatibleDC(hDC);

            var bi = new Native.BitmapInfoHeader();

            bi.biSize         = (uint)Marshal.SizeOf(bi);
            bi.biBitCount     = 24; //Creating RGB bitmap. The following three members don't matter
            bi.biClrUsed      = 0;
            bi.biClrImportant = 0;
            bi.biCompression  = 0;
            bi.biHeight       = Height;
            bi.biWidth        = Width;
            bi.biPlanes       = 1;

            var cb = (int)(bi.biHeight * bi.biWidth * bi.biBitCount / 8); //8 is bits per byte.

            bi.biSizeImage = (uint)(((((bi.biWidth * bi.biBitCount) + 31) & ~31) / 8) * bi.biHeight);
            //bi.biXPelsPerMeter = XPelsPerMeter;
            //bi.biYPelsPerMeter = YPelsPerMeter;
            bi.biXPelsPerMeter = 96;
            bi.biYPelsPerMeter = 96;

            var pBits = IntPtr.Zero;
            //Allocate memory for bitmap bits
            var pBI = Native.LocalAlloc((uint)Native.LocalMemoryFlags.LPTR, new UIntPtr(bi.biSize));

            // Not sure if this needed - simply trying to keep marshaller happy
            Marshal.StructureToPtr(bi, pBI, false);
            //This will return IntPtr to actual DIB bits in pBits
            var hBmp = Native.CreateDIBSection(hDC, ref pBI, 0, out pBits, IntPtr.Zero, 0);
            //Marshall back - now we have BitmapInfoHeader correctly filled in Marshal.PtrToStructure(pBI, bi);

            var biNew = (Native.BitmapInfoHeader)Marshal.PtrToStructure(pBI, typeof(Native.BitmapInfoHeader));
            //Usual stuff
            var hOldBitmap = Native.SelectObject(hMemDC, hBmp);
            //Grab bitmap
            var nRet = Native.BitBlt(hMemDC, 0, 0, bi.biWidth, bi.biHeight, hDC, Left, Top, Native.CopyPixelOperation.SourceCopy | Native.CopyPixelOperation.CaptureBlt);

            // Allocate memory for a copy of bitmap bits
            var RealBits = new byte[cb];

            // And grab bits from DIBSestion data
            Marshal.Copy(pBits, RealBits, 0, cb);

            //This simply creates valid bitmap file header, so it can be saved to disk
            var bfh = new Native.BitmapFileHeader();

            bfh.bfSize    = (uint)cb + 0x36; // Size of header + size of Native.BitmapInfoHeader size of bitmap bits
            bfh.bfType    = 0x4d42;          //BM
            bfh.bfOffBits = 0x36;            //
            var HdrSize = 14;
            var header  = new byte[HdrSize];

            BitConverter.GetBytes(bfh.bfType).CopyTo(header, 0);
            BitConverter.GetBytes(bfh.bfSize).CopyTo(header, 2);
            BitConverter.GetBytes(bfh.bfOffBits).CopyTo(header, 10);
            //Allocate enough memory for complete bitmap file
            var data = new byte[cb + bfh.bfOffBits];

            //BITMAPFILEHEADER
            header.CopyTo(data, 0);

            //BitmapInfoHeader
            header = new byte[Marshal.SizeOf(bi)];
            var pHeader = Native.LocalAlloc((uint)Native.LocalMemoryFlags.LPTR, new UIntPtr((uint)Marshal.SizeOf(bi)));

            Marshal.StructureToPtr(biNew, pHeader, false);
            Marshal.Copy(pHeader, header, 0, Marshal.SizeOf(bi));
            Native.LocalFree(pHeader);
            header.CopyTo(data, HdrSize);
            //Bitmap bits
            RealBits.CopyTo(data, (int)bfh.bfOffBits);

            //Native.SelectObject(_compatibleDeviceContext, _oldBitmap);
            //Native.DeleteObject(_compatibleBitmap);
            //Native.DeleteDC(_compatibleDeviceContext);
            //Native.ReleaseDC(_desktopWindow, _windowDeviceContext);

            Native.SelectObject(hMemDC, hOldBitmap);
            Native.DeleteObject(hBmp);
            Native.DeleteDC(hMemDC);
            Native.ReleaseDC(IntPtr.Zero, hDC);
        }