From 46758d238c5ec9821afd43e72e34b7337628dc9f Mon Sep 17 00:00:00 2001 From: RKrom Date: Thu, 9 Feb 2012 15:30:27 +0000 Subject: [PATCH] Changes for Thomas & fixed undo/redo for background changes git-svn-id: http://svn.code.sf.net/p/greenshot/code/trunk@1647 7dccd23d-a4a3-4e1f-8c07-b4c1b4018ab4 --- Greenshot/Destinations/PickerDestination.cs | 10 ++ Greenshot/Drawing/Surface.cs | 25 +++-- Greenshot/Greenshot.csproj | 2 +- ...o.cs => SurfaceBackgroundChangeMemento.cs} | 12 +-- GreenshotPlugin/Core/ImageHelper.cs | 95 +++++++++++++++++-- GreenshotPlugin/Core/WindowsHelper.cs | 30 +++++- GreenshotPlugin/Interfaces/Generic.cs | 2 +- GreenshotPlugin/UnmanagedHelpers/DWM.cs | 19 ++++ 8 files changed, 164 insertions(+), 31 deletions(-) rename Greenshot/Memento/{SurfaceCropMemento.cs => SurfaceBackgroundChangeMemento.cs} (79%) diff --git a/Greenshot/Destinations/PickerDestination.cs b/Greenshot/Destinations/PickerDestination.cs index a44fb742a..352d43460 100644 --- a/Greenshot/Destinations/PickerDestination.cs +++ b/Greenshot/Destinations/PickerDestination.cs @@ -132,6 +132,16 @@ namespace Greenshot.Destinations { effectSubItem.Click += delegate { surface.ApplyBitmapEffect(Effects.TornEdge); }; + effectSubItem = new ToolStripMenuItem("Border"); + effectItem.DropDownItems.Add(effectSubItem); + effectSubItem.Click += delegate { + surface.ApplyBitmapEffect(Effects.Border); + }; + effectSubItem = new ToolStripMenuItem("Grayscale"); + effectItem.DropDownItems.Add(effectSubItem); + effectSubItem.Click += delegate { + surface.ApplyBitmapEffect(Effects.Grayscale); + }; }; } // Close diff --git a/Greenshot/Drawing/Surface.cs b/Greenshot/Drawing/Surface.cs index 75ef447a0..9a29be75e 100644 --- a/Greenshot/Drawing/Surface.cs +++ b/Greenshot/Drawing/Surface.cs @@ -552,20 +552,28 @@ namespace Greenshot.Drawing { Point offset = Point.Empty; switch (effect) { case Effects.Shadow: - newImage = ImageHelper.CreateShadow((Bitmap)Image, 1f, 10, Image.PixelFormat, out offset); + offset = new Point(6, 6); + newImage = ImageHelper.CreateShadow((Bitmap)Image, 1f, 7, offset, PixelFormat.Format24bppRgb); //Image.PixelFormat); break; case Effects.TornEdge: + offset = new Point(5, 5); using (Bitmap tmpImage = ImageHelper.CreateTornEdge((Bitmap)Image)) { - newImage = ImageHelper.CreateShadow(tmpImage, 1f, 8, Image.PixelFormat, out offset); + newImage = ImageHelper.CreateShadow(tmpImage, 1f, 6, offset, PixelFormat.Format24bppRgb); //Image.PixelFormat); } break; + case Effects.Border: + newImage = ImageHelper.CreateBorder((Bitmap)Image, 2, Color.Black, Image.PixelFormat, out offset); + break; + case Effects.Grayscale: + newImage = ImageHelper.CreateGrayscale((Bitmap)Image); + break; } if (newImage != null) { // Make sure the elements move according to the offset the effect made the bitmap move elements.MoveBy(offset.X, offset.Y); // Make undoable - MakeUndoable(new SurfaceCropMemento(this, imageRectangle), false); + MakeUndoable(new SurfaceBackgroundChangeMemento(this, offset), false); SetImage(newImage, false); Invalidate(); } @@ -600,11 +608,12 @@ namespace Greenshot.Drawing { Bitmap tmpImage = ((Bitmap)Image).Clone(cropRectangle, Image.PixelFormat); tmpImage.SetResolution(Image.HorizontalResolution, Image.VerticalResolution); + Point offset = new Point(-cropRectangle.Left, -cropRectangle.Top); // Make undoable - MakeUndoable(new SurfaceCropMemento(this, cropRectangle), false); + MakeUndoable(new SurfaceBackgroundChangeMemento(this, offset), false); SetImage(tmpImage, false); - elements.MoveBy(-cropRectangle.Left, -cropRectangle.Top); + elements.MoveBy(offset.X, offset.Y); if (SurfaceSizeChanged != null) { SurfaceSizeChanged(this); } @@ -613,10 +622,10 @@ namespace Greenshot.Drawing { } return false; } - - public void UndoCrop(Image previous, Rectangle cropRectangle) { + + public void UndoBackgroundChange(Image previous, Point offset) { SetImage(previous, false); - elements.MoveBy(cropRectangle.Left, cropRectangle.Top); + elements.MoveBy(offset.X, offset.Y); if (SurfaceSizeChanged != null) { SurfaceSizeChanged(this); } diff --git a/Greenshot/Greenshot.csproj b/Greenshot/Greenshot.csproj index a980f682a..578961637 100644 --- a/Greenshot/Greenshot.csproj +++ b/Greenshot/Greenshot.csproj @@ -197,7 +197,7 @@ - + diff --git a/Greenshot/Memento/SurfaceCropMemento.cs b/Greenshot/Memento/SurfaceBackgroundChangeMemento.cs similarity index 79% rename from Greenshot/Memento/SurfaceCropMemento.cs rename to Greenshot/Memento/SurfaceBackgroundChangeMemento.cs index 598ac9e3f..009bfa9b6 100644 --- a/Greenshot/Memento/SurfaceCropMemento.cs +++ b/Greenshot/Memento/SurfaceBackgroundChangeMemento.cs @@ -28,15 +28,15 @@ namespace Greenshot.Memento { /// /// The SurfaceCropMemento makes it possible to undo-redo an surface crop /// - public class SurfaceCropMemento : IMemento { + public class SurfaceBackgroundChangeMemento : IMemento { private Image image; private Surface surface; - private Rectangle cropRectangle; + private Point offset; - public SurfaceCropMemento(Surface surface, Rectangle cropRectangle) { + public SurfaceBackgroundChangeMemento(Surface surface, Point offset) { this.surface = surface; this.image = surface.Image; - this.cropRectangle = cropRectangle; + this.offset = new Point(-offset.X, -offset.Y); } public void Dispose() { @@ -58,8 +58,8 @@ namespace Greenshot.Memento { } public IMemento Restore() { - SurfaceCropMemento oldState = new SurfaceCropMemento( surface, cropRectangle); - surface.UndoCrop(image, cropRectangle); + SurfaceBackgroundChangeMemento oldState = new SurfaceBackgroundChangeMemento(surface, offset); + surface.UndoBackgroundChange(image, offset); surface.Invalidate(); return oldState; } diff --git a/GreenshotPlugin/Core/ImageHelper.cs b/GreenshotPlugin/Core/ImageHelper.cs index 9a902a4b9..14fcf3ceb 100644 --- a/GreenshotPlugin/Core/ImageHelper.cs +++ b/GreenshotPlugin/Core/ImageHelper.cs @@ -306,11 +306,7 @@ namespace GreenshotPlugin.Core { /// Changed bitmap public static Bitmap CreateTornEdge(Bitmap sourceBitmap) { Bitmap returnImage = new Bitmap(sourceBitmap.Width, sourceBitmap.Height, PixelFormat.Format32bppArgb); - try { - returnImage.SetResolution(sourceBitmap.HorizontalResolution, sourceBitmap.VerticalResolution); - } catch (Exception ex) { - LOG.Warn("An exception occured while setting the resolution.", ex); - } + returnImage.SetResolution(sourceBitmap.HorizontalResolution, sourceBitmap.VerticalResolution); using (GraphicsPath path = new GraphicsPath()) { Random random = new Random(); int regionWidth = 20; @@ -612,12 +608,10 @@ namespace GreenshotPlugin.Core { /// What pixel format must the returning bitmap have /// How many pixels is the original image moved? /// Bitmap with the shadow, is bigger than the sourceBitmap!! - public static Bitmap CreateShadow(Bitmap sourceBitmap, float darkness, int shadowSize, PixelFormat targetPixelformat, out Point offset) { - // "return" the shifted offset, so the caller can e.g. move elements - offset = new Point(shadowSize - 2, shadowSize - 2); - + public static Bitmap CreateShadow(Bitmap sourceBitmap, float darkness, int shadowSize, Point offset, PixelFormat targetPixelformat) { // Create a new "clean" image Bitmap newImage = new Bitmap(sourceBitmap.Width + (shadowSize * 2), sourceBitmap.Height + (shadowSize * 2), targetPixelformat); + newImage.SetResolution(sourceBitmap.HorizontalResolution, sourceBitmap.VerticalResolution); using (Graphics graphics = Graphics.FromImage(newImage)) { // Make sure the background color is what we want (transparent or white, depending on the pixel format) @@ -650,11 +644,92 @@ namespace GreenshotPlugin.Core { // draw original with a TextureBrush so we have nice antialiasing! using (Brush textureBrush = new TextureBrush(sourceBitmap, WrapMode.Clamp)) { // We need to do a translate-tranform otherwise the image is wrapped - graphics.TranslateTransform(shadowSize - 2, shadowSize - 2); + graphics.TranslateTransform(offset.X, offset.Y); graphics.FillRectangle(textureBrush, 0, 0, sourceBitmap.Width, sourceBitmap.Height); } } return newImage; } + + /// + /// Create a new bitmap where the sourceBitmap has a Simple border around it + /// + /// Bitmap to make a border on + /// Size of the border + /// Color of the border + /// What pixel format must the returning bitmap have + /// How many pixels is the original image moved? + /// Bitmap with the shadow, is bigger than the sourceBitmap!! + public static Bitmap CreateBorder(Bitmap sourceBitmap, int borderSize, Color borderColor, PixelFormat targetPixelformat, out Point offset) { + // "return" the shifted offset, so the caller can e.g. move elements + offset = new Point(borderSize, borderSize); + + // Create a new "clean" image + Bitmap newImage = new Bitmap(sourceBitmap.Width + (borderSize * 2), sourceBitmap.Height + (borderSize * 2), targetPixelformat); + newImage.SetResolution(sourceBitmap.HorizontalResolution, sourceBitmap.VerticalResolution); + using (Graphics graphics = Graphics.FromImage(newImage)) { + // Make sure the background color is what we want (transparent or white, depending on the pixel format) + if (Image.IsAlphaPixelFormat(targetPixelformat)) { + graphics.Clear(Color.Transparent); + } else { + graphics.Clear(Color.White); + } + // Make sure we draw with the best quality! + graphics.SmoothingMode = SmoothingMode.HighQuality; + graphics.PixelOffsetMode = PixelOffsetMode.HighQuality; + graphics.CompositingQuality = CompositingQuality.HighQuality; + graphics.InterpolationMode = InterpolationMode.HighQualityBicubic; + using (GraphicsPath path = new GraphicsPath()) { + path.AddRectangle(new Rectangle(borderSize >> 1, borderSize >> 1, newImage.Width - (borderSize), newImage.Height - (borderSize))); + using (Pen pen = new Pen(borderColor, borderSize)) { + pen.LineJoin = LineJoin.Round; + pen.StartCap = LineCap.Round; + pen.EndCap = LineCap.Round; + graphics.DrawPath(pen, path); + } + } + // draw original with a TextureBrush so we have nice antialiasing! + using (Brush textureBrush = new TextureBrush(sourceBitmap, WrapMode.Clamp)) { + // We need to do a translate-tranform otherwise the image is wrapped + graphics.TranslateTransform(offset.X, offset.Y); + graphics.FillRectangle(textureBrush, 0, 0, sourceBitmap.Width, sourceBitmap.Height); + } + } + return newImage; + } + + /// + /// Create a new bitmap where the sourceBitmap is in grayscale + /// + /// Original bitmap + /// Bitmap with grayscale + public static Bitmap CreateGrayscale(Bitmap sourceBitmap) { + //create a blank bitmap the same size as original + Bitmap newBitmap = new Bitmap(sourceBitmap.Width, sourceBitmap.Height); + + //get a graphics object from the new image + using (Graphics graphics = Graphics.FromImage(newBitmap)) { + // create the grayscale ColorMatrix + ColorMatrix colorMatrix = new ColorMatrix( + new float[][] { + new float[] {.3f, .3f, .3f, 0, 0}, + new float[] {.59f, .59f, .59f, 0, 0}, + new float[] {.11f, .11f, .11f, 0, 0}, + new float[] {0, 0, 0, 1, 0}, + new float[] {0, 0, 0, 0, 1} + }); + + //create some image attributes + ImageAttributes attributes = new ImageAttributes(); + + //set the color matrix attribute + attributes.SetColorMatrix(colorMatrix); + + //draw the original image on the new image using the grayscale color matrix + graphics.DrawImage(sourceBitmap, new Rectangle(0, 0, sourceBitmap.Width, sourceBitmap.Height), 0, 0, sourceBitmap.Width, sourceBitmap.Height, GraphicsUnit.Pixel, attributes); + } + + return newBitmap; + } } } diff --git a/GreenshotPlugin/Core/WindowsHelper.cs b/GreenshotPlugin/Core/WindowsHelper.cs index 46a4ae2bd..53a66cc0f 100644 --- a/GreenshotPlugin/Core/WindowsHelper.cs +++ b/GreenshotPlugin/Core/WindowsHelper.cs @@ -715,9 +715,11 @@ namespace GreenshotPlugin.Core { /// /// Capture DWM Window /// - /// - /// - public ICapture CaptureDWMWindow(ICapture capture, WindowCaptureMode windowCaptureMode, bool failIfNotFits) { + /// Capture to fill + /// Wanted WindowCaptureMode + /// True if auto modus is used + /// ICapture with the capture + public ICapture CaptureDWMWindow(ICapture capture, WindowCaptureMode windowCaptureMode, bool autoMode) { IntPtr thumbnailHandle = IntPtr.Zero; Form tempForm = null; bool tempFormShown = false; @@ -789,7 +791,7 @@ namespace GreenshotPlugin.Core { // and subtrackting the border from the size (2 times, as we move right/down for the capture without resizing) captureRectangle.Width -= 2 * borderSize.Width; captureRectangle.Height -= 2 * borderSize.Height; - } else if (failIfNotFits) { + } else if (autoMode) { // check if the capture fits if (!capture.ScreenBounds.Contains(captureRectangle)) { // if GDI is allowed.. @@ -856,7 +858,14 @@ namespace GreenshotPlugin.Core { // If no capture up till now, create a normal capture. if (capturedBitmap == null) { // Remove transparency, this will break the capturing - tempForm.BackColor = Color.FromArgb(255, conf.DWMBackgroundColor.R, conf.DWMBackgroundColor.G, conf.DWMBackgroundColor.B); + if (!autoMode) { + tempForm.BackColor = Color.FromArgb(255, conf.DWMBackgroundColor.R, conf.DWMBackgroundColor.G, conf.DWMBackgroundColor.B); + } else { + Color colorizationColor = DWM.ColorizationColor; + // Modify by losing the transparency and increasing the intensity (as if the background color is white) + colorizationColor = Color.FromArgb(255, (colorizationColor.R + 255) >> 1, (colorizationColor.G + 255) >> 1, (colorizationColor.B + 255) >> 1); + tempForm.BackColor = colorizationColor; + } // Make sure everything is visible tempForm.Refresh(); Application.DoEvents(); @@ -865,6 +874,12 @@ namespace GreenshotPlugin.Core { } if (capturedBitmap != null && redMask != null) { // Remove corners + if (!Image.IsAlphaPixelFormat(capturedBitmap.PixelFormat)) { + LOG.Debug("Changing pixelformat to Alpha for the RemoveCorners"); + Bitmap tmpBitmap = capturedBitmap.Clone(new Rectangle(Point.Empty, capturedBitmap.Size), PixelFormat.Format32bppArgb); + capturedBitmap.Dispose(); + capturedBitmap = tmpBitmap; + } RemoveCorners(capturedBitmap, redMask, windowCaptureMode, conf.DWMBackgroundColor); } } @@ -1208,6 +1223,11 @@ namespace GreenshotPlugin.Core { LOG.DebugFormat("Not freezing ourselves, process was: {0}", proc.ProcessName); return; } + // TODO: Check Outlook, Office etc? + if (proc.ProcessName.ToLower().Contains("outlook")) { + LOG.DebugFormat("Not freezing outlook due to Destinations, process was: {0}", proc.ProcessName); + return; + } LOG.DebugFormat("Freezing process: {0}", proc.ProcessName); foreach (ProcessThread pT in proc.Threads) { diff --git a/GreenshotPlugin/Interfaces/Generic.cs b/GreenshotPlugin/Interfaces/Generic.cs index 9052f4636..7455e1808 100644 --- a/GreenshotPlugin/Interfaces/Generic.cs +++ b/GreenshotPlugin/Interfaces/Generic.cs @@ -31,7 +31,7 @@ namespace Greenshot.Plugin { /// //public enum HorizontalAlignment {LEFT, CENTER, RIGHT}; public enum VerticalAlignment {TOP, CENTER, BOTTOM}; - public enum Effects { Shadow, TornEdge }; + public enum Effects { Shadow, TornEdge, Border, Grayscale }; public enum SurfaceMessageTyp { FileSaved, diff --git a/GreenshotPlugin/UnmanagedHelpers/DWM.cs b/GreenshotPlugin/UnmanagedHelpers/DWM.cs index 33d1f6ea0..12b552063 100644 --- a/GreenshotPlugin/UnmanagedHelpers/DWM.cs +++ b/GreenshotPlugin/UnmanagedHelpers/DWM.cs @@ -20,6 +20,8 @@ */ using System; using System.Runtime.InteropServices; +using Microsoft.Win32; +using System.Drawing; namespace GreenshotPlugin.UnmanagedHelpers { @@ -107,6 +109,9 @@ namespace GreenshotPlugin.UnmanagedHelpers { [DllImport("dwmapi", SetLastError = true)] public static extern int DwmEnableBlurBehindWindow(IntPtr hwnd, ref DWM_BLURBEHIND blurBehind); + // Key to ColorizationColor for DWM + private const string COLORIZATION_COLOR_KEY = @"SOFTWARE\Microsoft\Windows\DWM"; + /// /// Helper method for an easy DWM check /// @@ -119,5 +124,19 @@ namespace GreenshotPlugin.UnmanagedHelpers { } return false; } + + public static Color ColorizationColor { + get { + using (RegistryKey key = Registry.CurrentUser.OpenSubKey(COLORIZATION_COLOR_KEY, false)) { + if (key != null) { + object dwordValue = key.GetValue("ColorizationColor"); + if (dwordValue != null) { + return Color.FromArgb((Int32)dwordValue); + } + } + } + return Color.White; + } + } } }