コード例 #1
0
 static void Main(string[] args)
 {
     //ObjectComparison.Do();
     //LazyLoading.Do();
     //Bugfoot.Do();
     ParallelFor.Do();
 }
コード例 #2
0
        /// <inheritdoc/>
        protected override void OnFrameApply(ImageFrame <TPixel> source, ImageFrame <TPixel> destination, Rectangle sourceRectangle, Configuration configuration)
        {
            // Handle resize dimensions identical to the original
            if (source.Width == destination.Width && source.Height == destination.Height && sourceRectangle == this.CropRectangle)
            {
                // the cloned will be blank here copy all the pixel data over
                source.GetPixelSpan().CopyTo(destination.GetPixelSpan());
                return;
            }

            int minY = Math.Max(this.CropRectangle.Y, sourceRectangle.Y);
            int maxY = Math.Min(this.CropRectangle.Bottom, sourceRectangle.Bottom);
            int minX = Math.Max(this.CropRectangle.X, sourceRectangle.X);
            int maxX = Math.Min(this.CropRectangle.Right, sourceRectangle.Right);

            ParallelFor.WithConfiguration(
                minY,
                maxY,
                configuration,
                y =>
            {
                Span <TPixel> sourceRow = source.GetPixelRowSpan(y).Slice(minX);
                Span <TPixel> targetRow = destination.GetPixelRowSpan(y - minY);
                sourceRow.Slice(0, maxX - minX).CopyTo(targetRow);
            });
        }
コード例 #3
0
        /// <summary>
        /// Rotates the image 270 degrees clockwise at the centre point.
        /// </summary>
        /// <param name="source">The source image.</param>
        /// <param name="destination">The destination image.</param>
        /// <param name="configuration">The configuration.</param>
        private void Rotate270(ImageFrame <TPixel> source, ImageFrame <TPixel> destination, Configuration configuration)
        {
            int       width             = source.Width;
            int       height            = source.Height;
            Rectangle destinationBounds = destination.Bounds();

            ParallelFor.WithConfiguration(
                0,
                height,
                configuration,
                y =>
            {
                Span <TPixel> sourceRow = source.GetPixelRowSpan(y);
                for (int x = 0; x < width; x++)
                {
                    int newX = height - y - 1;
                    newX     = height - newX - 1;
                    int newY = width - x - 1;

                    if (destinationBounds.Contains(newX, newY))
                    {
                        destination[newX, newY] = sourceRow[x];
                    }
                }
            });
        }
コード例 #4
0
ファイル: CopyPixels.cs プロジェクト: viktortat/ImageSharp
        public Rgba32 CopyByPixelAccesorSpan()
        {
            using (var source = new Image <Rgba32>(1024, 768))
                using (var target = new Image <Rgba32>(1024, 768))
                {
                    Buffer2D <Rgba32> sourcePixels = source.GetRootFramePixelBuffer();
                    Buffer2D <Rgba32> targetPixels = target.GetRootFramePixelBuffer();
                    ParallelFor.WithConfiguration(
                        0,
                        source.Height,
                        Configuration.Default,
                        y =>
                    {
                        Span <Rgba32> sourceRow = sourcePixels.GetRowSpan(y);
                        Span <Rgba32> targetRow = targetPixels.GetRowSpan(y);

                        for (int x = 0; x < source.Width; x++)
                        {
                            targetRow[x] = sourceRow[x];
                        }
                    });

                    return(targetPixels[0, 0]);
                }
        }
コード例 #5
0
        /// <inheritdoc/>
        protected override void OnFrameApply(ImageFrame <TPixelDst> source, Rectangle sourceRectangle, Configuration configuration)
        {
            Image <TPixelSrc>        targetImage = this.Image;
            PixelBlender <TPixelDst> blender     = this.Blender;
            int locationY = this.Location.Y;

            // Align start/end positions.
            Rectangle bounds = targetImage.Bounds();

            int minX    = Math.Max(this.Location.X, sourceRectangle.X);
            int maxX    = Math.Min(this.Location.X + bounds.Width, sourceRectangle.Width);
            int targetX = minX - this.Location.X;

            int minY = Math.Max(this.Location.Y, sourceRectangle.Y);
            int maxY = Math.Min(this.Location.Y + bounds.Height, sourceRectangle.Bottom);

            int width = maxX - minX;

            MemoryAllocator memoryAllocator = this.Image.GetConfiguration().MemoryAllocator;

            ParallelFor.WithConfiguration(
                minY,
                maxY,
                configuration,
                y =>
            {
                Span <TPixelDst> background = source.GetPixelRowSpan(y).Slice(minX, width);
                Span <TPixelSrc> foreground = targetImage.GetPixelRowSpan(y - locationY).Slice(targetX, width);
                blender.Blend <TPixelSrc>(memoryAllocator, background, background, foreground, this.Opacity);
            });
        }
