mirror of
https://github.com/ShareX/ShareX.git
synced 2024-07-07 23:46:00 +12:00
Merge pull request #4104 from sylveon/master
Parallelize matrix convolution and consider transparency in gaussian blurs
This commit is contained in:
commit
79a913d10c
|
@ -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)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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];
|
||||||
|
|
Loading…
Reference in a new issue