Beispiel #1
0
        void GetScreenshot(string rpMapName, int rpWidth, int rpHeight, int rpBitCount)
        {
            var rTimestamp = long.Parse(rpMapName.Substring(rpMapName.LastIndexOf('/') + 1));
            var rHeight    = Math.Abs(rpHeight);

            using (var rMap = MemoryMappedFile.CreateOrOpen(rpMapName, rpWidth * rHeight * 3, MemoryMappedFileAccess.ReadWrite))
            {
                var rInfo = new NativeStructs.BITMAPINFO();
                rInfo.bmiHeader.biSize     = Marshal.SizeOf(typeof(NativeStructs.BITMAPINFOHEADER));
                rInfo.bmiHeader.biWidth    = rpWidth;
                rInfo.bmiHeader.biHeight   = rpHeight;
                rInfo.bmiHeader.biBitCount = (ushort)rpBitCount;
                rInfo.bmiHeader.biPlanes   = 1;

                IntPtr rBits;
                var    rHBitmap = NativeMethods.Gdi32.CreateDIBSection(IntPtr.Zero, ref rInfo, 0, out rBits, rMap.SafeMemoryMappedFileHandle.DangerousGetHandle(), 0);
                if (rHBitmap == IntPtr.Zero)
                {
                    throw new InvalidOperationException();
                }

                var rImage = Imaging.CreateBitmapSourceFromHBitmap(rHBitmap, IntPtr.Zero, new Int32Rect(0, 0, rpWidth, rHeight), BitmapSizeOptions.FromEmptyOptions());
                rImage.Freeze();
                r_TaskScreenshotTasks[rTimestamp].SetResult(rImage);

                NativeMethods.Gdi32.DeleteObject(rHBitmap);
            }

            BrowserService.Instance.Communicator.Write(CommunicatorMessages.FinishScreenshotTransmission);
        }
Beispiel #2
0
 public static extern IntPtr CreateDIBSection(
     IntPtr hdc,
     ref NativeStructs.BITMAPINFO pbmi,
     uint iUsage,
     out IntPtr ppvBits,
     IntPtr hSection,
     uint dwOffset);
Beispiel #3
0
        ScreenshotData TakeScreenshotCore(NativeInterfaces.IViewObject rpViewObject)
        {
            const int BitCount = 24;

            var rEmbedElement = rpViewObject as HTMLEmbed;
            var rWidth        = rEmbedElement.clientWidth;
            var rHeight       = rEmbedElement.clientHeight;

            var rScreenDC = NativeMethods.User32.GetDC(IntPtr.Zero);
            var rHDC      = NativeMethods.Gdi32.CreateCompatibleDC(rScreenDC);

            var rInfo = new NativeStructs.BITMAPINFO();

            rInfo.bmiHeader.biSize     = Marshal.SizeOf(typeof(NativeStructs.BITMAPINFOHEADER));
            rInfo.bmiHeader.biWidth    = rWidth;
            rInfo.bmiHeader.biHeight   = rHeight;
            rInfo.bmiHeader.biBitCount = BitCount;
            rInfo.bmiHeader.biPlanes   = 1;

            IntPtr rBits;
            var    rHBitmap   = NativeMethods.Gdi32.CreateDIBSection(rHDC, ref rInfo, 0, out rBits, IntPtr.Zero, 0);
            var    rOldObject = NativeMethods.Gdi32.SelectObject(rHDC, rHBitmap);

            var rTargetDevice = new NativeStructs.DVTARGETDEVICE()
            {
                tdSize = 0
            };
            var rRect      = new NativeStructs.RECT(0, 0, rWidth, rHeight);
            var rEmptyRect = default(NativeStructs.RECT);

            rpViewObject.Draw(1, 0, IntPtr.Zero, ref rTargetDevice, IntPtr.Zero, rHDC, ref rRect, ref rEmptyRect, IntPtr.Zero, IntPtr.Zero);

            var rResult = new ScreenshotData(rWidth, rHeight, BitCount);

            var rPixels = new byte[rWidth * rHeight * 3];

            Marshal.Copy(rBits, rPixels, 0, rPixels.Length);
            rResult.BitmapData = rPixels;

            NativeMethods.Gdi32.SelectObject(rHDC, rOldObject);
            NativeMethods.Gdi32.DeleteObject(rHBitmap);
            NativeMethods.Gdi32.DeleteDC(rHDC);
            NativeMethods.User32.ReleaseDC(IntPtr.Zero, rScreenDC);

            return(rResult);
        }