コード例 #6
0
ファイル: FlipProcessor.cs プロジェクト: viktortat/ImageSharp
        /// <summary>
        /// Swaps the image at the X-axis, which goes horizontally through the middle at half the height of the image.
        /// </summary>
        /// <param name="source">The source image to apply the process to.</param>
        /// <param name="configuration">The configuration.</param>
        private void FlipX(ImageFrame <TPixel> source, Configuration configuration)
        {
            int height     = source.Height;
            int halfHeight = (int)Math.Ceiling(source.Height * .5F);

            using (Buffer2D <TPixel> targetPixels = configuration.MemoryAllocator.Allocate2D <TPixel>(source.Size()))
            {
                ParallelFor.WithConfiguration(
                    0,
                    halfHeight,
                    configuration,
                    y =>
                {
                    int newY = height - y - 1;
                    Span <TPixel> sourceRow    = source.GetPixelRowSpan(y);
                    Span <TPixel> altSourceRow = source.GetPixelRowSpan(newY);
                    Span <TPixel> targetRow    = targetPixels.GetRowSpan(y);
                    Span <TPixel> altTargetRow = targetPixels.GetRowSpan(newY);

                    sourceRow.CopyTo(altTargetRow);
                    altSourceRow.CopyTo(targetRow);
                });

                Buffer2D <TPixel> .SwapOrCopyContent(source.PixelBuffer, targetPixels);
            }
        }
コード例 #7
0
ファイル: FlipProcessor.cs プロジェクト: viktortat/ImageSharp
        /// <summary>
        /// Swaps the image at the Y-axis, which goes vertically through the middle at half of the width of the image.
        /// </summary>
        /// <param name="source">The source image to apply the process to.</param>
        /// <param name="configuration">The configuration.</param>
        private void FlipY(ImageFrame <TPixel> source, Configuration configuration)
        {
            int width     = source.Width;
            int height    = source.Height;
            int halfWidth = (int)Math.Ceiling(width * .5F);

            using (Buffer2D <TPixel> targetPixels = configuration.MemoryAllocator.Allocate2D <TPixel>(source.Size()))
            {
                ParallelFor.WithConfiguration(
                    0,
                    height,
                    configuration,
                    y =>
                {
                    Span <TPixel> sourceRow = source.GetPixelRowSpan(y);
                    Span <TPixel> targetRow = targetPixels.GetRowSpan(y);

                    for (int x = 0; x < halfWidth; x++)
                    {
                        int newX        = width - x - 1;
                        targetRow[x]    = sourceRow[newX];
                        targetRow[newX] = sourceRow[x];
                    }
                });

                Buffer2D <TPixel> .SwapOrCopyContent(source.PixelBuffer, targetPixels);
            }
        }
コード例 #8
0
        /// <inheritdoc/>
        protected override void OnFrameApply(ImageFrame <TPixel> source, Rectangle sourceRectangle, Configuration configuration)
        {
            var       interest = Rectangle.Intersect(sourceRectangle, source.Bounds());
            int       startY   = interest.Y;
            int       endY     = interest.Bottom;
            int       startX   = interest.X;
            int       endX     = interest.Right;
            Matrix4x4 matrix   = this.Matrix;

            ParallelFor.WithConfiguration(
                startY,
                endY,
                configuration,
                y =>
            {
                Span <TPixel> row = source.GetPixelRowSpan(y);

                for (int x = startX; x < endX; x++)
                {
                    ref TPixel pixel = ref row[x];
                    var vector       = Vector4.Transform(pixel.ToVector4(), matrix);
                    pixel.PackFromVector4(vector);
                }
            });
        }
コード例 #9
0
        /// <summary>
        /// Applies the process to the specified portion of the specified <see cref="ImageFrame{TPixel}"/> at the specified location
        /// and with the specified size.
        /// </summary>
        /// <param name="targetPixels">The target pixels to apply the process to.</param>
        /// <param name="sourcePixels">The source pixels. Cannot be null.</param>
        /// <param name="sourceRectangle">
        /// The <see cref="Rectangle"/> structure that specifies the portion of the image object to draw.
        /// </param>
        /// <param name="kernel">The kernel operator.</param>
        /// <param name="configuration">The <see cref="Configuration"/></param>
        private void ApplyConvolution(
            Buffer2D <TPixel> targetPixels,
            Buffer2D <TPixel> sourcePixels,
            Rectangle sourceRectangle,
            DenseMatrix <float> kernel,
            Configuration configuration)
        {
            int kernelHeight = kernel.Rows;
            int kernelWidth  = kernel.Columns;
            int radiusY      = kernelHeight >> 1;
            int radiusX      = kernelWidth >> 1;

            int startY = sourceRectangle.Y;
            int endY   = sourceRectangle.Bottom;
            int startX = sourceRectangle.X;
            int endX   = sourceRectangle.Right;
            int maxY   = endY - 1;
            int maxX   = endX - 1;

            ParallelFor.WithConfiguration(
                startY,
                endY,
                configuration,
                y =>
            {
                Span <TPixel> targetRow = targetPixels.GetRowSpan(y);

                for (int x = startX; x < endX; x++)
                {
                    Vector4 destination = default;

                    // Apply each matrix multiplier to the color components for each pixel.
                    for (int fy = 0; fy < kernelHeight; fy++)
                    {
                        int fyr     = fy - radiusY;
                        int offsetY = y + fyr;

                        offsetY           = offsetY.Clamp(0, maxY);
                        Span <TPixel> row = sourcePixels.GetRowSpan(offsetY);

                        for (int fx = 0; fx < kernelWidth; fx++)
                        {
                            int fxr     = fx - radiusX;
                            int offsetX = x + fxr;

                            offsetX = offsetX.Clamp(0, maxX);

                            Vector4 currentColor = row[offsetX].ToVector4().Premultiply();
                            destination         += kernel[fy, fx] * currentColor;
                        }
                    }

                    ref TPixel pixel = ref targetRow[x];
                    pixel.PackFromVector4(destination.UnPremultiply());
                }
            });
        }
