コード例 #1
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);
                });
            }
        }