Beispiel #1
0
            /// <summary>
            /// Initializes a new instance of the <see cref="RecolorBrushApplicator{TPixel}" /> class.
            /// </summary>
            /// <param name="configuration">The configuration instance to use when performing operations.</param>
            /// <param name="options">The options</param>
            /// <param name="source">The source image.</param>
            /// <param name="sourceColor">Color of the source.</param>
            /// <param name="targetColor">Color of the target.</param>
            /// <param name="threshold">The threshold .</param>
            public RecolorBrushApplicator(
                Configuration configuration,
                GraphicsOptions options,
                ImageFrame <TPixel> source,
                TPixel sourceColor,
                TPixel targetColor,
                float threshold)
                : base(configuration, options, source)
            {
                this.sourceColor      = sourceColor.ToVector4();
                this.targetColorPixel = targetColor;

                // Lets hack a min max extremes for a color space by letting the IPackedPixel clamp our values to something in the correct spaces :)
                var maxColor = default(TPixel);

                maxColor.FromVector4(new Vector4(float.MaxValue));
                var minColor = default(TPixel);

                minColor.FromVector4(new Vector4(float.MinValue));
                this.threshold = Vector4.DistanceSquared(maxColor.ToVector4(), minColor.ToVector4()) * threshold;

                this.scalineWidth   = source.Width;
                this.allocator      = configuration.MemoryAllocator;
                this.blenderBuffers = new ThreadLocalBlenderBuffers <TPixel>(configuration.MemoryAllocator, source.Width);
            }
Beispiel #2
0
        public void Dispose_ReturnsAllBuffers(bool amountBufferOnly, int threadCount)
        {
            var buffers = new ThreadLocalBlenderBuffers <Rgb24>(this.memoryAllocator, 100, amountBufferOnly);

            void RunThread()
            {
                buffers.AmountSpan[0] = 42;
            }

            Thread[] threads = new Thread[threadCount];
            for (int i = 0; i < threadCount; i++)
            {
                threads[i] = new Thread(RunThread);
                threads[i].Start();
            }

            foreach (Thread thread in threads)
            {
                thread.Join();
            }

            buffers.Dispose();

            int expectedReturnCount = amountBufferOnly ? threadCount : 2 * threadCount;

            Assert.Equal(expectedReturnCount, this.memoryAllocator.ReturnLog.Count);
        }
Beispiel #3
0
            /// <summary>
            /// Initializes a new instance of the <see cref="SolidBrushApplicator{TPixel}"/> class.
            /// </summary>
            /// <param name="configuration">The configuration instance to use when performing operations.</param>
            /// <param name="options">The graphics options.</param>
            /// <param name="source">The source image.</param>
            /// <param name="color">The color.</param>
            public SolidBrushApplicator(
                Configuration configuration,
                GraphicsOptions options,
                ImageFrame <TPixel> source,
                TPixel color)
                : base(configuration, options, source)
            {
                this.colors = configuration.MemoryAllocator.Allocate <TPixel>(source.Width);
                this.colors.Memory.Span.Fill(color);
                this.scalineWidth = source.Width;
                this.allocator    = configuration.MemoryAllocator;

                // The threadlocal value is lazily invoked so there is no need to optionally create the type.
                this.blenderBuffers = new ThreadLocalBlenderBuffers <TPixel>(configuration.MemoryAllocator, source.Width, true);
            }
Beispiel #4
0
 /// <summary>
 /// Initializes a new instance of the <see cref="GradientBrushApplicator{TPixel}"/> class.
 /// </summary>
 /// <param name="configuration">The configuration instance to use when performing operations.</param>
 /// <param name="options">The graphics options.</param>
 /// <param name="target">The target image.</param>
 /// <param name="colorStops">An array of color stops sorted by their position.</param>
 /// <param name="repetitionMode">Defines if and how the gradient should be repeated.</param>
 protected GradientBrushApplicator(
     Configuration configuration,
     GraphicsOptions options,
     ImageFrame <TPixel> target,
     ColorStop[] colorStops,
     GradientRepetitionMode repetitionMode)
     : base(configuration, options, target)
 {
     // TODO: requires colorStops to be sorted by position.
     // Use Array.Sort with a custom comparer.
     this.colorStops     = colorStops;
     this.repetitionMode = repetitionMode;
     this.scalineWidth   = target.Width;
     this.allocator      = configuration.MemoryAllocator;
     this.blenderBuffers = new ThreadLocalBlenderBuffers <TPixel>(this.allocator, this.scalineWidth);
 }
Beispiel #5
0
            /// <summary>
            /// Initializes a new instance of the <see cref="PathGradientBrushApplicator{TPixel}"/> class.
            /// </summary>
            /// <param name="configuration">The configuration instance to use when performing operations.</param>
            /// <param name="options">The graphics options.</param>
            /// <param name="source">The source image.</param>
            /// <param name="edges">Edges of the polygon.</param>
            /// <param name="centerColor">Color at the center of the gradient area to which the other colors converge.</param>
            /// <param name="hasSpecialCenterColor">Whether the center color is different from a smooth gradient between the edges.</param>
            public PathGradientBrushApplicator(
                Configuration configuration,
                GraphicsOptions options,
                ImageFrame <TPixel> source,
                IList <Edge> edges,
                Color centerColor,
                bool hasSpecialCenterColor)
                : base(configuration, options, source)
            {
                this.edges = edges;
                Vector2[] points = edges.Select(s => s.Start).ToArray();

                this.center                = points.Aggregate((p1, p2) => p1 + p2) / edges.Count;
                this.centerColor           = (Vector4)centerColor;
                this.hasSpecialCenterColor = hasSpecialCenterColor;
                this.centerPixel           = centerColor.ToPixel <TPixel>();
                this.maxDistance           = points.Select(p => p - this.center).Max(d => d.Length());
                this.transparentPixel      = Color.Transparent.ToPixel <TPixel>();
                this.blenderBuffers        = new ThreadLocalBlenderBuffers <TPixel>(configuration.MemoryAllocator, source.Width);
            }
Beispiel #6
0
        public void CreatesPerThreadUniqueInstances()
        {
            using var buffers = new ThreadLocalBlenderBuffers <Rgb24>(this.memoryAllocator, 100);

            var allSetSemaphore = new SemaphoreSlim(2);

            var thread1 = new Thread(() =>
            {
                Span <float> ams      = buffers.AmountSpan;
                Span <Rgb24> overlays = buffers.OverlaySpan;

                ams[0]      = 10;
                overlays[0] = new Rgb24(10, 10, 10);

                allSetSemaphore.Release(1);
                allSetSemaphore.Wait();

                Assert.Equal(10, buffers.AmountSpan[0]);
                Assert.Equal(10, buffers.OverlaySpan[0].R);
            });

            var thread2 = new Thread(() =>
            {
                Span <float> ams      = buffers.AmountSpan;
                Span <Rgb24> overlays = buffers.OverlaySpan;

                ams[0]      = 20;
                overlays[0] = new Rgb24(20, 20, 20);

                allSetSemaphore.Release(1);
                allSetSemaphore.Wait();

                Assert.Equal(20, buffers.AmountSpan[0]);
                Assert.Equal(20, buffers.OverlaySpan[0].R);
            });

            thread1.Start();
            thread2.Start();
            thread1.Join();
            thread2.Join();
        }