From 75a841b31efc8fb786fa6668c5f7a7ccceb46e60 Mon Sep 17 00:00:00 2001 From: RKrom Date: Thu, 15 Nov 2012 14:11:00 +0000 Subject: [PATCH] Fixes for better performance in some experimental code, also fixed some formatting in the code. git-svn-id: http://svn.code.sf.net/p/greenshot/code/trunk@2287 7dccd23d-a4a3-4e1f-8c07-b4c1b4018ab4 --- Greenshot/Forms/CaptureForm.cs | 13 +++++++- Greenshot/Greenshot.csproj | 8 +++-- Greenshot/Helpers/CaptureHelper.cs | 26 +++++++++++++++- Greenshot/Helpers/ScreenCaptureHelper.cs | 38 ++++++++++++++++-------- GreenshotPlugin/Core/WindowCapture.cs | 9 +++--- GreenshotPlugin/Interfaces/Capture.cs | 2 +- 6 files changed, 72 insertions(+), 24 deletions(-) diff --git a/Greenshot/Forms/CaptureForm.cs b/Greenshot/Forms/CaptureForm.cs index e2d0e7307..b89e68251 100644 --- a/Greenshot/Forms/CaptureForm.cs +++ b/Greenshot/Forms/CaptureForm.cs @@ -183,6 +183,13 @@ namespace Greenshot.Forms { // Toggle mouse cursor capture.CursorVisible = !capture.CursorVisible; Invalidate(); + } else if (e.KeyCode == Keys.V) { + if (capture.CaptureDetails.CaptureMode != CaptureMode.Video) { + capture.CaptureDetails.CaptureMode = CaptureMode.Video; + } else { + capture.CaptureDetails.CaptureMode = captureMode; + } + Invalidate(); } else if (e.KeyCode == Keys.Z) { // Toggle zoom if (zoomForm == null) { @@ -400,7 +407,11 @@ namespace Greenshot.Forms { if (mouseDown || captureMode == CaptureMode.Window) { captureRect.Intersect(new Rectangle(Point.Empty, capture.ScreenBounds.Size)); // crop what is outside the screen Rectangle fixedRect = new Rectangle( captureRect.X, captureRect.Y, captureRect.Width, captureRect.Height ); - graphics.FillRectangle(GreenOverlayBrush, fixedRect); + if (capture.CaptureDetails.CaptureMode == CaptureMode.Video) { + graphics.FillRectangle(RedOverlayBrush, fixedRect); + } else { + graphics.FillRectangle(GreenOverlayBrush, fixedRect); + } graphics.DrawRectangle(OverlayPen, fixedRect); // rulers diff --git a/Greenshot/Greenshot.csproj b/Greenshot/Greenshot.csproj index 991c044fd..e877121ad 100644 --- a/Greenshot/Greenshot.csproj +++ b/Greenshot/Greenshot.csproj @@ -180,8 +180,10 @@ MovableShowColorForm.cs - - + + + Form + @@ -203,7 +205,7 @@ - + diff --git a/Greenshot/Helpers/CaptureHelper.cs b/Greenshot/Helpers/CaptureHelper.cs index 20de9b114..790ddf390 100644 --- a/Greenshot/Helpers/CaptureHelper.cs +++ b/Greenshot/Helpers/CaptureHelper.cs @@ -45,7 +45,7 @@ namespace Greenshot.Helpers { public class CaptureHelper { private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(CaptureHelper)); private static CoreConfiguration conf = IniConfig.GetIniSection(); - //private static ScreenCaptureHelper screenCapture = null; + private static ScreenCaptureHelper screenCapture = null; private List windows = new List(); private WindowDetails selectedCaptureWindow = null; private Rectangle captureRect = Rectangle.Empty; @@ -160,6 +160,12 @@ namespace Greenshot.Helpers { /// Make Capture with specified destinations /// private void MakeCapture() { + // Experimental code + if (screenCapture != null) { + screenCapture.Stop(); + screenCapture = null; + return; + } // This fixes a problem when a balloon is still visible and a capture needs to be taken // forcefully removes the balloon! if (!conf.HideTrayicon) { @@ -892,6 +898,24 @@ namespace Greenshot.Helpers { // windowDetailsThread.Join(); //} + // Experimental code for Video capture + if (capture.CaptureDetails.CaptureMode == CaptureMode.Video) { + if (captureForm.UsedCaptureMode == CaptureMode.Window) { + screenCapture = new ScreenCaptureHelper(selectedCaptureWindow); + } else if (captureForm.UsedCaptureMode == CaptureMode.Region) { + screenCapture = new ScreenCaptureHelper(captureRect); + } + if (screenCapture != null) { + screenCapture.RecordMouse = capture.CursorVisible; + if (screenCapture.Start(25)) { + return; + } + // User clicked cancel or a problem occured + screenCapture.Stop(); + screenCapture = null; + return; + } + } // Take the captureRect, this already is specified as bitmap coordinates capture.Crop(captureRect); diff --git a/Greenshot/Helpers/ScreenCaptureHelper.cs b/Greenshot/Helpers/ScreenCaptureHelper.cs index 4242af280..96c552424 100644 --- a/Greenshot/Helpers/ScreenCaptureHelper.cs +++ b/Greenshot/Helpers/ScreenCaptureHelper.cs @@ -44,7 +44,6 @@ namespace Greenshot.Helpers { public class ScreenCaptureHelper { private static log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(ScreenCaptureHelper)); private static CoreConfiguration conf = IniConfig.GetIniSection(); - private const int MAX_FRAMES = 500; private const int ALIGNMENT = 8; private IntPtr hWndDesktop = IntPtr.Zero; private IntPtr hDCDesktop = IntPtr.Zero; @@ -63,11 +62,19 @@ namespace Greenshot.Helpers { private Bitmap GDIBitmap; private string filename = null; private Stopwatch stopwatch = new Stopwatch(); + private bool disabledDWM = false; - public ScreenCaptureHelper(Rectangle recordingRectangle) { + private ScreenCaptureHelper() { + if (DWM.isDWMEnabled()) { + // with DWM Composition disabled the capture goes ~2x faster + DWM.DisableComposition(); + disabledDWM = true; + } + } + public ScreenCaptureHelper(Rectangle recordingRectangle) : this() { this.recordingRectangle = recordingRectangle; } - public ScreenCaptureHelper(WindowDetails recordingWindow) { + public ScreenCaptureHelper(WindowDetails recordingWindow) : this() { this.recordingWindow = recordingWindow; } @@ -111,14 +118,14 @@ namespace Greenshot.Helpers { LOG.InfoFormat("Starting recording rectangle {0}", recordingRectangle); recordingSize = recordingRectangle.Size; } - if (recordingSize.Width % ALIGNMENT > 0) { - LOG.InfoFormat("Correcting width to be factor alignment, {0} => {1}", recordingSize.Width, recordingSize.Width + (ALIGNMENT - (recordingSize.Width % ALIGNMENT))); - recordingSize = new Size(recordingSize.Width + (ALIGNMENT - (recordingSize.Width % ALIGNMENT)), recordingSize.Height); - } - if (recordingSize.Height % ALIGNMENT > 0) { - LOG.InfoFormat("Correcting Height to be factor alignment, {0} => {1}", recordingSize.Height, recordingSize.Height + (ALIGNMENT - (recordingSize.Height % ALIGNMENT))); - recordingSize = new Size(recordingSize.Width, recordingSize.Height + (ALIGNMENT - (recordingSize.Height % ALIGNMENT))); - } + //if (recordingSize.Width % ALIGNMENT > 0) { + // LOG.InfoFormat("Correcting width to be factor alignment, {0} => {1}", recordingSize.Width, recordingSize.Width + (ALIGNMENT - (recordingSize.Width % ALIGNMENT))); + // recordingSize = new Size(recordingSize.Width + (ALIGNMENT - (recordingSize.Width % ALIGNMENT)), recordingSize.Height); + //} + //if (recordingSize.Height % ALIGNMENT > 0) { + // LOG.InfoFormat("Correcting Height to be factor alignment, {0} => {1}", recordingSize.Height, recordingSize.Height + (ALIGNMENT - (recordingSize.Height % ALIGNMENT))); + // recordingSize = new Size(recordingSize.Width, recordingSize.Height + (ALIGNMENT - (recordingSize.Height % ALIGNMENT))); + //} this.framesPerSecond = framesPerSecond; // "P/Invoke" Solution for capturing the screen hWndDesktop = User32.GetDesktopWindow(); @@ -162,7 +169,7 @@ namespace Greenshot.Helpers { throw exceptionToThrow; } // Create a GDI Bitmap so we can use GDI and GDI+ operations on the same memory - GDIBitmap = new Bitmap(recordingSize.Width, recordingSize.Height, 32, PixelFormat.Format32bppArgb, bits0); + GDIBitmap = new Bitmap(recordingSize.Width, recordingSize.Height, 32, PixelFormat.Format32bppPArgb, bits0); // select the bitmap object and store the old handle hOldObject = GDI32.SelectObject(hDCDest, hDIBSection); stop = false; @@ -202,7 +209,8 @@ namespace Greenshot.Helpers { captureLocation = new Point(recordingRectangle.X, recordingRectangle.Y); } // "Capture" - GDI32.BitBlt(hDCDest, 0, 0, recordingSize.Width, recordingSize.Height, hDCDesktop, captureLocation.X, captureLocation.Y, CopyPixelOperation.SourceCopy | CopyPixelOperation.CaptureBlt); + GDI32.BitBlt(hDCDest, 0, 0, recordingSize.Width, recordingSize.Height, hDCDesktop, captureLocation.X, captureLocation.Y, CopyPixelOperation.SourceCopy); + //GDI32.BitBlt(hDCDest, 0, 0, recordingSize.Width, recordingSize.Height, hDCDesktop, captureLocation.X, captureLocation.Y, CopyPixelOperation.SourceCopy | CopyPixelOperation.CaptureBlt); // Mouse if (RecordMouse) { @@ -282,6 +290,10 @@ namespace Greenshot.Helpers { aviWriter = null; MessageBox.Show("Recording written to " + filename); } + + if (disabledDWM) { + DWM.EnableComposition(); + } } } } diff --git a/GreenshotPlugin/Core/WindowCapture.cs b/GreenshotPlugin/Core/WindowCapture.cs index 4eb63ce31..51b6d0e11 100644 --- a/GreenshotPlugin/Core/WindowCapture.cs +++ b/GreenshotPlugin/Core/WindowCapture.cs @@ -609,7 +609,6 @@ namespace GreenshotPlugin.Core { } else { 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); @@ -623,7 +622,7 @@ namespace GreenshotPlugin.Core { IntPtr hWndDesktop = User32.GetDesktopWindow(); // get te hDC of the target window IntPtr hDCDesktop = User32.GetWindowDC(hWndDesktop); - + // Make sure the last error is set to 0 Win32.SetLastError(0); @@ -667,7 +666,7 @@ namespace GreenshotPlugin.Core { // bitblt over (make copy) GDI32.BitBlt(hDCDest, 0, 0, captureBounds.Width, captureBounds.Height, hDCDesktop, captureBounds.X, captureBounds.Y, CopyPixelOperation.SourceCopy | CopyPixelOperation.CaptureBlt); - + // restore selection (old handle) GDI32.SelectObject(hDCDest, hOldObject); // clean up @@ -697,7 +696,7 @@ namespace GreenshotPlugin.Core { GDI32.DeleteObject(hDIBSection); } - return returnBitmap; - } + return returnBitmap; + } } } diff --git a/GreenshotPlugin/Interfaces/Capture.cs b/GreenshotPlugin/Interfaces/Capture.cs index 50f1a65a2..53b682df3 100644 --- a/GreenshotPlugin/Interfaces/Capture.cs +++ b/GreenshotPlugin/Interfaces/Capture.cs @@ -26,7 +26,7 @@ namespace Greenshot.Plugin { /// /// The capture mode for Greenshot /// - public enum CaptureMode { None, Region, FullScreen, ActiveWindow, Window, LastRegion, Clipboard, File, IE, Import }; + public enum CaptureMode { None, Region, FullScreen, ActiveWindow, Window, LastRegion, Clipboard, File, IE, Import, Video }; public enum ScreenCaptureMode { Auto, FullScreen, Fixed}; ///