mirror of
https://github.com/greenshot/greenshot
synced 2025-07-15 01:23:47 -07:00
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)...
This commit is contained in:
parent
d1ab25f852
commit
2f20c0820c
6 changed files with 92 additions and 67 deletions
|
@ -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 {
|
||||
/// <summary>
|
||||
|
@ -125,6 +126,34 @@ namespace Greenshot.Drawing {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Apply matrix to all elements
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Moves all elements in the list by the given amount of pixels.
|
||||
/// </summary>
|
||||
|
|
|
@ -171,7 +171,7 @@ namespace Greenshot.Drawing {
|
|||
/// <param name="shadow"></param>
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
|||
/// </summary>
|
||||
/// <param name="previous"></param>
|
||||
/// <param name="offset"></param>
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -18,23 +18,20 @@
|
|||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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 {
|
||||
/// <summary>
|
||||
/// Interface to describe an effect
|
||||
/// </summary>
|
||||
public interface IEffect {
|
||||
Image Apply(Image sourceImage, out Point offsetChange);
|
||||
Image Apply(Image sourceImage, Matrix matrix);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -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
|
||||
/// </summary>
|
||||
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
|
||||
/// </summary>
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -406,10 +406,10 @@ namespace GreenshotPlugin.Core {
|
|||
/// <param name="sourceBitmap">Bitmap</param>
|
||||
/// <param name="effect">IEffect</param>
|
||||
/// <returns>Bitmap</returns>
|
||||
public static Image ApplyEffect(Image sourceImage, IEffect effect, out Point offset) {
|
||||
public static Image ApplyEffect(Image sourceImage, IEffect effect, Matrix matrix) {
|
||||
List<IEffect> effects = new List<IEffect>();
|
||||
effects.Add(effect);
|
||||
return ApplyEffects(sourceImage, effects, out offset);
|
||||
return ApplyEffects(sourceImage, effects, matrix);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -418,16 +418,12 @@ namespace GreenshotPlugin.Core {
|
|||
/// <param name="sourceBitmap">Bitmap</param>
|
||||
/// <param name="effects">List<IEffect></param>
|
||||
/// <returns>Bitmap</returns>
|
||||
public static Image ApplyEffects(Image sourceImage, List<IEffect> effects, out Point offset) {
|
||||
public static Image ApplyEffects(Image sourceImage, List<IEffect> 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 {
|
|||
/// <param name="targetPixelformat">What pixel format must the returning bitmap have</param>
|
||||
/// <param name="offset">How many pixels is the original image moved?</param>
|
||||
/// <returns>Bitmap with the shadow, is bigger than the sourceBitmap!!</returns>
|
||||
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 {
|
|||
/// <param name="targetPixelformat">What pixel format must the returning bitmap have</param>
|
||||
/// <param name="offset">How many pixels is the original image moved?</param>
|
||||
/// <returns>Bitmap with the shadow, is bigger than the sourceBitmap!!</returns>
|
||||
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 {
|
|||
/// <param name="top"></param>
|
||||
/// <param name="bottom"></param>
|
||||
/// <returns>a new bitmap with the source copied on it</returns>
|
||||
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 {
|
|||
/// <param name="newWidth"></param>
|
||||
/// <param name="newHeight"></param>
|
||||
/// <returns></returns>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -1346,7 +1344,7 @@ namespace GreenshotPlugin.Core {
|
|||
/// <param name="newWidth">new width</param>
|
||||
/// <param name="newHeight">new height</param>
|
||||
/// <returns>a new bitmap with the specified size, the source-Image scaled to fit with aspect ratio locked</returns>
|
||||
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)) {
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue