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); }
public static extern IntPtr CreateDIBSection( IntPtr hdc, ref NativeStructs.BITMAPINFO pbmi, uint iUsage, out IntPtr ppvBits, IntPtr hSection, uint dwOffset);
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); }
/// <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; }