From 2f20c0820c38c5e111e764df152de109c85a1c0e Mon Sep 17 00:00:00 2001 From: RKrom Date: Fri, 30 May 2014 16:44:27 +0200 Subject: [PATCH] Trying to solve the problem that effects don't change the elements, except for the offset, by using a Matrix and than later transforming the elements. This is just the start of an idea, if this leads to nothing we can "git revert" the commit(s)... --- Greenshot/Drawing/DrawableContainerList.cs | 29 +++++++++++ Greenshot/Drawing/ImageContainer.cs | 2 +- Greenshot/Drawing/Surface.cs | 26 ++++++---- GreenshotPlugin/Core/Effects.cs | 60 ++++++++++------------ GreenshotPlugin/Core/ImageHelper.cs | 38 +++++++------- GreenshotPlugin/Core/ImageOutput.cs | 4 +- 6 files changed, 92 insertions(+), 67 deletions(-) diff --git a/Greenshot/Drawing/DrawableContainerList.cs b/Greenshot/Drawing/DrawableContainerList.cs index 62080def8..8de1cde17 100644 --- a/Greenshot/Drawing/DrawableContainerList.cs +++ b/Greenshot/Drawing/DrawableContainerList.cs @@ -30,6 +30,7 @@ using Greenshot.Plugin.Drawing; using System.Windows.Forms; using GreenshotPlugin.Core; using Greenshot.Configuration; +using System.Drawing.Drawing2D; namespace Greenshot.Drawing { /// @@ -125,6 +126,34 @@ namespace Greenshot.Drawing { } } + /// + /// Apply matrix to all elements + /// + public void Transform(Matrix matrix) { + // Track modifications + bool modified = false; + Invalidate(); + foreach (var dc in this) { + //Point[] points = new Point[] { new Point(rectangle.Left, rectangle.Top), new Point(rectangle.Right, rectangle.Bottom) }; + //matrix.TransformPoints(points); + // Return that as a rectangle + //new Rectangle(points[0], new Size(points[0].X - points[1].X, points[0].Y - points[1].Y)); + + Point[] location = new Point[] { dc.Location }; + matrix.TransformPoints(location); + + dc.Left = location[0].X; + dc.Top = location[0].Y; + modified = true; + } + // Invalidate after + Invalidate(); + // If we moved something, tell the surface it's modified! + if (modified) { + Parent.Modified = true; + } + } + /// /// Moves all elements in the list by the given amount of pixels. /// diff --git a/Greenshot/Drawing/ImageContainer.cs b/Greenshot/Drawing/ImageContainer.cs index 6351bbb68..26aadc9da 100644 --- a/Greenshot/Drawing/ImageContainer.cs +++ b/Greenshot/Drawing/ImageContainer.cs @@ -171,7 +171,7 @@ namespace Greenshot.Drawing { /// private void CheckShadow(bool shadow) { if (shadow && _shadowBitmap == null) { - _shadowBitmap = ImageHelper.ApplyEffect(image, new DropShadowEffect(), out _shadowOffset); + _shadowBitmap = ImageHelper.ApplyEffect(image, new DropShadowEffect(), new Matrix()); } } diff --git a/Greenshot/Drawing/Surface.cs b/Greenshot/Drawing/Surface.cs index 10fe8f084..20ddc8248 100644 --- a/Greenshot/Drawing/Surface.cs +++ b/Greenshot/Drawing/Surface.cs @@ -37,6 +37,7 @@ using Greenshot.IniFile; using GreenshotPlugin.Controls; using Greenshot.Core; using log4net; +using System.Drawing.Drawing2D; namespace Greenshot.Drawing { @@ -867,7 +868,7 @@ namespace Greenshot.Drawing { Bitmap newBitmap = ImageHelper.CreateEmptyLike((Bitmap)Image, Color.Empty); if (newBitmap != null) { // Make undoable - MakeUndoable(new SurfaceBackgroundChangeMemento(this, Point.Empty), false); + MakeUndoable(new SurfaceBackgroundChangeMemento(this, null), false); SetImage(newBitmap, false); Invalidate(); } @@ -883,13 +884,13 @@ namespace Greenshot.Drawing { Application.DoEvents(); try { Rectangle imageRectangle = new Rectangle(Point.Empty, Image.Size); - Point offset; - Image newImage = ImageHelper.ApplyEffect(Image, effect, out offset); + Matrix matrix = new Matrix(); + Image newImage = ImageHelper.ApplyEffect(Image, effect, matrix); if (newImage != null) { // Make sure the elements move according to the offset the effect made the bitmap move - elements.MoveBy(offset.X, offset.Y); + elements.Transform(matrix); // Make undoable - MakeUndoable(new SurfaceBackgroundChangeMemento(this, offset), false); + MakeUndoable(new SurfaceBackgroundChangeMemento(this, matrix), false); SetImage(newImage, false); Invalidate(); if (surfaceSizeChanged != null && !imageRectangle.Equals(new Rectangle(Point.Empty, newImage.Size))) { @@ -963,13 +964,14 @@ namespace Greenshot.Drawing { throw; } - Point offset = new Point(-cropRectangle.Left, -cropRectangle.Top); + Matrix matrix = new Matrix(); + matrix.Translate(-cropRectangle.Left, -cropRectangle.Top); // Make undoable - MakeUndoable(new SurfaceBackgroundChangeMemento(this, offset), false); + MakeUndoable(new SurfaceBackgroundChangeMemento(this, matrix), false); // Do not dispose otherwise we can't undo the image! SetImage(tmpImage, false); - elements.MoveBy(offset.X, offset.Y); + elements.Transform(matrix); if (surfaceSizeChanged != null && !imageRectangle.Equals(new Rectangle(Point.Empty, tmpImage.Size))) { surfaceSizeChanged(this, null); } @@ -985,9 +987,11 @@ namespace Greenshot.Drawing { /// /// /// - public void UndoBackgroundChange(Image previous, Point offset) { + public void UndoBackgroundChange(Image previous, Matrix matrix) { SetImage(previous, false); - elements.MoveBy(offset.X, offset.Y); + if (matrix != null) { + elements.Transform(matrix); + } if (surfaceSizeChanged != null) { surfaceSizeChanged(this, null); } @@ -1162,7 +1166,7 @@ namespace Greenshot.Drawing { mouseStart = currentMouse; mouseDownElement.Invalidate(); modified = true; - } else if(drawingElement != null) { + } else if (drawingElement != null) { drawingElement.HandleMouseMove(currentMouse.X, currentMouse.Y); modified = true; } diff --git a/GreenshotPlugin/Core/Effects.cs b/GreenshotPlugin/Core/Effects.cs index eb4c1d388..87145fd86 100644 --- a/GreenshotPlugin/Core/Effects.cs +++ b/GreenshotPlugin/Core/Effects.cs @@ -18,23 +18,20 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -using System; -using System.Drawing; -using System.Drawing.Imaging; -using System.Windows.Forms; -using Greenshot.Plugin.Drawing; -using System.IO; -using System.Collections.Generic; using GreenshotPlugin.Core; using log4net; +using System; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Drawing.Imaging; namespace Greenshot.Core { /// /// Interface to describe an effect /// public interface IEffect { - Image Apply(Image sourceImage, out Point offsetChange); + Image Apply(Image sourceImage, Matrix matrix); } /// @@ -58,8 +55,8 @@ namespace Greenshot.Core { get; set; } - public virtual Image Apply(Image sourceImage, out Point offsetChange) { - return ImageHelper.CreateShadow(sourceImage, Darkness, ShadowSize, ShadowOffset, out offsetChange, PixelFormat.Format32bppArgb); + public virtual Image Apply(Image sourceImage, Matrix matrix) { + return ImageHelper.CreateShadow(sourceImage, Darkness, ShadowSize, ShadowOffset, matrix, PixelFormat.Format32bppArgb); } } @@ -90,9 +87,9 @@ namespace Greenshot.Core { get; set; } - public override Image Apply(Image sourceImage, out Point offsetChange) { + public override Image Apply(Image sourceImage, Matrix matrix) { using (Image tmpTornImage = ImageHelper.CreateTornEdge(sourceImage, ToothHeight, HorizontalToothRange, VerticalToothRange, Edges)) { - return ImageHelper.CreateShadow(tmpTornImage, Darkness, ShadowSize, ShadowOffset, out offsetChange, PixelFormat.Format32bppArgb); + return ImageHelper.CreateShadow(tmpTornImage, Darkness, ShadowSize, ShadowOffset, matrix, PixelFormat.Format32bppArgb); } } } @@ -101,8 +98,7 @@ namespace Greenshot.Core { /// GrayscaleEffect /// public class GrayscaleEffect : IEffect { - public Image Apply(Image sourceImage, out Point offsetChange) { - offsetChange = Point.Empty; + public Image Apply(Image sourceImage, Matrix matrix) { return ImageHelper.CreateGrayscale(sourceImage); } } @@ -116,8 +112,7 @@ namespace Greenshot.Core { public MonochromeEffect(byte threshold) { this.threshold = threshold; } - public Image Apply(Image sourceImage, out Point offsetChange) { - offsetChange = Point.Empty; + public Image Apply(Image sourceImage, Matrix matrix) { return ImageHelper.CreateMonochrome(sourceImage, threshold); } } @@ -143,8 +138,7 @@ namespace Greenshot.Core { get; set; } - public Image Apply(Image sourceImage, out Point offsetChange) { - offsetChange = Point.Empty; + public Image Apply(Image sourceImage, Matrix matrix) { return ImageHelper.Adjust(sourceImage, Brightness, Contrast, Gamma); } } @@ -161,8 +155,7 @@ namespace Greenshot.Core { get; set; } - public Image Apply(Image sourceImage, out Point offsetChange) { - offsetChange = Point.Empty; + public Image Apply(Image sourceImage, Matrix matrix) { using (WuQuantizer quantizer = new WuQuantizer((Bitmap)sourceImage)) { int colorCount = quantizer.GetColorCount(); if (colorCount > Colors) { @@ -181,8 +174,7 @@ namespace Greenshot.Core { /// InvertEffect /// public class InvertEffect : IEffect { - public Image Apply(Image sourceImage, out Point offsetChange) { - offsetChange = Point.Empty; + public Image Apply(Image sourceImage, Matrix matrix) { return ImageHelper.CreateNegative(sourceImage); } } @@ -203,8 +195,8 @@ namespace Greenshot.Core { get; set; } - public Image Apply(Image sourceImage, out Point offsetChange) { - return ImageHelper.CreateBorder(sourceImage, Width, Color, sourceImage.PixelFormat, out offsetChange); + public Image Apply(Image sourceImage, Matrix matrix) { + return ImageHelper.CreateBorder(sourceImage, Width, Color, sourceImage.PixelFormat, matrix); } } @@ -219,13 +211,18 @@ namespace Greenshot.Core { get; set; } - public Image Apply(Image sourceImage, out Point offsetChange) { - offsetChange = Point.Empty; + public Image Apply(Image sourceImage, Matrix matrix) { RotateFlipType flipType; if (Angle == 90) { + matrix.Rotate(90); + matrix.Translate(-sourceImage.Height, 0); + //matrix.RotateAt(90, new Point(sourceImage.Width / 2, sourceImage.Height / 2)); flipType = RotateFlipType.Rotate90FlipNone; } else if (Angle == -90 || Angle == 270) { flipType = RotateFlipType.Rotate270FlipNone; + matrix.Rotate(-90); + //matrix.RotateAt(-90, new Point(sourceImage.Width / 2, sourceImage.Height / 2)); + matrix.Translate(0, -sourceImage.Width); } else { throw new NotSupportedException("Currently only an angle of 90 or -90 (270) is supported."); } @@ -254,9 +251,8 @@ namespace Greenshot.Core { get; set; } - public Image Apply(Image sourceImage, out Point offsetChange) { - offsetChange = Point.Empty; - return ImageHelper.ResizeImage(sourceImage, MaintainAspectRatio, Width, Height); + public Image Apply(Image sourceImage, Matrix matrix) { + return ImageHelper.ResizeImage(sourceImage, MaintainAspectRatio, Width, Height, matrix); } } @@ -291,10 +287,8 @@ namespace Greenshot.Core { get; set; } - public Image Apply(Image sourceImage, out Point offsetChange) { - // Make sure the elements move according to the offset the effect made the bitmap move - offsetChange = new Point(Left, Top); - return ImageHelper.ResizeCanvas(sourceImage, BackgroundColor, Left, Right, Top, Bottom); + public Image Apply(Image sourceImage, Matrix matrix) { + return ImageHelper.ResizeCanvas(sourceImage, BackgroundColor, Left, Right, Top, Bottom, matrix); } } } \ No newline at end of file diff --git a/GreenshotPlugin/Core/ImageHelper.cs b/GreenshotPlugin/Core/ImageHelper.cs index e92174347..3344e1f00 100644 --- a/GreenshotPlugin/Core/ImageHelper.cs +++ b/GreenshotPlugin/Core/ImageHelper.cs @@ -406,10 +406,10 @@ namespace GreenshotPlugin.Core { /// Bitmap /// IEffect /// Bitmap - public static Image ApplyEffect(Image sourceImage, IEffect effect, out Point offset) { + public static Image ApplyEffect(Image sourceImage, IEffect effect, Matrix matrix) { List effects = new List(); effects.Add(effect); - return ApplyEffects(sourceImage, effects, out offset); + return ApplyEffects(sourceImage, effects, matrix); } /// @@ -418,16 +418,12 @@ namespace GreenshotPlugin.Core { /// Bitmap /// List /// Bitmap - public static Image ApplyEffects(Image sourceImage, List effects, out Point offset) { + public static Image ApplyEffects(Image sourceImage, List effects, Matrix matrix) { Image currentImage = sourceImage; bool disposeImage = false; - // Default out value for the offset, will be modified there where needed - offset = new Point(0, 0); - Point tmpPoint; foreach (IEffect effect in effects) { - Image tmpImage = effect.Apply(currentImage, out tmpPoint); + Image tmpImage = effect.Apply(currentImage, matrix); if (tmpImage != null) { - offset.Offset(tmpPoint); if (disposeImage) { currentImage.Dispose(); } @@ -824,11 +820,12 @@ 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(Image sourceBitmap, float darkness, int shadowSize, Point shadowOffset, out Point offset, PixelFormat targetPixelformat) { - // Create a new "clean" image - offset = shadowOffset; + public static Bitmap CreateShadow(Image sourceBitmap, float darkness, int shadowSize, Point shadowOffset, Matrix matrix, PixelFormat targetPixelformat) { + Point offset = shadowOffset; offset.X += shadowSize - 1; offset.Y += shadowSize - 1; + matrix.Translate(offset.X, offset.Y); + // Create a new "clean" image Bitmap returnImage = CreateEmpty(sourceBitmap.Width + (shadowSize * 2), sourceBitmap.Height + (shadowSize * 2), targetPixelformat, Color.Empty, sourceBitmap.HorizontalResolution, sourceBitmap.VerticalResolution); // Make sure the shadow is odd, there is no reason for an even blur! if ((shadowSize & 1) == 0) { @@ -985,9 +982,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 Image CreateBorder(Image sourceImage, int borderSize, Color borderColor, PixelFormat targetPixelformat, out Point offset) { + public static Image CreateBorder(Image sourceImage, int borderSize, Color borderColor, PixelFormat targetPixelformat, Matrix matrix) { // "return" the shifted offset, so the caller can e.g. move elements - offset = new Point(borderSize, borderSize); + Point offset = new Point(borderSize, borderSize); + matrix.Translate(offset.X, offset.Y); // Create a new "clean" image Bitmap newImage = CreateEmpty(sourceImage.Width + (borderSize * 2), sourceImage.Height + (borderSize * 2), targetPixelformat, Color.Empty, sourceImage.HorizontalResolution, sourceImage.VerticalResolution); @@ -1287,7 +1285,8 @@ namespace GreenshotPlugin.Core { /// /// /// a new bitmap with the source copied on it - public static Image ResizeCanvas(Image sourceImage, Color backgroundColor, int left, int right, int top, int bottom) { + public static Image ResizeCanvas(Image sourceImage, Color backgroundColor, int left, int right, int top, int bottom, Matrix matrix) { + matrix.Translate(left, top); Bitmap newBitmap = CreateEmpty(sourceImage.Width + left + right, sourceImage.Height + top + bottom, sourceImage.PixelFormat, backgroundColor, sourceImage.HorizontalResolution, sourceImage.VerticalResolution); using (Graphics graphics = Graphics.FromImage(newBitmap)) { graphics.DrawImageUnscaled(sourceImage, left, top); @@ -1303,9 +1302,8 @@ namespace GreenshotPlugin.Core { /// /// /// - public static Image ResizeImage(Image sourceImage, bool maintainAspectRatio, int newWidth, int newHeight) { - Point throwAway; - return ResizeImage(sourceImage, maintainAspectRatio, false, Color.Empty, newWidth, newHeight, out throwAway); + public static Image ResizeImage(Image sourceImage, bool maintainAspectRatio, int newWidth, int newHeight, Matrix matrix) { + return ResizeImage(sourceImage, maintainAspectRatio, false, Color.Empty, newWidth, newHeight, matrix); } /// @@ -1346,7 +1344,7 @@ namespace GreenshotPlugin.Core { /// new width /// new height /// a new bitmap with the specified size, the source-Image scaled to fit with aspect ratio locked - public static Image ResizeImage(Image sourceImage, bool maintainAspectRatio, bool canvasUseNewSize, Color backgroundColor, int newWidth, int newHeight, out Point offset) { + public static Image ResizeImage(Image sourceImage, bool maintainAspectRatio, bool canvasUseNewSize, Color backgroundColor, int newWidth, int newHeight, Matrix matrix) { int destX = 0; int destY = 0; @@ -1379,8 +1377,6 @@ namespace GreenshotPlugin.Core { } } - offset = new Point(destX, destY); - int destWidth = (int)(sourceImage.Width * nPercentW); int destHeight = (int)(sourceImage.Height * nPercentH); if (newWidth == 0) { @@ -1392,8 +1388,10 @@ namespace GreenshotPlugin.Core { Image newImage = null; if (maintainAspectRatio && canvasUseNewSize) { newImage = CreateEmpty(newWidth, newHeight, sourceImage.PixelFormat, backgroundColor, sourceImage.HorizontalResolution, sourceImage.VerticalResolution); + matrix.Scale(sourceImage.Width / newWidth, sourceImage.Height / newHeight); } else { newImage = CreateEmpty(destWidth, destHeight, sourceImage.PixelFormat, backgroundColor, sourceImage.HorizontalResolution, sourceImage.VerticalResolution); + matrix.Scale(sourceImage.Width / destWidth, sourceImage.Height / destHeight); } using (Graphics graphics = Graphics.FromImage(newImage)) { diff --git a/GreenshotPlugin/Core/ImageOutput.cs b/GreenshotPlugin/Core/ImageOutput.cs index 6fbdd5d3d..ba54b560d 100644 --- a/GreenshotPlugin/Core/ImageOutput.cs +++ b/GreenshotPlugin/Core/ImageOutput.cs @@ -26,6 +26,7 @@ using log4net; using System; using System.Diagnostics; using System.Drawing; +using System.Drawing.Drawing2D; using System.Drawing.Imaging; using System.IO; using System.Reflection; @@ -302,8 +303,7 @@ namespace GreenshotPlugin.Core { Image tmpImage; if (outputSettings.Effects != null && outputSettings.Effects.Count > 0) { // apply effects, if there are any - Point ignoreOffset; - tmpImage = ImageHelper.ApplyEffects(imageToSave, outputSettings.Effects, out ignoreOffset); + tmpImage = ImageHelper.ApplyEffects(imageToSave, outputSettings.Effects, new Matrix()); if (tmpImage != null) { if (disposeImage) { imageToSave.Dispose();