From dd7dcefcb5aa2eeac0242bf9fe829e32e3b41211 Mon Sep 17 00:00:00 2001 From: Jaex Date: Wed, 6 Nov 2013 00:00:55 +0200 Subject: [PATCH] Using convolution matrix for sharpen --- HelpersLib/ConvolutionMatrix.cs | 63 ++++++++++++++ HelpersLib/ConvolutionMatrixManager.cs | 111 +++++++++++++++++++++++++ HelpersLib/Helpers/ImageHelpers.cs | 4 +- HelpersLib/HelpersLib.csproj | 2 + ImageEffectsLib/Filters/Sharpen.cs | 15 ++-- 5 files changed, 183 insertions(+), 12 deletions(-) create mode 100644 HelpersLib/ConvolutionMatrix.cs create mode 100644 HelpersLib/ConvolutionMatrixManager.cs diff --git a/HelpersLib/ConvolutionMatrix.cs b/HelpersLib/ConvolutionMatrix.cs new file mode 100644 index 000000000..118e15ed5 --- /dev/null +++ b/HelpersLib/ConvolutionMatrix.cs @@ -0,0 +1,63 @@ +#region License Information (GPL v3) + +/* + ShareX - A program that allows you to take screenshots and share any file type + Copyright (C) 2008-2013 ShareX Developers + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + Optionally you can also view the license at . +*/ + +#endregion License Information (GPL v3) + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace HelpersLib +{ + public class ConvolutionMatrix + { + public int Size { get; private set; } + public int[,] Matrix { get; set; } + public int Factor { get; set; } + public int Offset { get; set; } + + public ConvolutionMatrix() + : this(3) + { + } + + public ConvolutionMatrix(int size) + { + Size = size; + Matrix = new int[Size, Size]; + Factor = 1; + } + + public void SetAll(int value) + { + for (int y = 0; y < Size; y++) + { + for (int x = 0; x < Size; x++) + { + Matrix[x, y] = value; + } + } + } + } +} \ No newline at end of file diff --git a/HelpersLib/ConvolutionMatrixManager.cs b/HelpersLib/ConvolutionMatrixManager.cs new file mode 100644 index 000000000..9f36485f7 --- /dev/null +++ b/HelpersLib/ConvolutionMatrixManager.cs @@ -0,0 +1,111 @@ +#region License Information (GPL v3) + +/* + ShareX - A program that allows you to take screenshots and share any file type + Copyright (C) 2008-2013 ShareX Developers + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + Optionally you can also view the license at . +*/ + +#endregion License Information (GPL v3) + +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Drawing.Imaging; +using System.Linq; +using System.Text; + +namespace HelpersLib +{ + public static class ConvolutionMatrixManager + { + public static Image Apply(this ConvolutionMatrix matrix, Image img) + { + Bitmap result = (Bitmap)img.Clone(); + + using (UnsafeBitmap source = new UnsafeBitmap((Bitmap)img, true, ImageLockMode.ReadOnly)) + using (UnsafeBitmap dest = new UnsafeBitmap(result, true, ImageLockMode.WriteOnly)) + { + ColorBgra[,] pixelColor = new ColorBgra[3, 3]; + ColorBgra color = new ColorBgra(); + + for (int y = 0; y < source.Height - 2; y++) + { + for (int x = 0; x < source.Width - 2; x++) + { + pixelColor[0, 0] = source.GetPixel(x, y); + pixelColor[0, 1] = source.GetPixel(x, y + 1); + pixelColor[0, 2] = source.GetPixel(x, y + 2); + pixelColor[1, 0] = source.GetPixel(x + 1, y); + pixelColor[1, 1] = source.GetPixel(x + 1, y + 1); + pixelColor[1, 2] = source.GetPixel(x + 1, y + 2); + pixelColor[2, 0] = source.GetPixel(x + 2, y); + pixelColor[2, 1] = source.GetPixel(x + 2, y + 1); + pixelColor[2, 2] = source.GetPixel(x + 2, y + 2); + + color.Alpha = pixelColor[1, 1].Alpha; + + color.Red = (byte)(((((pixelColor[0, 0].Red * matrix.Matrix[0, 0]) + + (pixelColor[1, 0].Red * matrix.Matrix[1, 0]) + + (pixelColor[2, 0].Red * matrix.Matrix[2, 0]) + + (pixelColor[0, 1].Red * matrix.Matrix[0, 1]) + + (pixelColor[1, 1].Red * matrix.Matrix[1, 1]) + + (pixelColor[2, 1].Red * matrix.Matrix[2, 1]) + + (pixelColor[0, 2].Red * matrix.Matrix[0, 2]) + + (pixelColor[1, 2].Red * matrix.Matrix[1, 2]) + + (pixelColor[2, 2].Red * matrix.Matrix[2, 2])) / matrix.Factor) + matrix.Offset).Between(0, 255)); + + color.Green = (byte)(((((pixelColor[0, 0].Green * matrix.Matrix[0, 0]) + + (pixelColor[1, 0].Green * matrix.Matrix[1, 0]) + + (pixelColor[2, 0].Green * matrix.Matrix[2, 0]) + + (pixelColor[0, 1].Green * matrix.Matrix[0, 1]) + + (pixelColor[1, 1].Green * matrix.Matrix[1, 1]) + + (pixelColor[2, 1].Green * matrix.Matrix[2, 1]) + + (pixelColor[0, 2].Green * matrix.Matrix[0, 2]) + + (pixelColor[1, 2].Green * matrix.Matrix[1, 2]) + + (pixelColor[2, 2].Green * matrix.Matrix[2, 2])) / matrix.Factor) + matrix.Offset).Between(0, 255)); + + color.Blue = (byte)(((((pixelColor[0, 0].Blue * matrix.Matrix[0, 0]) + + (pixelColor[1, 0].Blue * matrix.Matrix[1, 0]) + + (pixelColor[2, 0].Blue * matrix.Matrix[2, 0]) + + (pixelColor[0, 1].Blue * matrix.Matrix[0, 1]) + + (pixelColor[1, 1].Blue * matrix.Matrix[1, 1]) + + (pixelColor[2, 1].Blue * matrix.Matrix[2, 1]) + + (pixelColor[0, 2].Blue * matrix.Matrix[0, 2]) + + (pixelColor[1, 2].Blue * matrix.Matrix[1, 2]) + + (pixelColor[2, 2].Blue * matrix.Matrix[2, 2])) / matrix.Factor) + matrix.Offset).Between(0, 255)); + + dest.SetPixel(x + 1, y + 1, color); + } + } + } + + return result; + } + + public static ConvolutionMatrix Sharpen(int weight = 11) + { + ConvolutionMatrix matrix = new ConvolutionMatrix(); + matrix.SetAll(0); + matrix.Matrix[1, 1] = weight; + matrix.Matrix[1, 0] = matrix.Matrix[0, 1] = matrix.Matrix[2, 1] = matrix.Matrix[1, 2] = -2; + matrix.Factor = Math.Max(weight - 8, 1); + return matrix; + } + } +} \ No newline at end of file diff --git a/HelpersLib/Helpers/ImageHelpers.cs b/HelpersLib/Helpers/ImageHelpers.cs index 5db1084fe..a6e822c3b 100644 --- a/HelpersLib/Helpers/ImageHelpers.cs +++ b/HelpersLib/Helpers/ImageHelpers.cs @@ -850,9 +850,7 @@ public static Bitmap Sharpen(Image image, double strength) // Lock image bits for read/write. if (sharpenImage != null) { - BitmapData pbits = sharpenImage.LockBits(new Rectangle(0, 0, width, height), - ImageLockMode.ReadWrite, - PixelFormat.Format24bppRgb); + BitmapData pbits = sharpenImage.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); // Declare an array to hold the bytes of the bitmap. int bytes = pbits.Stride * height; diff --git a/HelpersLib/HelpersLib.csproj b/HelpersLib/HelpersLib.csproj index ff67a9304..d084946f1 100644 --- a/HelpersLib/HelpersLib.csproj +++ b/HelpersLib/HelpersLib.csproj @@ -84,6 +84,8 @@ + + diff --git a/ImageEffectsLib/Filters/Sharpen.cs b/ImageEffectsLib/Filters/Sharpen.cs index f6a03f4ae..dd2bdd589 100644 --- a/ImageEffectsLib/Filters/Sharpen.cs +++ b/ImageEffectsLib/Filters/Sharpen.cs @@ -31,17 +31,14 @@ namespace ImageEffectsLib { internal class Sharpen : ImageEffect { - [DefaultValue(1.0d)] - public double Strength { get; set; } - - public Sharpen() - { - this.ApplyDefaultPropertyValues(); - } - public override Image Apply(Image img) { - return ImageHelpers.Sharpen(img, Strength); + //return ImageHelpers.Sharpen(img, Strength); + + using (img) + { + return ConvolutionMatrixManager.Sharpen().Apply(img); + } } } } \ No newline at end of file