Beispiel #4
0
        /// <summary>
        /// Allocates a bitmap of the given height and width. Pixel data may be read/written directly,
        /// and it may be drawn to the screen using PdnGraphics.DrawBitmap().
        /// </summary>
        /// <param name="width">The width of the bitmap to allocate.</param>
        /// <param name="height">The height of the bitmap to allocate.</param>
        /// <param name="handle">Receives a handle to the bitmap.</param>
        /// <returns>A pointer to the bitmap's pixel data.</returns>
        /// <remarks>
        /// The following invariants may be useful for implementors:
        /// * The bitmap is always 32-bits per pixel, BGRA.
        /// * Stride for the bitmap is always width * 4.
        /// * The upper-left pixel of the bitmap (0,0) is located at the first memory location pointed to by the returned pointer.
        /// * The bitmap is top-down ("memory correct" ordering).
        /// * The 'handle' may be any type of data you want, but must be unique for the lifetime of the bitmap, and must not be IntPtr.Zero.
        /// * The handle's value must be understanded by PdnGraphics.DrawBitmap().
        /// * The bitmap is always modified by directly reading and writing to the memory pointed to by the return value.
        /// * PdnGraphics.DrawBitmap() must always render from this memory location (i.e. it must treat the memory as 'volatile')
        /// </remarks>
        public static IntPtr AllocateBitmap(int width, int height, out IntPtr handle)
        {
            var bmi = new NativeStructs.BITMAPINFO
            {
                bmiHeader =
                {
                    biSize          = (uint)sizeof(NativeStructs.BITMAPINFOHEADER),
                    biWidth         = width,
                    biHeight        =                                      -height,
                    biPlanes        =                                            1,
                    biBitCount      =                                           32,
                    biCompression   = NativeConstants.BI_RGB,
                    biSizeImage     =                                            0,
                    biXPelsPerMeter =                                           96,
                    biYPelsPerMeter =                                           96,
                    biClrUsed       =                                            0,
                    biClrImportant  = 0
                }
            };

            IntPtr pvBits;
            IntPtr hBitmap = SafeNativeMethods.CreateDIBSection(
                IntPtr.Zero,
                ref bmi,
                NativeConstants.DIB_RGB_COLORS,
                out pvBits,
                IntPtr.Zero,
                0);

            if (hBitmap == IntPtr.Zero)
            {
                throw new OutOfMemoryException("CreateDIBSection returned NULL (" + Marshal.GetLastWin32Error().ToString() + ") while attempting to allocate " + width + "x" + height + " bitmap");
            }

            handle = hBitmap;
            long bytes = (long)width * (long)height * 4;

            if (bytes > 0)
            {
                GC.AddMemoryPressure(bytes);
            }

            return(pvBits);
        }
        void GetScreenshot(string rpMapName, int rpWidth, int rpHeight, int rpBitCount)
        {
            var rTimestamp = long.Parse(rpMapName.Substring(rpMapName.LastIndexOf('/') + 1));
            var rHeight = Math.Abs(rpHeight);

            using (var rMap = MemoryMappedFile.CreateOrOpen(rpMapName, rpWidth * rHeight * 3, MemoryMappedFileAccess.ReadWrite))
            {
                var rInfo = new NativeStructs.BITMAPINFO();
                rInfo.bmiHeader.biSize = Marshal.SizeOf(typeof(NativeStructs.BITMAPINFOHEADER));
                rInfo.bmiHeader.biWidth = rpWidth;
                rInfo.bmiHeader.biHeight = rpHeight;
                rInfo.bmiHeader.biBitCount = (ushort)rpBitCount;
                rInfo.bmiHeader.biPlanes = 1;

                IntPtr rBits;
                var rHBitmap = NativeMethods.Gdi32.CreateDIBSection(IntPtr.Zero, ref rInfo, 0, out rBits, rMap.SafeMemoryMappedFileHandle.DangerousGetHandle(), 0);
                if (rHBitmap == IntPtr.Zero)
                    throw new InvalidOperationException();

                var rImage = Imaging.CreateBitmapSourceFromHBitmap(rHBitmap, IntPtr.Zero, new Int32Rect(0, 0, rpWidth, rHeight), BitmapSizeOptions.FromEmptyOptions());
                rImage.Freeze();
                r_TaskScreenshotTasks[rTimestamp].SetResult(rImage);

                NativeMethods.Gdi32.DeleteObject(rHBitmap);
            }

            BrowserService.Instance.Communicator.Write(CommunicatorMessages.FinishScreenshotTransmission);
        }
        ScreenshotData TakeScreenshotCore(NativeInterfaces.IViewObject rpViewObject)
        {
            const int BitCount = 24;

            var rEmbedElement = rpViewObject as HTMLEmbed;
            var rWidth = rEmbedElement.clientWidth;
            var rHeight = rEmbedElement.clientHeight;

            var rScreenDC = NativeMethods.User32.GetDC(IntPtr.Zero);
            var rHDC = NativeMethods.Gdi32.CreateCompatibleDC(rScreenDC);

            var rInfo = new NativeStructs.BITMAPINFO();
            rInfo.bmiHeader.biSize = Marshal.SizeOf(typeof(NativeStructs.BITMAPINFOHEADER));
            rInfo.bmiHeader.biWidth = rWidth;
            rInfo.bmiHeader.biHeight = rHeight;
            rInfo.bmiHeader.biBitCount = BitCount;
            rInfo.bmiHeader.biPlanes = 1;

            IntPtr rBits;
            var rHBitmap = NativeMethods.Gdi32.CreateDIBSection(rHDC, ref rInfo, 0, out rBits, IntPtr.Zero, 0);
            var rOldObject = NativeMethods.Gdi32.SelectObject(rHDC, rHBitmap);

            var rTargetDevice = new NativeStructs.DVTARGETDEVICE() { tdSize = 0 };
            var rRect = new NativeStructs.RECT(0, 0, rWidth, rHeight);
            var rEmptyRect = default(NativeStructs.RECT);
            rpViewObject.Draw(1, 0, IntPtr.Zero, ref rTargetDevice, IntPtr.Zero, rHDC, ref rRect, ref rEmptyRect, IntPtr.Zero, IntPtr.Zero);

            var rResult = new ScreenshotData(rWidth, rHeight, BitCount);

            var rPixels = new byte[rWidth * rHeight * 3];
            Marshal.Copy(rBits, rPixels, 0, rPixels.Length);
            rResult.BitmapData = rPixels;

            NativeMethods.Gdi32.SelectObject(rHDC, rOldObject);
            NativeMethods.Gdi32.DeleteObject(rHBitmap);
            NativeMethods.Gdi32.DeleteDC(rHDC);
            NativeMethods.User32.ReleaseDC(IntPtr.Zero, rScreenDC);

            return rResult;
        }