|
|
@ -2,7 +2,9 @@ |
|
|
// Licensed under the Apache License, Version 2.0.
|
|
|
// Licensed under the Apache License, Version 2.0.
|
|
|
|
|
|
|
|
|
using System; |
|
|
using System; |
|
|
|
|
|
using System.Runtime.CompilerServices; |
|
|
using SixLabors.ImageSharp.Advanced; |
|
|
using SixLabors.ImageSharp.Advanced; |
|
|
|
|
|
using SixLabors.ImageSharp.Memory; |
|
|
using SixLabors.ImageSharp.PixelFormats; |
|
|
using SixLabors.ImageSharp.PixelFormats; |
|
|
|
|
|
|
|
|
namespace SixLabors.ImageSharp.Processing.Processors.Drawing |
|
|
namespace SixLabors.ImageSharp.Processing.Processors.Drawing |
|
|
@ -100,15 +102,58 @@ namespace SixLabors.ImageSharp.Processing.Processors.Drawing |
|
|
ParallelRowIterator.IterateRows( |
|
|
ParallelRowIterator.IterateRows( |
|
|
workingRect, |
|
|
workingRect, |
|
|
configuration, |
|
|
configuration, |
|
|
rows => |
|
|
new RowIntervalAction(source, targetImage, blender, configuration, minX, width, locationY, targetX, this.Opacity)); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// A <see langword="struct"/> implementing the draw logic for <see cref="DrawImageProcessor{TPixelBg,TPixelFg}"/>.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private readonly struct RowIntervalAction : IRowIntervalAction |
|
|
|
|
|
{ |
|
|
|
|
|
private readonly ImageFrame<TPixelBg> sourceFrame; |
|
|
|
|
|
private readonly Image<TPixelFg> targetImage; |
|
|
|
|
|
private readonly PixelBlender<TPixelBg> blender; |
|
|
|
|
|
private readonly Configuration configuration; |
|
|
|
|
|
private readonly int minX; |
|
|
|
|
|
private readonly int width; |
|
|
|
|
|
private readonly int locationY; |
|
|
|
|
|
private readonly int targetX; |
|
|
|
|
|
private readonly float opacity; |
|
|
|
|
|
|
|
|
|
|
|
[MethodImpl(InliningOptions.ShortMethod)] |
|
|
|
|
|
public RowIntervalAction( |
|
|
|
|
|
ImageFrame<TPixelBg> sourceFrame, |
|
|
|
|
|
Image<TPixelFg> targetImage, |
|
|
|
|
|
PixelBlender<TPixelBg> blender, |
|
|
|
|
|
Configuration configuration, |
|
|
|
|
|
int minX, |
|
|
|
|
|
int width, |
|
|
|
|
|
int locationY, |
|
|
|
|
|
int targetX, |
|
|
|
|
|
float opacity) |
|
|
|
|
|
{ |
|
|
|
|
|
this.sourceFrame = sourceFrame; |
|
|
|
|
|
this.targetImage = targetImage; |
|
|
|
|
|
this.blender = blender; |
|
|
|
|
|
this.configuration = configuration; |
|
|
|
|
|
this.minX = minX; |
|
|
|
|
|
this.width = width; |
|
|
|
|
|
this.locationY = locationY; |
|
|
|
|
|
this.targetX = targetX; |
|
|
|
|
|
this.opacity = opacity; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc/>
|
|
|
|
|
|
[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<TPixelBg> background = this.sourceFrame.GetPixelRowSpan(y).Slice(this.minX, this.width); |
|
|
{ |
|
|
Span<TPixelFg> foreground = this.targetImage.GetPixelRowSpan(y - this.locationY).Slice(this.targetX, this.width); |
|
|
Span<TPixelBg> background = source.GetPixelRowSpan(y).Slice(minX, width); |
|
|
this.blender.Blend<TPixelFg>(this.configuration, background, background, foreground, this.opacity); |
|
|
Span<TPixelFg> foreground = targetImage.GetPixelRowSpan(y - locationY).Slice(targetX, width); |
|
|
} |
|
|
blender.Blend<TPixelFg>(configuration, background, background, foreground, this.Opacity); |
|
|
} |
|
|
} |
|
|
|
|
|
}); |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|