コード例 #10
0
    public static void Explain(this ParallelFor runnable, TextWriter writer)
    {
        writer.WriteLine(@"
- `CpuBound.Compute` contains a quick sort algorithm
- `Parallel.For` is here to divide and conquer compute bound problems faster by applying parallelism
- Operations are scheduled on the worker thread pool
- Multiple arrays of length 5 to 10 will be sorted in parallel
- Parallel.For is a blocking operation
");
    }
コード例 #11
0
        /// <inheritdoc/>
        protected override void OnFrameApply(ImageFrame <TPixel> source, Rectangle sourceRectangle, Configuration configuration)
        {
            int startY = sourceRectangle.Y;
            int endY   = sourceRectangle.Bottom;
            int startX = sourceRectangle.X;
            int endX   = sourceRectangle.Right;

            // Align start/end positions.
            int minX = Math.Max(0, startX);
            int maxX = Math.Min(source.Width, endX);
            int minY = Math.Max(0, startY);
            int maxY = Math.Min(source.Height, endY);

            // Reset offset if necessary.
            if (minX > 0)
            {
                startX = 0;
            }

            if (minY > 0)
            {
                startY = 0;
            }

            int width = maxX - minX;

            using (IMemoryOwner <TPixel> colors = source.MemoryAllocator.Allocate <TPixel>(width))
                using (IMemoryOwner <float> amount = source.MemoryAllocator.Allocate <float>(width))
                {
                    // Be careful! Do not capture colorSpan & amountSpan in the lambda below!
                    Span <TPixel> colorSpan  = colors.GetSpan();
                    Span <float>  amountSpan = amount.GetSpan();

                    // TODO: Use Span.Fill?
                    for (int i = 0; i < width; i++)
                    {
                        colorSpan[i]  = this.Color;
                        amountSpan[i] = this.GraphicsOptions.BlendPercentage;
                    }

                    PixelBlender <TPixel> blender = PixelOperations <TPixel> .Instance.GetPixelBlender(this.GraphicsOptions);

                    ParallelFor.WithConfiguration(
                        minY,
                        maxY,
                        configuration,
                        y =>
                    {
                        Span <TPixel> destination = source.GetPixelRowSpan(y - startY).Slice(minX - startX, width);

                        // This switched color & destination in the 2nd and 3rd places because we are applying the target color under the current one
                        blender.Blend(source.MemoryAllocator, destination, colors.GetSpan(), destination, amount.GetSpan());
                    });
                }
        }
コード例 #12
0
        static void Main(string[] args)
        {
            DataContractSerialization.Start(null);
            BinarySerialization.Start(null);
            XmlSerialization.Start(null);

            Assemblies.Start(null);
            Reflect.Start(null);

            TLS.Start(null);

            Linq.Start(null);

            ParallelInvoke.Start(null);
            ParallelFor.Start(null);
            ParallelForEach.Start(null);
        }
コード例 #13
0
 /// <summary>
 /// Executes a parallel For loop.
 /// </summary>
 /// <param name="start">Loop start index.</param>
 /// <param name="stop">Loop stop index.</param>
 /// <param name="loopBody">Loop body.</param>
 /// <remarks>The method is used to parallelise for loop by running iterations across
 /// several threads.
 /// Example usage:
 /// <code>
 /// for ( int i = 0; i &lt; 10; i++ )
 /// {
 ///   System.Diagnostics.Debug.WriteLine( "i = " + i );
 /// }
 /// </code>
 /// can be replaced by:
 /// <code>
 /// Parallel.For( 0, 10, delegate( int i )
 /// {
 ///   System.Diagnostics.Debug.WriteLine( "i = " + i );
 /// } );
 /// </code>
 /// If <c>Parallel.ThreadCount</c> is exactly <c>1</c>, no threads are spawned.
 /// </remarks>
 public static void For(int start, int stop, ParallelFor.ForLoopDelegate loopBody)
 {
     if (Parallel.threadCount == 1)
     {
         for (int i = start; i < stop; i++)
         {
             loopBody(i);
         }
     }
     else
     {
         lock (lockObject) {
             ParallelFor parallel = ParallelFor.GetInstance(threadCount);
             parallel.DoFor(start, stop, loopBody);
         }
     }
 }
コード例 #14
0
 /// <summary>
 /// Get instance of the ParallelFor class for singleton pattern and
 /// update the number of threads if appropriate.
 /// </summary>
 /// <param name="threadCount">The thread count.</param>
 /// <returns></returns>
 public static ParallelFor GetInstance(int threadCount)
 {
     if (instance == null)
     {
         instance             = new ParallelFor();
         instance.threadCount = threadCount;
         instance.Initialize();
     }
     else
     {
         // Ensure we have the correct number of threads.
         if (instance.workerThreads.Count != threadCount)
         {
             instance.Terminate();
             instance.threadCount = threadCount;
             instance.Initialize();
         }
     }
     return(instance);
 }
コード例 #15
0
        /// <summary>
        /// Rotates the image 180 degrees clockwise at the centre point.
        /// </summary>
        /// <param name="source">The source image.</param>
        /// <param name="destination">The destination image.</param>
        /// <param name="configuration">The configuration.</param>
        private void Rotate180(ImageFrame <TPixel> source, ImageFrame <TPixel> destination, Configuration configuration)
        {
            int width  = source.Width;
            int height = source.Height;

            ParallelFor.WithConfiguration(
                0,
                height,
                configuration,
                y =>
            {
                Span <TPixel> sourceRow = source.GetPixelRowSpan(y);
                Span <TPixel> targetRow = destination.GetPixelRowSpan(height - y - 1);

                for (int x = 0; x < width; x++)
                {
                    targetRow[width - x - 1] = sourceRow[x];
                }
            });
        }
コード例 #16
0
ファイル: CopyPixels.cs プロジェクト: viktortat/ImageSharp
        public Rgba32 Copy()
        {
            using (var source = new Image <Rgba32>(1024, 768))
                using (var target = new Image <Rgba32>(1024, 768))
                {
                    ParallelFor.WithConfiguration(
                        0,
                        source.Height,
                        Configuration.Default,
                        y =>
                    {
                        for (int x = 0; x < source.Width; x++)
                        {
                            target[x, y] = source[x, y];
                        }
                    });

                    return(target[0, 0]);
                }
        }
コード例 #17
0
ファイル: Program.cs プロジェクト: Ahura007/loop
        static void Main(string[] args)
        {
            var           someData = Enumerable.Range(0, 1000000000).ToList();
            StringBuilder sb       = new StringBuilder();

            sb.Append("for Property             " + For.Property(someData) + Environment.NewLine);
            sb.Append("for Variable             " + For.Variable(someData.Count) + Environment.NewLine);

            sb.Append("parallel For Property    " + ParallelFor.Property(someData) + Environment.NewLine);
            sb.Append("parallel For Variable    " + ParallelFor.Variable(someData.Count) + Environment.NewLine);

            sb.Append("while Variable           " + While.Variable(someData.Count) + Environment.NewLine);
            sb.Append("while Property           " + While.Property(someData) + Environment.NewLine);

            sb.Append("do While Variable        " + DoWhile.Variable(someData.Count) + Environment.NewLine);
            sb.Append("do While Property        " + DoWhile.Property(someData) + Environment.NewLine);

            sb.Append("foreach A                " + Foreach.Test(someData) + Environment.NewLine);
            sb.Append("foreach B                " + Foreach.BasicTestOne(someData) + Environment.NewLine);
            sb.Append("foreach C                " + Foreach.BasicTestTwo(someData) + Environment.NewLine);

            sb.Append("parallel Foreach         " + ParallelForEach.Test(someData) + Environment.NewLine);

            sb.Append("foreach Linq A           " + ForeachLinq.Test(someData) + Environment.NewLine);
            sb.Append("foreach Linq B           " + ForeachLinq.BasicForEach(someData) + Environment.NewLine);


            System.IO.File.WriteAllText(Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\loop.txt", sb.ToString());



            //set break point in CustomEnumerator method and debug
            var list = new CustomEnumerator();

            foreach (Person item in list)
            {
            }


            Console.ReadLine();
        }
コード例 #18
0
ファイル: CopyPixels.cs プロジェクト: viktortat/ImageSharp
        public Rgba32 CopySpan()
        {
            using (var source = new Image <Rgba32>(1024, 768))
                using (var target = new Image <Rgba32>(1024, 768))
                {
                    ParallelFor.WithConfiguration(
                        0,
                        source.Height,
                        Configuration.Default,
                        y =>
                    {
                        Span <Rgba32> sourceRow = source.Frames.RootFrame.GetPixelRowSpan(y);
                        Span <Rgba32> targetRow = target.Frames.RootFrame.GetPixelRowSpan(y);

                        for (int x = 0; x < source.Width; x++)
                        {
                            targetRow[x] = sourceRow[x];
                        }
                    });

                    return(target[0, 0]);
                }
        }
コード例 #19
0
 /// <summary>
 /// Executes a parallel For loop.
 /// </summary>
 /// <param name="start">Loop start index.</param>
 /// <param name="stop">Loop stop index.</param>
 /// <param name="loopBody">Loop body.</param>
 /// <param name="cancellationToken">Used to signal if the user wishes to cancel the loop before it completes.</param>
 /// <remarks>The method is used to parallelise for loop by running iterations across
 /// several threads.
 /// Example usage:
 /// <code>
 /// for ( int i = 0; i &lt; 10; i++ )
 /// {
 ///   System.Diagnostics.Debug.WriteLine( "i = " + i );
 /// }
 /// </code>
 /// can be replaced by:
 /// <code>
 /// Parallel.For( 0, 10, delegate( int i )
 /// {
 ///   System.Diagnostics.Debug.WriteLine( "i = " + i );
 /// } );
 /// </code>
 /// If <c>Parallel.ThreadCount</c> is exactly <c>1</c>, no threads are spawned.
 /// </remarks>
 public static void For(int start, int stop, [NotNull, InstantHandle] Action <int> loopBody, CancellationToken cancellationToken = default(CancellationToken))
 {
     if (loopBody == null)
     {
         throw new ArgumentNullException("loopBody");
     }
     if (Parallel.threadCount == 1)
     {
         for (int i = start; i < stop; i++)
         {
             loopBody(i);
             cancellationToken.ThrowIfCancellationRequested();
         }
     }
     else
     {
         lock (lockObject)
         {
             ParallelFor parallel = ParallelFor.GetInstance(threadCount);
             parallel.DoFor(start, stop, loopBody, cancellationToken);
             cancellationToken.ThrowIfCancellationRequested();
         }
     }
 }
コード例 #20
0
        /// <inheritdoc/>
        protected override void OnFrameApply(ImageFrame <TPixel> source, Rectangle sourceRectangle, Configuration configuration)
        {
            float  threshold = this.Threshold * 255F;
            TPixel upper     = this.UpperColor;
            TPixel lower     = this.LowerColor;

            var interest = Rectangle.Intersect(sourceRectangle, source.Bounds());
            int startY   = interest.Y;
            int endY     = interest.Bottom;
            int startX   = interest.X;
            int endX     = interest.Right;

            bool isAlphaOnly = typeof(TPixel) == typeof(Alpha8);

            ParallelFor.WithConfiguration(
                startY,
                endY,
                configuration,
                y =>
            {
                Span <TPixel> row = source.GetPixelRowSpan(y);
                Rgba32 rgba       = default;

                for (int x = startX; x < endX; x++)
                {
                    ref TPixel color = ref row[x];
                    color.ToRgba32(ref rgba);

                    // Convert to grayscale using ITU-R Recommendation BT.709 if required
                    float luminance = isAlphaOnly
                                                  ? rgba.A
                                                  : (.2126F * rgba.R) + (.7152F * rgba.G) + (.0722F * rgba.B);
                    color = luminance >= threshold ? upper : lower;
                }
            });
        }
コード例 #21
0
        /// <inheritdoc/>
        protected override void OnFrameApply(ImageFrame <TPixel> source, Rectangle sourceRectangle, Configuration configuration)
        {
            int startX = sourceRectangle.X;
            int endX   = sourceRectangle.Right;
            int startY = sourceRectangle.Y;
            int endY   = sourceRectangle.Bottom;

            // Align start/end positions.
            int minX = Math.Max(0, startX);
            int maxX = Math.Min(source.Width, endX);
            int minY = Math.Max(0, startY);
            int maxY = Math.Min(source.Height, endY);

            int width = maxX - minX;

            // If there's no reason for blending, then avoid it.
            if (this.IsSolidBrushWithoutBlending(out SolidBrush <TPixel> solidBrush))
            {
                ParallelFor.WithConfiguration(
                    minY,
                    maxY,
                    configuration,
                    y =>
                {
                    source.GetPixelRowSpan(y).Slice(minX, width).Fill(solidBrush.Color);
                });
            }
            else
            {
                // Reset offset if necessary.
                if (minX > 0)
                {
                    startX = 0;
                }

                if (minY > 0)
                {
                    startY = 0;
                }

                using (IMemoryOwner <float> amount = source.MemoryAllocator.Allocate <float>(width))
                    using (BrushApplicator <TPixel> applicator = this.brush.CreateApplicator(
                               source,
                               sourceRectangle,
                               this.options))
                    {
                        amount.GetSpan().Fill(1f);

                        ParallelFor.WithConfiguration(
                            minY,
                            maxY,
                            configuration,
                            y =>
                        {
                            int offsetY = y - startY;
                            int offsetX = minX - startX;

                            applicator.Apply(amount.GetSpan(), offsetX, offsetY);
                        });
                    }
            }
        }
コード例 #22
0
ファイル: Glow.cs プロジェクト: viktortat/ImageSharp
            /// <inheritdoc/>
            protected override void OnFrameApply(
                ImageFrame <TPixel> source,
                Rectangle sourceRectangle,
                Configuration configuration)
            {
                int     startY      = sourceRectangle.Y;
                int     endY        = sourceRectangle.Bottom;
                int     startX      = sourceRectangle.X;
                int     endX        = sourceRectangle.Right;
                TPixel  glowColor   = this.GlowColor;
                Vector2 centre      = Rectangle.Center(sourceRectangle);
                float   maxDistance = this.Radius > 0
                                        ? Math.Min(this.Radius, sourceRectangle.Width * .5F)
                                        : sourceRectangle.Width * .5F;

                // Align start/end positions.
                int minX = Math.Max(0, startX);
                int maxX = Math.Min(source.Width, endX);
                int minY = Math.Max(0, startY);
                int maxY = Math.Min(source.Height, endY);

                // Reset offset if necessary.
                if (minX > 0)
                {
                    startX = 0;
                }

                if (minY > 0)
                {
                    startY = 0;
                }

                int width = maxX - minX;

                using (IMemoryOwner <TPixel> rowColors = Configuration.Default.MemoryAllocator.Allocate <TPixel>(width))
                {
                    Buffer2D <TPixel> sourcePixels = source.PixelBuffer;
                    rowColors.GetSpan().Fill(glowColor);

                    ParallelFor.WithConfiguration(
                        minY,
                        maxY,
                        configuration,
                        y =>
                    {
                        int offsetY = y - startY;

                        for (int x = minX; x < maxX; x++)
                        {
                            int offsetX         = x - startX;
                            float distance      = Vector2.Distance(centre, new Vector2(offsetX, offsetY));
                            Vector4 sourceColor = sourcePixels[offsetX, offsetY].ToVector4();
                            TPixel packed       = default(TPixel);
                            packed.PackFromVector4(
                                PremultipliedLerp(
                                    sourceColor,
                                    glowColor.ToVector4(),
                                    1 - (.95F * (distance / maxDistance))));
                            sourcePixels[offsetX, offsetY] = packed;
                        }
                    });
                }
            }
コード例 #23
0
        /// <inheritdoc />
        protected override void OnFrameApply(ImageFrame <TPixel> source, Rectangle sourceRectangle, Configuration configuration)
        {
            DenseMatrix <float>[] kernels = { this.North, this.NorthWest, this.West, this.SouthWest, this.South, this.SouthEast, this.East, this.NorthEast };

            int startY = sourceRectangle.Y;
            int endY   = sourceRectangle.Bottom;
            int startX = sourceRectangle.X;
            int endX   = sourceRectangle.Right;

            // Align start/end positions.
            int minX = Math.Max(0, startX);
            int maxX = Math.Min(source.Width, endX);
            int minY = Math.Max(0, startY);
            int maxY = Math.Min(source.Height, endY);

            // we need a clean copy for each pass to start from
            using (ImageFrame <TPixel> cleanCopy = source.Clone())
            {
                new ConvolutionProcessor <TPixel>(kernels[0]).Apply(source, sourceRectangle, configuration);

                if (kernels.Length == 1)
                {
                    return;
                }

                int shiftY = startY;
                int shiftX = startX;

                // Reset offset if necessary.
                if (minX > 0)
                {
                    shiftX = 0;
                }

                if (minY > 0)
                {
                    shiftY = 0;
                }

                // Additional runs.
                // ReSharper disable once ForCanBeConvertedToForeach
                for (int i = 1; i < kernels.Length; i++)
                {
                    using (ImageFrame <TPixel> pass = cleanCopy.Clone())
                    {
                        new ConvolutionProcessor <TPixel>(kernels[i]).Apply(pass, sourceRectangle, configuration);

                        Buffer2D <TPixel> passPixels   = pass.PixelBuffer;
                        Buffer2D <TPixel> targetPixels = source.PixelBuffer;

                        ParallelFor.WithConfiguration(
                            minY,
                            maxY,
                            configuration,
                            y =>
                        {
                            int offsetY = y - shiftY;

                            ref TPixel passPixelsBase   = ref MemoryMarshal.GetReference(passPixels.GetRowSpan(offsetY));
                            ref TPixel targetPixelsBase = ref MemoryMarshal.GetReference(targetPixels.GetRowSpan(offsetY));

                            for (int x = minX; x < maxX; x++)
                            {
                                int offsetX = x - shiftX;

                                // Grab the max components of the two pixels
                                ref TPixel currentPassPixel   = ref Unsafe.Add(ref passPixelsBase, offsetX);
                                ref TPixel currentTargetPixel = ref Unsafe.Add(ref targetPixelsBase, offsetX);

                                var pixelValue = Vector4.Max(
                                    currentPassPixel.ToVector4(),
                                    currentTargetPixel.ToVector4());

                                currentTargetPixel.PackFromVector4(pixelValue);
                            }
                        });
コード例 #24
0
        /// <inheritdoc/>
        protected override void OnFrameApply(
            ImageFrame <TPixel> source,
            ImageFrame <TPixel> destination,
            Rectangle sourceRectangle,
            Configuration configuration)
        {
            int height = this.TargetDimensions.Height;
            int width  = this.TargetDimensions.Width;

            Rectangle sourceBounds = source.Bounds();
            var       targetBounds = new Rectangle(0, 0, width, height);

            // Since could potentially be resizing the canvas we might need to re-calculate the matrix
            Matrix3x2 matrix = this.GetProcessingMatrix(sourceBounds, targetBounds);

            // Convert from screen to world space.
            Matrix3x2.Invert(matrix, out matrix);

            if (this.Sampler is NearestNeighborResampler)
            {
                ParallelFor.WithConfiguration(
                    0,
                    height,
                    configuration,
                    y =>
                {
                    Span <TPixel> destRow = destination.GetPixelRowSpan(y);

                    for (int x = 0; x < width; x++)
                    {
                        var point = Point.Transform(new Point(x, y), matrix);
                        if (sourceBounds.Contains(point.X, point.Y))
                        {
                            destRow[x] = source[point.X, point.Y];
                        }
                    }
                });

                return;
            }

            int maxSourceX = source.Width - 1;
            int maxSourceY = source.Height - 1;

            (float radius, float scale, float ratio)xRadiusScale = this.GetSamplingRadius(source.Width, destination.Width);
            (float radius, float scale, float ratio)yRadiusScale = this.GetSamplingRadius(source.Height, destination.Height);
            float      xScale    = xRadiusScale.scale;
            float      yScale    = yRadiusScale.scale;
            var        radius    = new Vector2(xRadiusScale.radius, yRadiusScale.radius);
            IResampler sampler   = this.Sampler;
            var        maxSource = new Vector4(maxSourceX, maxSourceY, maxSourceX, maxSourceY);
            int        xLength   = (int)MathF.Ceiling((radius.X * 2) + 2);
            int        yLength   = (int)MathF.Ceiling((radius.Y * 2) + 2);

            MemoryAllocator memoryAllocator = configuration.MemoryAllocator;

            using (Buffer2D <float> yBuffer = memoryAllocator.Allocate2D <float>(yLength, height))
                using (Buffer2D <float> xBuffer = memoryAllocator.Allocate2D <float>(xLength, height))
                {
                    ParallelFor.WithConfiguration(
                        0,
                        height,
                        configuration,
                        y =>
                    {
                        ref TPixel destRowRef = ref MemoryMarshal.GetReference(destination.GetPixelRowSpan(y));
                        ref float ySpanRef    = ref MemoryMarshal.GetReference(yBuffer.GetRowSpan(y));
                        ref float xSpanRef    = ref MemoryMarshal.GetReference(xBuffer.GetRowSpan(y));
コード例 #25
0
        /// <inheritdoc/>
        protected override void OnFrameApply(ImageFrame <TPixel> source, Rectangle sourceRectangle, Configuration configuration)
        {
            if (this.BrushSize <= 0 || this.BrushSize > source.Height || this.BrushSize > source.Width)
            {
                throw new ArgumentOutOfRangeException(nameof(this.BrushSize));
            }

            int startY = sourceRectangle.Y;
            int endY   = sourceRectangle.Bottom;
            int startX = sourceRectangle.X;
            int endX   = sourceRectangle.Right;
            int maxY   = endY - 1;
            int maxX   = endX - 1;

            int radius = this.BrushSize >> 1;
            int levels = this.Levels;

            using (Buffer2D <TPixel> targetPixels = configuration.MemoryAllocator.Allocate2D <TPixel>(source.Size()))
            {
                source.CopyTo(targetPixels);

                ParallelFor.WithConfiguration(
                    startY,
                    maxY,
                    configuration,
                    y =>
                {
                    Span <TPixel> sourceRow = source.GetPixelRowSpan(y);
                    Span <TPixel> targetRow = targetPixels.GetRowSpan(y);

                    for (int x = startX; x < endX; x++)
                    {
                        int maxIntensity = 0;
                        int maxIndex     = 0;

                        int[] intensityBin = new int[levels];
                        float[] redBin     = new float[levels];
                        float[] blueBin    = new float[levels];
                        float[] greenBin   = new float[levels];

                        for (int fy = 0; fy <= radius; fy++)
                        {
                            int fyr     = fy - radius;
                            int offsetY = y + fyr;

                            offsetY = offsetY.Clamp(0, maxY);

                            Span <TPixel> sourceOffsetRow = source.GetPixelRowSpan(offsetY);

                            for (int fx = 0; fx <= radius; fx++)
                            {
                                int fxr     = fx - radius;
                                int offsetX = x + fxr;
                                offsetX     = offsetX.Clamp(0, maxX);

                                var vector = sourceOffsetRow[offsetX].ToVector4();

                                float sourceRed   = vector.X;
                                float sourceBlue  = vector.Z;
                                float sourceGreen = vector.Y;

                                int currentIntensity = (int)MathF.Round((sourceBlue + sourceGreen + sourceRed) / 3F * (levels - 1));

                                intensityBin[currentIntensity]++;
                                blueBin[currentIntensity]  += sourceBlue;
                                greenBin[currentIntensity] += sourceGreen;
                                redBin[currentIntensity]   += sourceRed;

                                if (intensityBin[currentIntensity] > maxIntensity)
                                {
                                    maxIntensity = intensityBin[currentIntensity];
                                    maxIndex     = currentIntensity;
                                }
                            }

                            float red   = MathF.Abs(redBin[maxIndex] / maxIntensity);
                            float green = MathF.Abs(greenBin[maxIndex] / maxIntensity);
                            float blue  = MathF.Abs(blueBin[maxIndex] / maxIntensity);

                            ref TPixel pixel = ref targetRow[x];
                            pixel.PackFromVector4(new Vector4(red, green, blue, sourceRow[x].ToVector4().W));
                        }
                    }
                });

                Buffer2D <TPixel> .SwapOrCopyContent(source.PixelBuffer, targetPixels);
            }
        }
コード例 #26
0
ファイル: GlowProcessor.cs プロジェクト: viktortat/ImageSharp
        /// <inheritdoc/>
        protected override void OnFrameApply(ImageFrame <TPixel> source, Rectangle sourceRectangle, Configuration configuration)
        {
            int     startY    = sourceRectangle.Y;
            int     endY      = sourceRectangle.Bottom;
            int     startX    = sourceRectangle.X;
            int     endX      = sourceRectangle.Right;
            TPixel  glowColor = this.GlowColor;
            Vector2 center    = Rectangle.Center(sourceRectangle);

            float finalRadius = this.Radius.Calculate(source.Size());

            float maxDistance = finalRadius > 0 ? MathF.Min(finalRadius, sourceRectangle.Width * .5F) : sourceRectangle.Width * .5F;

            // Align start/end positions.
            int minX = Math.Max(0, startX);
            int maxX = Math.Min(source.Width, endX);
            int minY = Math.Max(0, startY);
            int maxY = Math.Min(source.Height, endY);

            // Reset offset if necessary.
            if (minX > 0)
            {
                startX = 0;
            }

            if (minY > 0)
            {
                startY = 0;
            }

            int width = maxX - minX;

            using (IMemoryOwner <TPixel> rowColors = source.MemoryAllocator.Allocate <TPixel>(width))
            {
                // Be careful! Do not capture rowColorsSpan in the lambda below!
                Span <TPixel> rowColorsSpan = rowColors.GetSpan();

                for (int i = 0; i < width; i++)
                {
                    rowColorsSpan[i] = glowColor;
                }

                ParallelFor.WithTemporaryBuffer <float>(
                    minY,
                    maxY,
                    configuration,
                    width,
                    (y, amounts) =>
                {
                    Span <float> amountsSpan = amounts.GetSpan();
                    int offsetY = y - startY;
                    int offsetX = minX - startX;
                    for (int i = 0; i < width; i++)
                    {
                        float distance = Vector2.Distance(center, new Vector2(i + offsetX, offsetY));
                        amountsSpan[i] = (this.GraphicsOptions.BlendPercentage * (1 - (.95F * (distance / maxDistance)))).Clamp(0, 1);
                    }

                    Span <TPixel> destination = source.GetPixelRowSpan(offsetY).Slice(offsetX, width);

                    this.blender.Blend(source.MemoryAllocator, destination, destination, rowColors.GetSpan(), amountsSpan);
                });
            }
        }
コード例 #27
0
        /// <inheritdoc/>
        protected override void OnFrameApply(ImageFrame <TPixel> source, Rectangle sourceRectangle, Configuration configuration)
        {
            int kernelLength = this.KernelXY.Rows;
            int radius       = kernelLength >> 1;

            int startY = sourceRectangle.Y;
            int endY   = sourceRectangle.Bottom;
            int startX = sourceRectangle.X;
            int endX   = sourceRectangle.Right;
            int maxY   = endY - 1;
            int maxX   = endX - 1;

            using (Buffer2D <TPixel> targetPixels = configuration.MemoryAllocator.Allocate2D <TPixel>(source.Size()))
            {
                source.CopyTo(targetPixels);

                ParallelFor.WithConfiguration(
                    startY,
                    endY,
                    configuration,
                    y =>
                {
                    Span <TPixel> sourceRow = source.GetPixelRowSpan(y);
                    Span <TPixel> targetRow = targetPixels.GetRowSpan(y);

                    for (int x = startX; x < endX; x++)
                    {
                        float red   = 0;
                        float green = 0;
                        float blue  = 0;

                        // Apply each matrix multiplier to the color components for each pixel.
                        for (int fy = 0; fy < kernelLength; fy++)
                        {
                            int fyr     = fy - radius;
                            int offsetY = y + fyr;

                            offsetY = offsetY.Clamp(0, maxY);
                            Span <TPixel> sourceOffsetRow = source.GetPixelRowSpan(offsetY);

                            for (int fx = 0; fx < kernelLength; fx++)
                            {
                                int fxr     = fx - radius;
                                int offsetX = x + fxr;

                                offsetX = offsetX.Clamp(0, maxX);

                                Vector4 currentColor = sourceOffsetRow[offsetX].ToVector4().Premultiply();
                                currentColor        *= this.KernelXY[fy, fx];

                                red   += currentColor.X;
                                green += currentColor.Y;
                                blue  += currentColor.Z;
                            }
                        }

                        ref TPixel pixel = ref targetRow[x];
                        pixel.PackFromVector4(new Vector4(red, green, blue, sourceRow[x].ToVector4().W).UnPremultiply());
                    }
                });

                Buffer2D <TPixel> .SwapOrCopyContent(source.PixelBuffer, targetPixels);
            }
        }
コード例 #28
0
 public Worker(ParallelFor p, byte index)
 {
     this.source      = p;
     this.threadIndex = index;
 }
コード例 #29
0
        /// <inheritdoc/>
        protected override void OnFrameApply(ImageFrame <TPixel> source, Rectangle sourceRectangle, Configuration configuration)
        {
            int kernelYHeight = this.KernelY.Rows;
            int kernelYWidth  = this.KernelY.Columns;
            int kernelXHeight = this.KernelX.Rows;
            int kernelXWidth  = this.KernelX.Columns;
            int radiusY       = kernelYHeight >> 1;
            int radiusX       = kernelXWidth >> 1;

            int startY = sourceRectangle.Y;
            int endY   = sourceRectangle.Bottom;
            int startX = sourceRectangle.X;
            int endX   = sourceRectangle.Right;
            int maxY   = endY - 1;
            int maxX   = endX - 1;

            using (Buffer2D <TPixel> targetPixels = configuration.MemoryAllocator.Allocate2D <TPixel>(source.Width, source.Height))
            {
                source.CopyTo(targetPixels);

                ParallelFor.WithConfiguration(
                    startY,
                    endY,
                    configuration,
                    y =>
                {
                    Span <TPixel> sourceRow = source.GetPixelRowSpan(y);
                    Span <TPixel> targetRow = targetPixels.GetRowSpan(y);

                    for (int x = startX; x < endX; x++)
                    {
                        float rX = 0;
                        float gX = 0;
                        float bX = 0;
                        float rY = 0;
                        float gY = 0;
                        float bY = 0;

                        // Apply each matrix multiplier to the color components for each pixel.
                        for (int fy = 0; fy < kernelYHeight; fy++)
                        {
                            int fyr     = fy - radiusY;
                            int offsetY = y + fyr;

                            offsetY = offsetY.Clamp(0, maxY);
                            Span <TPixel> sourceOffsetRow = source.GetPixelRowSpan(offsetY);

                            for (int fx = 0; fx < kernelXWidth; fx++)
                            {
                                int fxr     = fx - radiusX;
                                int offsetX = x + fxr;

                                offsetX = offsetX.Clamp(0, maxX);
                                Vector4 currentColor = sourceOffsetRow[offsetX].ToVector4().Premultiply();

                                if (fy < kernelXHeight)
                                {
                                    Vector4 kx = this.KernelX[fy, fx] * currentColor;
                                    rX        += kx.X;
                                    gX        += kx.Y;
                                    bX        += kx.Z;
                                }

                                if (fx < kernelYWidth)
                                {
                                    Vector4 ky = this.KernelY[fy, fx] * currentColor;
                                    rY        += ky.X;
                                    gY        += ky.Y;
                                    bY        += ky.Z;
                                }
                            }
                        }

                        float red   = MathF.Sqrt((rX * rX) + (rY * rY));
                        float green = MathF.Sqrt((gX * gX) + (gY * gY));
                        float blue  = MathF.Sqrt((bX * bX) + (bY * bY));

                        ref TPixel pixel = ref targetRow[x];
                        pixel.PackFromVector4(new Vector4(red, green, blue, sourceRow[x].ToVector4().W).UnPremultiply());
                    }
                });

                Buffer2D <TPixel> .SwapOrCopyContent(source.PixelBuffer, targetPixels);
            }
        }