Merge pull request #4104 from sylveon/master

Parallelize matrix convolution and consider transparency in gaussian blurs
This commit is contained in:
Jaex 2019-04-29 21:28:35 +03:00 committed by GitHub
commit 79a913d10c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 36 additions and 6 deletions

View file

@ -33,6 +33,8 @@ public class ConvolutionMatrix
public int Height => matrix.GetLength(0); public int Height => matrix.GetLength(0);
public byte Offset { get; set; } public byte Offset { get; set; }
public bool ConsiderAlpha { get; set; }
public ConvolutionMatrix() : this(3) public ConvolutionMatrix() : this(3)
{ {
} }

View file

@ -29,6 +29,7 @@
using System; using System;
using System.Drawing; using System.Drawing;
using System.Drawing.Imaging; using System.Drawing.Imaging;
using System.Threading.Tasks;
namespace ShareX.HelpersLib namespace ShareX.HelpersLib
{ {
@ -44,13 +45,14 @@ public static Image Apply(this ConvolutionMatrix kernel, Image img)
int originX = (kernel.Width - 1) / 2; int originX = (kernel.Width - 1) / 2;
int originY = (kernel.Height - 1) / 2; int originY = (kernel.Height - 1) / 2;
for (int y = 0; y < source.Height; y++) Parallel.For(0, source.Height, y =>
{ {
for (int x = 0; x < source.Width; x++) Parallel.For(0, source.Width, x =>
{ {
double r = 0.0; double r = 0.0;
double g = 0.0; double g = 0.0;
double b = 0.0; double b = 0.0;
double a = 0.0;
// Apply each matrix multiplier to the color components for each pixel. // Apply each matrix multiplier to the color components for each pixel.
for (int fy = 0; fy < kernel.Height; fy++) for (int fy = 0; fy < kernel.Height; fy++)
@ -72,6 +74,10 @@ public static Image Apply(this ConvolutionMatrix kernel, Image img)
r += kernel[fy, fx] * currentColor.Red; r += kernel[fy, fx] * currentColor.Red;
g += kernel[fy, fx] * currentColor.Green; g += kernel[fy, fx] * currentColor.Green;
b += kernel[fy, fx] * currentColor.Blue; b += kernel[fy, fx] * currentColor.Blue;
if (kernel.ConsiderAlpha)
{
a += kernel[fy, fx] * currentColor.Alpha;
}
} }
} }
@ -84,9 +90,26 @@ public static Image Apply(this ConvolutionMatrix kernel, Image img)
b += kernel.Offset; b += kernel.Offset;
b.Clamp(0, 255); b.Clamp(0, 255);
dest.SetPixel(x, y, new ColorBgra((byte)b, (byte)g, (byte)r, source.GetPixel(x, y).Alpha)); if (kernel.ConsiderAlpha)
} {
} a += kernel.Offset;
a.Clamp(0, 255);
}
dest.SetPixel(
x,
y,
new ColorBgra(
(byte)b,
(byte)g,
(byte)r,
kernel.ConsiderAlpha
? (byte)a
: source.GetPixel(x, y).Alpha
)
);
});
});
} }
return result; return result;
@ -115,6 +138,7 @@ private static double GaussianFunction(double x, double sigma)
public static ConvolutionMatrix GaussianBlur(int height, int width, double sigma) public static ConvolutionMatrix GaussianBlur(int height, int width, double sigma)
{ {
ConvolutionMatrix cm = new ConvolutionMatrix(height, width); ConvolutionMatrix cm = new ConvolutionMatrix(height, width);
cm.ConsiderAlpha = true;
double sum = 0.0; double sum = 0.0;
double midpointX = (width - 1) / 2.0; double midpointX = (width - 1) / 2.0;

View file

@ -67,7 +67,11 @@ public override Image Apply(Image img)
{ {
ConvolutionMatrix kernelHoriz = ConvolutionMatrixManager.GaussianBlur(1, size, sigma); ConvolutionMatrix kernelHoriz = ConvolutionMatrixManager.GaussianBlur(1, size, sigma);
ConvolutionMatrix kernelVert = new ConvolutionMatrix(size, 1); ConvolutionMatrix kernelVert = new ConvolutionMatrix(size, 1)
{
ConsiderAlpha = kernelHoriz.ConsiderAlpha
};
for (int i = 0; i < size; i++) for (int i = 0; i < size; i++)
{ {
kernelVert[i, 0] = kernelHoriz[0, i]; kernelVert[i, 0] = kernelHoriz[0, i];