diff options
Diffstat (limited to 'UVtools.Core/Extensions')
-rw-r--r-- | UVtools.Core/Extensions/DrawingExtensions.cs | 34 | ||||
-rw-r--r-- | UVtools.Core/Extensions/EmguExtensions.cs | 17 | ||||
-rw-r--r-- | UVtools.Core/Extensions/SpanExtensions.cs | 34 |
3 files changed, 77 insertions, 8 deletions
diff --git a/UVtools.Core/Extensions/DrawingExtensions.cs b/UVtools.Core/Extensions/DrawingExtensions.cs new file mode 100644 index 0000000..8a60ee4 --- /dev/null +++ b/UVtools.Core/Extensions/DrawingExtensions.cs @@ -0,0 +1,34 @@ +using System; +using System.Drawing; + +namespace UVtools.Core.Extensions +{ + public static class DrawingExtensions + { + public static Color FactorColor(this Color color, byte pixelColor, byte min = 0, byte max = byte.MaxValue) => + FactorColor(color, pixelColor / 255f, min, max); + + public static Color FactorColor(this Color color, float factor, byte min = 0, byte max = byte.MaxValue) + { + byte r = (byte)(color.R == 0 ? 0 : + Math.Min(Math.Max(min, color.R * factor), max)); + + byte g = (byte)(color.G == 0 ? 0 : + Math.Min(Math.Max(min, color.G * factor), max)); + + byte b = (byte)(color.B == 0 ? 0 : + Math.Min(Math.Max(min, color.B * factor), max)); + return Color.FromArgb(r, g, b); + } + + public static int GetArea(this Rectangle rect) + { + return rect.Width * rect.Height; + } + + public static int GetArea(this Size size) + { + return size.Width * size.Height; + } + } +} diff --git a/UVtools.Core/Extensions/EmguExtensions.cs b/UVtools.Core/Extensions/EmguExtensions.cs index a96a50f..735c41a 100644 --- a/UVtools.Core/Extensions/EmguExtensions.cs +++ b/UVtools.Core/Extensions/EmguExtensions.cs @@ -27,11 +27,10 @@ namespace UVtools.Core.Extensions return new Span<T>(mat.DataPointer.ToPointer(), mat.GetLength()); } - public static Span<T> GetPixelRowSpan<T>(this Mat mat, int y) + public static unsafe Span<T> GetPixelRowSpan<T>(this Mat mat, int y) { - int offset = y * mat.Step; - //IntPtr ptr = IntPtr.Add(mat.DataPointer, offset); - return mat.GetPixelSpan<T>().Slice(offset, mat.Step); + return new Span<T>(IntPtr.Add(mat.DataPointer, y * mat.Step).ToPointer(), mat.Step); + //return mat.GetPixelSpan<T>().Slice(offset, mat.Step); } /// <summary> @@ -44,17 +43,19 @@ namespace UVtools.Core.Extensions /// <param name="xTrans">X translation</param> /// <param name="yTrans">Y translation</param> /// <param name="interpolation">Interpolation mode</param> - public static void ScaleFromCenter(this Mat src, double xScale, double yScale, double xTrans = 0, double yTrans = 0, Inter interpolation = Inter.Linear) + public static void TransformFromCenter(this Mat src, double xScale, double yScale, double xTrans = 0, double yTrans = 0, Inter interpolation = Inter.Linear) { //var dst = new Mat(src.Size, src.Depth, src.NumberOfChannels); - var translateTransform = new Matrix<double>(2, 3) + using (var translateTransform = new Matrix<double>(2, 3) { [0, 0] = xScale, // xScale [1, 1] = yScale, // yScale [0, 2] = xTrans + (src.Width - src.Width * xScale) / 2.0, //x translation + compensation of x scaling [1, 2] = yTrans + (src.Height - src.Height * yScale) / 2.0 // y translation + compensation of y scaling - }; - CvInvoke.WarpAffine(src, src, translateTransform, src.Size, interpolation); + }) + { + CvInvoke.WarpAffine(src, src, translateTransform, src.Size, interpolation); + } } /// <summary> diff --git a/UVtools.Core/Extensions/SpanExtensions.cs b/UVtools.Core/Extensions/SpanExtensions.cs new file mode 100644 index 0000000..0a9ffeb --- /dev/null +++ b/UVtools.Core/Extensions/SpanExtensions.cs @@ -0,0 +1,34 @@ +using System; +using System.Runtime.CompilerServices; +using System.Threading.Tasks; + +namespace UVtools.Core.Extensions +{ + public static class SpanExtensions + { + public static unsafe void Fill<T>(this Span<T> span, Func<T> provider) where T : struct + { + int + cores = Environment.ProcessorCount, + batch = span.Length / cores, + mod = span.Length % cores, + size = Unsafe.SizeOf<T>(); + ref T r0 = ref span.GetPinnableReference(); + fixed (byte* p0 = &Unsafe.As<T, byte>(ref r0)) + { + byte* p = p0; + Parallel.For(0, cores, i => + { + byte* pi = p + i * batch * size; + for (int j = 0; j < batch; j++, pi += size) + Unsafe.Write(pi, provider()); + }); + + // Remaining values + if (mod < 1) return; + for (int i = span.Length - mod; i < span.Length; i++) + Unsafe.Write(p + i * size, provider()); + } + } + } +} |