Browse Source

Update BackgroundColorProcessor{TPixel}.cs

pull/1108/head
James Jackson-South 6 years ago
parent
commit
d7bce16e2a
  1. 109
      src/ImageSharp/Processing/Processors/Overlays/BackgroundColorProcessor{TPixel}.cs

109
src/ImageSharp/Processing/Processors/Overlays/BackgroundColorProcessor{TPixel}.cs

@ -3,6 +3,7 @@
using System; using System;
using System.Buffers; using System.Buffers;
using System.Runtime.CompilerServices;
using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.PixelFormats;
@ -27,9 +28,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Overlays
/// <param name="sourceRectangle">The source area to process for the current processor instance.</param> /// <param name="sourceRectangle">The source area to process for the current processor instance.</param>
public BackgroundColorProcessor(Configuration configuration, BackgroundColorProcessor definition, Image<TPixel> source, Rectangle sourceRectangle) public BackgroundColorProcessor(Configuration configuration, BackgroundColorProcessor definition, Image<TPixel> source, Rectangle sourceRectangle)
: base(configuration, source, sourceRectangle) : base(configuration, source, sourceRectangle)
{ => this.definition = definition;
this.definition = definition;
}
/// <inheritdoc/> /// <inheritdoc/>
protected override void OnFrameApply(ImageFrame<TPixel> source) protected override void OnFrameApply(ImageFrame<TPixel> source)
@ -37,65 +36,69 @@ namespace SixLabors.ImageSharp.Processing.Processors.Overlays
TPixel color = this.definition.Color.ToPixel<TPixel>(); TPixel color = this.definition.Color.ToPixel<TPixel>();
GraphicsOptions graphicsOptions = this.definition.GraphicsOptions; GraphicsOptions graphicsOptions = this.definition.GraphicsOptions;
int startY = this.SourceRectangle.Y; var interest = Rectangle.Intersect(this.SourceRectangle, source.Bounds());
int endY = this.SourceRectangle.Bottom;
int startX = this.SourceRectangle.X;
int endX = this.SourceRectangle.Right;
// Align start/end positions. Configuration configuration = this.Configuration;
int minX = Math.Max(0, startX); MemoryAllocator memoryAllocator = configuration.MemoryAllocator;
int maxX = Math.Min(source.Width, endX);
int minY = Math.Max(0, startY);
int maxY = Math.Min(source.Height, endY);
// Reset offset if necessary. using IMemoryOwner<TPixel> colors = memoryAllocator.Allocate<TPixel>(interest.Width);
if (minX > 0) using IMemoryOwner<float> amount = memoryAllocator.Allocate<float>(interest.Width);
{
startX = 0;
}
if (minY > 0) colors.GetSpan().Fill(color);
{ amount.GetSpan().Fill(graphicsOptions.BlendPercentage);
startY = 0;
}
int width = maxX - minX; PixelBlender<TPixel> blender = PixelOperations<TPixel>.Instance.GetPixelBlender(graphicsOptions);
var workingRect = Rectangle.FromLTRB(minX, minY, maxX, maxY); ParallelRowIterator.IterateRows(
Configuration configuration = this.Configuration; interest,
MemoryAllocator memoryAllocator = configuration.MemoryAllocator; configuration,
new RowIntervalAction(configuration, interest, blender, amount, colors, source));
using (IMemoryOwner<TPixel> colors = memoryAllocator.Allocate<TPixel>(width)) }
using (IMemoryOwner<float> amount = 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();
colorSpan.Fill(color); private readonly struct RowIntervalAction : IRowIntervalAction
amountSpan.Fill(graphicsOptions.BlendPercentage); {
private readonly Configuration configuration;
private readonly Rectangle bounds;
private readonly PixelBlender<TPixel> blender;
private readonly IMemoryOwner<float> amount;
private readonly IMemoryOwner<TPixel> colors;
private readonly ImageFrame<TPixel> source;
PixelBlender<TPixel> blender = PixelOperations<TPixel>.Instance.GetPixelBlender(graphicsOptions); [MethodImpl(InliningOptions.ShortMethod)]
public RowIntervalAction(
Configuration configuration,
Rectangle bounds,
PixelBlender<TPixel> blender,
IMemoryOwner<float> amount,
IMemoryOwner<TPixel> colors,
ImageFrame<TPixel> source)
{
this.configuration = configuration;
this.bounds = bounds;
this.blender = blender;
this.amount = amount;
this.colors = colors;
this.source = source;
}
ParallelRowIterator.IterateRows( [MethodImpl(InliningOptions.ShortMethod)]
workingRect, public void Invoke(in RowInterval rows)
configuration, {
rows => for (int y = rows.Min; y < rows.Max; y++)
{ {
for (int y = rows.Min; y < rows.Max; y++) Span<TPixel> destination =
{ this.source.GetPixelRowSpan(y)
Span<TPixel> destination = .Slice(this.bounds.X, this.bounds.Width);
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 // Switch color & destination in the 2nd and 3rd places because we are
blender.Blend( // applying the target color under the current one.
configuration, this.blender.Blend(
destination, this.configuration,
colors.GetSpan(), destination,
destination, this.colors.GetSpan(),
amount.GetSpan()); destination,
} this.amount.GetSpan());
}); }
} }
} }
} }

Loading…
Cancel
Save