diff --git a/Greenshot/Drawing/Surface.cs b/Greenshot/Drawing/Surface.cs
index 67f783c0e..c2a1711f2 100644
--- a/Greenshot/Drawing/Surface.cs
+++ b/Greenshot/Drawing/Surface.cs
@@ -535,7 +535,7 @@ namespace Greenshot.Drawing {
///
/// true if cropped
public bool AutoCrop() {
- Rectangle cropRectangle = ImageHelper.FindAutoCropRectangle(Image);
+ Rectangle cropRectangle = ImageHelper.FindAutoCropRectangle(Image, conf.AutoCropDifference);
if (isCropPossible(ref cropRectangle)) {
DrawingMode = DrawingModes.Crop;
cropContainer = new CropContainer(this);
@@ -637,6 +637,18 @@ namespace Greenshot.Drawing {
newImage = ImageHelper.RotateFlip((Bitmap)Image, rotateFlipType);
break;
}
+ // The following was added to correct any unneeded pixels, had the bad effect that sometimes everything was cropped... :(
+ //Rectangle autoCropRectangle = ImageHelper.FindAutoCropRectangle(newImage, 0);
+ //if (!Size.Empty.Equals(autoCropRectangle.Size) && !autoCropRectangle.Size.Equals(newImage.Size)) {
+ // LOG.InfoFormat("Crop to {0}", autoCropRectangle);
+ // using (Bitmap tmpImage = newImage) {
+ // newImage = ImageHelper.CloneArea(newImage, autoCropRectangle, PixelFormat.DontCare);
+ // }
+ // // Fix offset
+ // offset = new Point(offset.X - autoCropRectangle.X, offset.Y - autoCropRectangle.Y);
+ //} else {
+ // LOG.DebugFormat("No cropping needed!");
+ //}
if (newImage != null) {
// Make sure the elements move according to the offset the effect made the bitmap move
@@ -655,6 +667,11 @@ namespace Greenshot.Drawing {
}
}
+ ///
+ /// check if a crop is possible
+ ///
+ ///
+ /// true if this is possible
public bool isCropPossible(ref Rectangle cropRectangle) {
cropRectangle = Helpers.GuiRectangle.GetGuiRectangle(cropRectangle.Left, cropRectangle.Top, cropRectangle.Width, cropRectangle.Height);
if (cropRectangle.Left < 0) cropRectangle = new Rectangle(0, cropRectangle.Top, cropRectangle.Width + cropRectangle.Left, cropRectangle.Height);
@@ -684,12 +701,16 @@ namespace Greenshot.Drawing {
}
}
+ ///
+ /// Crop the surface
+ ///
+ ///
+ ///
public bool ApplyCrop(Rectangle cropRectangle) {
if (isCropPossible(ref cropRectangle)) {
Rectangle imageRectangle = new Rectangle(Point.Empty, Image.Size);
// we should not forget to Dispose the images!!
Bitmap tmpImage = ImageHelper.CloneArea(Image, cropRectangle, PixelFormat.DontCare);
- tmpImage.SetResolution(Image.HorizontalResolution, Image.VerticalResolution);
Point offset = new Point(-cropRectangle.Left, -cropRectangle.Top);
// Make undoable
diff --git a/Greenshot/Forms/MainForm.Designer.cs b/Greenshot/Forms/MainForm.Designer.cs
index f30c7ddd6..6e567c76b 100644
--- a/Greenshot/Forms/MainForm.Designer.cs
+++ b/Greenshot/Forms/MainForm.Designer.cs
@@ -132,7 +132,6 @@ namespace Greenshot {
this.contextmenu_capturefullscreen.ShortcutKeyDisplayString = "Ctrl + Print";
this.contextmenu_capturefullscreen.Size = new System.Drawing.Size(242, 22);
this.contextmenu_capturefullscreen.Text = "Capture full screen";
- this.contextmenu_capturefullscreen.Click += new System.EventHandler(this.CaptureFullScreenToolStripMenuItemClick);
//
// toolStripSeparator4
//
diff --git a/Greenshot/Forms/MainForm.cs b/Greenshot/Forms/MainForm.cs
index 13131d2d0..88d5e4c05 100644
--- a/Greenshot/Forms/MainForm.cs
+++ b/Greenshot/Forms/MainForm.cs
@@ -562,6 +562,7 @@ namespace Greenshot {
void CaptureRegion() {
CaptureHelper.CaptureRegion(true);
}
+
void CaptureClipboard() {
CaptureHelper.CaptureClipboard();
}
@@ -575,15 +576,19 @@ namespace Greenshot {
}
}
}
+
void CaptureFullScreen() {
- CaptureHelper.CaptureFullscreen(true);
+ CaptureHelper.CaptureFullscreen(true, conf.ScreenCaptureMode);
}
+
void CaptureLastRegion() {
CaptureHelper.CaptureLastRegion(true);
}
+
void CaptureIE() {
CaptureHelper.CaptureIE(true);
}
+
void CaptureWindow() {
if (conf.CaptureWindowsInteractive) {
CaptureHelper.CaptureWindowInteractive(true);
@@ -609,6 +614,17 @@ namespace Greenshot {
} catch (Exception ex) {
LOG.WarnFormat("Problem accessing IE information: {0}", ex.Message);
}
+
+ // Multi-Screen captures
+ this.contextmenu_capturefullscreen.Click -= new System.EventHandler(this.CaptureFullScreenToolStripMenuItemClick);
+ this.contextmenu_capturefullscreen.DropDownOpening -= new System.EventHandler(MultiScreenDropDownOpening);
+ this.contextmenu_capturefullscreen.DropDownClosed -= new System.EventHandler(MultiScreenDropDownClosing);
+ if (Screen.AllScreens.Length > 1) {
+ this.contextmenu_capturefullscreen.DropDownOpening += new System.EventHandler(MultiScreenDropDownOpening);
+ this.contextmenu_capturefullscreen.DropDownClosed += new System.EventHandler(MultiScreenDropDownClosing);
+ } else {
+ this.contextmenu_capturefullscreen.Click += new System.EventHandler(this.CaptureFullScreenToolStripMenuItemClick);
+ }
}
void ContextMenuClosing(object sender, EventArgs e) {
@@ -653,6 +669,56 @@ namespace Greenshot {
}
}
+ ///
+ /// MultiScreenDropDownOpening is called when mouse hovers over the Capture-Screen context menu
+ ///
+ ///
+ ///
+ private void MultiScreenDropDownOpening(object sender, EventArgs e) {
+ ToolStripMenuItem captureScreenMenuItem = (ToolStripMenuItem)sender;
+ captureScreenMenuItem.DropDownItems.Clear();
+ if (Screen.AllScreens.Length > 1) {
+ ToolStripMenuItem captureScreenItem;
+ string allDeviceName = "";
+ foreach (Screen screen in Screen.AllScreens) {
+ string deviceName = screen.DeviceName;
+ if (allDeviceName.Length > 0) {
+ allDeviceName += " + ";
+ }
+ allDeviceName += deviceName.Substring(deviceName.Length - 1);
+ }
+ captureScreenItem = new ToolStripMenuItem(allDeviceName);
+ captureScreenItem.Click += delegate {
+ BeginInvoke((MethodInvoker)delegate {
+ CaptureHelper.CaptureFullscreen(false, ScreenCaptureMode.FullScreen);
+ });
+ };
+ captureScreenMenuItem.DropDownItems.Add(captureScreenItem);
+ foreach (Screen screen in Screen.AllScreens) {
+ Screen screenToCapture = screen;
+ string deviceName = screenToCapture.DeviceName;
+ deviceName = deviceName.Substring(deviceName.Length - 1);
+ captureScreenItem = new ToolStripMenuItem(deviceName);
+ captureScreenItem.Click += delegate {
+ BeginInvoke((MethodInvoker)delegate {
+ CaptureHelper.CaptureRegion(false, screenToCapture.Bounds);
+ });
+ };
+ captureScreenMenuItem.DropDownItems.Add(captureScreenItem);
+ }
+ }
+ }
+
+ ///
+ /// MultiScreenDropDownOpening is called when mouse leaves the context menu
+ ///
+ ///
+ ///
+ private void MultiScreenDropDownClosing(object sender, EventArgs e) {
+ ToolStripMenuItem captureScreenMenuItem = (ToolStripMenuItem)sender;
+ captureScreenMenuItem.DropDownItems.Clear();
+ }
+
///
/// Build a selectable list of windows when we enter the menu item
///
@@ -783,7 +849,7 @@ namespace Greenshot {
void CaptureFullScreenToolStripMenuItemClick(object sender, EventArgs e) {
BeginInvoke((MethodInvoker)delegate {
- CaptureHelper.CaptureFullscreen(false);
+ CaptureHelper.CaptureFullscreen(false, conf.ScreenCaptureMode);
});
}
diff --git a/Greenshot/Helpers/CaptureHelper.cs b/Greenshot/Helpers/CaptureHelper.cs
index 68743cd71..860f6a1e7 100644
--- a/Greenshot/Helpers/CaptureHelper.cs
+++ b/Greenshot/Helpers/CaptureHelper.cs
@@ -52,6 +52,7 @@ namespace Greenshot.Helpers {
private bool captureMouseCursor = false;
private ICapture capture = null;
private CaptureMode captureMode;
+ private ScreenCaptureMode screenCaptureMode = ScreenCaptureMode.Auto;
private Thread windowDetailsThread = null;
public static void CaptureClipboard() {
@@ -64,7 +65,10 @@ namespace Greenshot.Helpers {
CaptureHelper captureHelper = new CaptureHelper(CaptureMode.Region, captureMouse, destination);
captureHelper.MakeCapture();
}
- public static void CaptureFullscreen(bool captureMouse) {
+ public static void CaptureRegion(bool captureMouse, Rectangle region) {
+ new CaptureHelper(CaptureMode.Region, captureMouse).MakeCapture(region);
+ }
+ public static void CaptureFullscreen(bool captureMouse, ScreenCaptureMode screenCaptureMode) {
new CaptureHelper(CaptureMode.FullScreen, captureMouse).MakeCapture();
}
public static void CaptureLastRegion(bool captureMouse) {
@@ -103,6 +107,11 @@ namespace Greenshot.Helpers {
this.captureMouseCursor = captureMouseCursor;
}
+ public CaptureHelper(CaptureMode captureMode, bool captureMouseCursor, ScreenCaptureMode screenCaptureMode) : this(captureMode) {
+ this.captureMouseCursor = captureMouseCursor;
+ this.screenCaptureMode = screenCaptureMode;
+ }
+
public CaptureHelper(CaptureMode captureMode, bool captureMouseCursor, IDestination destination) : this(captureMode, captureMouseCursor) {
capture.CaptureDetails.AddDestination(destination);
}
@@ -131,6 +140,16 @@ namespace Greenshot.Helpers {
MakeCapture();
}
+ ///
+ /// Make Capture for region
+ ///
+ /// filename
+ private void MakeCapture(Rectangle region) {
+ captureRect = region;
+ MakeCapture();
+ }
+
+
///
/// Make Capture with specified destinations
///
@@ -210,7 +229,32 @@ namespace Greenshot.Helpers {
}
break;
case CaptureMode.FullScreen:
- capture = WindowCapture.CaptureScreen(capture);
+ // Check how we need to capture the screen
+ bool captureTaken = false;
+ switch (screenCaptureMode) {
+ case ScreenCaptureMode.Auto:
+ Point mouseLocation = WindowCapture.GetCursorLocation();
+ foreach (Screen screen in Screen.AllScreens) {
+ if (screen.Bounds.Contains(mouseLocation)) {
+ capture = WindowCapture.CaptureRectangle(capture, screen.Bounds);
+ captureTaken = true;
+ break;
+ }
+ }
+ break;
+ case ScreenCaptureMode.Fixed:
+ if (conf.ScreenToCapture > 0 && conf.ScreenToCapture <= Screen.AllScreens.Length) {
+ capture = WindowCapture.CaptureRectangle(capture, Screen.AllScreens[conf.ScreenToCapture].Bounds);
+ captureTaken = true;
+ }
+ break;
+ case ScreenCaptureMode.FullScreen:
+ // Do nothing, we take the fullscreen capture automatically
+ break;
+ }
+ if (!captureTaken) {
+ capture = WindowCapture.CaptureScreen(capture);
+ }
HandleCapture();
break;
case CaptureMode.Clipboard:
@@ -279,19 +323,25 @@ namespace Greenshot.Helpers {
break;
case CaptureMode.LastRegion:
if (!RuntimeConfig.LastCapturedRegion.IsEmpty) {
- capture = WindowCapture.CaptureScreen(capture);
+ capture = WindowCapture.CaptureRectangle(capture, RuntimeConfig.LastCapturedRegion);
if (windowDetailsThread != null) {
windowDetailsThread.Join();
}
- capture.Crop(RuntimeConfig.LastCapturedRegion);
capture.CaptureDetails.AddMetaData("source", "screen");
HandleCapture();
}
break;
case CaptureMode.Region:
- capture = WindowCapture.CaptureScreen(capture);
- capture.CaptureDetails.AddMetaData("source", "screen");
- CaptureWithFeedback();
+ // Check if a region is pre-supplied!
+ if (Rectangle.Empty.Equals(captureRect)) {
+ capture = WindowCapture.CaptureScreen(capture);
+ capture.CaptureDetails.AddMetaData("source", "screen");
+ CaptureWithFeedback();
+ } else {
+ capture = WindowCapture.CaptureRectangle(capture, captureRect);
+ capture.CaptureDetails.AddMetaData("source", "screen");
+ HandleCapture();
+ }
break;
case CaptureMode.Video:
capture = WindowCapture.CaptureScreen(capture);
diff --git a/GreenshotPlugin/Core/CoreConfiguration.cs b/GreenshotPlugin/Core/CoreConfiguration.cs
index 83a624ae8..203f8529d 100644
--- a/GreenshotPlugin/Core/CoreConfiguration.cs
+++ b/GreenshotPlugin/Core/CoreConfiguration.cs
@@ -71,7 +71,11 @@ namespace GreenshotPlugin.Core {
public bool CaptureWindowsInteractive;
[IniProperty("CaptureDelay", Description="Capture delay in millseconds.", DefaultValue="100")]
public int CaptureDelay;
- [IniProperty("WindowCaptureMode", Description="The capture mode used to capture a Window.", DefaultValue="Auto")]
+ [IniProperty("ScreenCaptureMode", Description = "The capture mode used to capture a screen. (Auto, FullScreen, Fixed)", DefaultValue = "Auto")]
+ public ScreenCaptureMode ScreenCaptureMode;
+ [IniProperty("ScreenToCapture", Description = "The screen number to capture when using ScreenCaptureMode Fixed.", DefaultValue = "1")]
+ public int ScreenToCapture;
+ [IniProperty("WindowCaptureMode", Description = "The capture mode used to capture a Window (Screen, GDI, Aero, AeroTransparent, Auto).", DefaultValue = "Auto")]
public WindowCaptureMode WindowCaptureMode;
[IniProperty("WindowCaptureAllChildLocations", Description="Enable/disable capture all children, very slow but will make it possible to use this information in the editor.", DefaultValue="False")]
public bool WindowCaptureAllChildLocations;
diff --git a/GreenshotPlugin/Core/ImageHelper.cs b/GreenshotPlugin/Core/ImageHelper.cs
index c717ee2f4..f52c5e297 100644
--- a/GreenshotPlugin/Core/ImageHelper.cs
+++ b/GreenshotPlugin/Core/ImageHelper.cs
@@ -98,20 +98,20 @@ namespace GreenshotPlugin.Core {
///
///
///
- private static Rectangle FindAutoCropRectangle(BitmapBuffer buffer, Point colorPoint) {
+ private static Rectangle FindAutoCropRectangle(BitmapBuffer buffer, Point colorPoint, int cropDifference) {
Rectangle cropRectangle = Rectangle.Empty;
Color referenceColor = buffer.GetColorAtWithoutAlpha(colorPoint.X,colorPoint.Y);
Point min = new Point(int.MaxValue, int.MaxValue);
Point max = new Point(int.MinValue, int.MinValue);
-
- if (conf.AutoCropDifference > 0) {
+
+ if (cropDifference > 0) {
for(int y = 0; y < buffer.Height; y++) {
for(int x = 0; x < buffer.Width; x++) {
Color currentColor = buffer.GetColorAt(x, y);
int diffR = Math.Abs(currentColor.R - referenceColor.R);
int diffG = Math.Abs(currentColor.G - referenceColor.G);
int diffB = Math.Abs(currentColor.B - referenceColor.B);
- if (((diffR+diffG+diffB)/3) > conf.AutoCropDifference) {
+ if (((diffR + diffG + diffB) / 3) > cropDifference) {
if (x < min.X) min.X = x;
if (y < min.Y) min.Y = y;
if (x > max.X) max.X = x;
@@ -140,12 +140,13 @@ namespace GreenshotPlugin.Core {
}
return cropRectangle;
}
+
///
/// Get a rectangle for the image which crops the image of all colors equal to that on 0,0
///
///
/// Rectangle
- public static Rectangle FindAutoCropRectangle(Image image) {
+ public static Rectangle FindAutoCropRectangle(Image image, int cropDifference) {
Rectangle cropRectangle = Rectangle.Empty;
using (BitmapBuffer buffer = new BitmapBuffer((Bitmap)image, false)) {
buffer.Lock();
@@ -162,7 +163,7 @@ namespace GreenshotPlugin.Core {
// find biggest area
foreach(Point checkPoint in checkPoints) {
- currentRectangle = FindAutoCropRectangle(buffer, checkPoint);
+ currentRectangle = FindAutoCropRectangle(buffer, checkPoint, cropDifference);
if (currentRectangle.Width * currentRectangle.Height > cropRectangle.Width * cropRectangle.Height) {
cropRectangle = currentRectangle;
}
diff --git a/GreenshotPlugin/Interfaces/Capture.cs b/GreenshotPlugin/Interfaces/Capture.cs
index ee77f0dec..384b78167 100644
--- a/GreenshotPlugin/Interfaces/Capture.cs
+++ b/GreenshotPlugin/Interfaces/Capture.cs
@@ -27,6 +27,7 @@ namespace Greenshot.Plugin {
/// The capture mode for Greenshot
///
public enum CaptureMode { None, Region, FullScreen, ActiveWindow, Window, LastRegion, Clipboard, File, IE, Video, Import };
+ public enum ScreenCaptureMode { Auto, FullScreen, Fixed};
///
/// Details for the capture, like the window title and date/time etc.