Browse Source

Update BackgroundColorProcessor{TPixel}.cs

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

91
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.
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;
var workingRect = Rectangle.FromLTRB(minX, minY, maxX, maxY);
Configuration configuration = this.Configuration; Configuration configuration = this.Configuration;
MemoryAllocator memoryAllocator = configuration.MemoryAllocator; MemoryAllocator memoryAllocator = configuration.MemoryAllocator;
using (IMemoryOwner<TPixel> colors = memoryAllocator.Allocate<TPixel>(width)) using IMemoryOwner<TPixel> colors = memoryAllocator.Allocate<TPixel>(interest.Width);
using (IMemoryOwner<float> amount = memoryAllocator.Allocate<float>(width)) using IMemoryOwner<float> amount = memoryAllocator.Allocate<float>(interest.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); colors.GetSpan().Fill(color);
amountSpan.Fill(graphicsOptions.BlendPercentage); amount.GetSpan().Fill(graphicsOptions.BlendPercentage);
PixelBlender<TPixel> blender = PixelOperations<TPixel>.Instance.GetPixelBlender(graphicsOptions); PixelBlender<TPixel> blender = PixelOperations<TPixel>.Instance.GetPixelBlender(graphicsOptions);
ParallelRowIterator.IterateRows( ParallelRowIterator.IterateRows(
workingRect, interest,
configuration, configuration,
rows => new RowIntervalAction(configuration, interest, blender, amount, colors, source));
}
private readonly struct RowIntervalAction : IRowIntervalAction
{
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;
[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;
}
[MethodImpl(InliningOptions.ShortMethod)]
public void Invoke(in RowInterval rows)
{ {
for (int y = rows.Min; y < rows.Max; y++) for (int y = rows.Min; y < rows.Max; y++)
{ {
Span<TPixel> destination = Span<TPixel> destination =
source.GetPixelRowSpan(y - startY).Slice(minX - startX, width); this.source.GetPixelRowSpan(y)
.Slice(this.bounds.X, this.bounds.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(
this.configuration,
destination, destination,
colors.GetSpan(), this.colors.GetSpan(),
destination, destination,
amount.GetSpan()); this.amount.GetSpan());
} }
});
} }
} }
} }

Loading…
Cancel
Save