mirror of https://github.com/SixLabors/ImageSharp
committed by
GitHub
10 changed files with 522 additions and 1 deletions
@ -0,0 +1,103 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
using SixLabors.ImageSharp.Processing.Processors.Effects; |
|||
using SixLabors.Primitives; |
|||
|
|||
namespace SixLabors.ImageSharp.Processing |
|||
{ |
|||
/// <summary>
|
|||
/// Defines extension methods that allow the application of user defined pixel shaders to an <see cref="Image"/>.
|
|||
/// </summary>
|
|||
public static class PixelShaderExtensions |
|||
{ |
|||
/// <summary>
|
|||
/// Applies a user defined pixel shader to the image.
|
|||
/// </summary>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="pixelShader">The user defined pixel shader to use to modify images.</param>
|
|||
/// <returns>The <see cref="IImageProcessingContext"/> to allow chaining of operations.</returns>
|
|||
public static IImageProcessingContext ApplyPixelShaderProcessor(this IImageProcessingContext source, PixelShader pixelShader) |
|||
=> source.ApplyProcessor(new PixelShaderProcessor(pixelShader)); |
|||
|
|||
/// <summary>
|
|||
/// Applies a user defined pixel shader to the image.
|
|||
/// </summary>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="pixelShader">The user defined pixel shader to use to modify images.</param>
|
|||
/// <param name="modifiers">The <see cref="PixelConversionModifiers"/> to apply during the pixel conversions.</param>
|
|||
/// <returns>The <see cref="IImageProcessingContext"/> to allow chaining of operations.</returns>
|
|||
public static IImageProcessingContext ApplyPixelShaderProcessor(this IImageProcessingContext source, PixelShader pixelShader, PixelConversionModifiers modifiers) |
|||
=> source.ApplyProcessor(new PixelShaderProcessor(pixelShader, modifiers)); |
|||
|
|||
/// <summary>
|
|||
/// Applies a user defined pixel shader to the image.
|
|||
/// </summary>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="pixelShader">The user defined pixel shader to use to modify images.</param>
|
|||
/// <param name="rectangle">
|
|||
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
|
|||
/// </param>
|
|||
/// <returns>The <see cref="IImageProcessingContext"/> to allow chaining of operations.</returns>
|
|||
public static IImageProcessingContext ApplyPixelShaderProcessor(this IImageProcessingContext source, PixelShader pixelShader, Rectangle rectangle) |
|||
=> source.ApplyProcessor(new PixelShaderProcessor(pixelShader), rectangle); |
|||
|
|||
/// <summary>
|
|||
/// Applies a user defined pixel shader to the image.
|
|||
/// </summary>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="pixelShader">The user defined pixel shader to use to modify images.</param>
|
|||
/// <param name="rectangle">
|
|||
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
|
|||
/// </param>
|
|||
/// <param name="modifiers">The <see cref="PixelConversionModifiers"/> to apply during the pixel conversions.</param>
|
|||
/// <returns>The <see cref="IImageProcessingContext"/> to allow chaining of operations.</returns>
|
|||
public static IImageProcessingContext ApplyPixelShaderProcessor(this IImageProcessingContext source, PixelShader pixelShader, Rectangle rectangle, PixelConversionModifiers modifiers) |
|||
=> source.ApplyProcessor(new PixelShaderProcessor(pixelShader, modifiers), rectangle); |
|||
|
|||
/// <summary>
|
|||
/// Applies a user defined pixel shader to the image.
|
|||
/// </summary>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="pixelShader">The user defined pixel shader to use to modify images.</param>
|
|||
/// <returns>The <see cref="IImageProcessingContext"/> to allow chaining of operations.</returns>
|
|||
public static IImageProcessingContext ApplyPixelShaderProcessor(this IImageProcessingContext source, PositionAwarePixelShader pixelShader) |
|||
=> source.ApplyProcessor(new PositionAwarePixelShaderProcessor(pixelShader)); |
|||
|
|||
/// <summary>
|
|||
/// Applies a user defined pixel shader to the image.
|
|||
/// </summary>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="pixelShader">The user defined pixel shader to use to modify images.</param>
|
|||
/// <param name="modifiers">The <see cref="PixelConversionModifiers"/> to apply during the pixel conversions.</param>
|
|||
/// <returns>The <see cref="IImageProcessingContext"/> to allow chaining of operations.</returns>
|
|||
public static IImageProcessingContext ApplyPixelShaderProcessor(this IImageProcessingContext source, PositionAwarePixelShader pixelShader, PixelConversionModifiers modifiers) |
|||
=> source.ApplyProcessor(new PositionAwarePixelShaderProcessor(pixelShader, modifiers)); |
|||
|
|||
/// <summary>
|
|||
/// Applies a user defined pixel shader to the image.
|
|||
/// </summary>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="pixelShader">The user defined pixel shader to use to modify images.</param>
|
|||
/// <param name="rectangle">
|
|||
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
|
|||
/// </param>
|
|||
/// <returns>The <see cref="IImageProcessingContext"/> to allow chaining of operations.</returns>
|
|||
public static IImageProcessingContext ApplyPixelShaderProcessor(this IImageProcessingContext source, PositionAwarePixelShader pixelShader, Rectangle rectangle) |
|||
=> source.ApplyProcessor(new PositionAwarePixelShaderProcessor(pixelShader), rectangle); |
|||
|
|||
/// <summary>
|
|||
/// Applies a user defined pixel shader to the image.
|
|||
/// </summary>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <param name="pixelShader">The user defined pixel shader to use to modify images.</param>
|
|||
/// <param name="rectangle">
|
|||
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
|
|||
/// </param>
|
|||
/// <param name="modifiers">The <see cref="PixelConversionModifiers"/> to apply during the pixel conversions.</param>
|
|||
/// <returns>The <see cref="IImageProcessingContext"/> to allow chaining of operations.</returns>
|
|||
public static IImageProcessingContext ApplyPixelShaderProcessor(this IImageProcessingContext source, PositionAwarePixelShader pixelShader, Rectangle rectangle, PixelConversionModifiers modifiers) |
|||
=> source.ApplyProcessor(new PositionAwarePixelShaderProcessor(pixelShader, modifiers), rectangle); |
|||
} |
|||
} |
|||
@ -0,0 +1,15 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System; |
|||
using System.Numerics; |
|||
|
|||
namespace SixLabors.ImageSharp.Processing |
|||
{ |
|||
/// <summary>
|
|||
/// A <see langword="delegate"/> representing a user defined pixel shader.
|
|||
/// </summary>
|
|||
/// <param name="span">The target row of <see cref="Vector4"/> pixels to process.</param>
|
|||
/// <remarks>The <see cref="Vector4.X"/>, <see cref="Vector4.Y"/>, <see cref="Vector4.Z"/>, and <see cref="Vector4.W"/> fields map the RGBA channels respectively.</remarks>
|
|||
public delegate void PixelShader(Span<Vector4> span); |
|||
} |
|||
@ -0,0 +1,17 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System; |
|||
using System.Numerics; |
|||
using SixLabors.Primitives; |
|||
|
|||
namespace SixLabors.ImageSharp.Processing |
|||
{ |
|||
/// <summary>
|
|||
/// A <see langword="delegate"/> representing a user defined pixel shader.
|
|||
/// </summary>
|
|||
/// <param name="span">The target row of <see cref="Vector4"/> pixels to process.</param>
|
|||
/// <param name="offset">The initial horizontal and vertical offset for the input pixels to process.</param>
|
|||
/// <remarks>The <see cref="Vector4.X"/>, <see cref="Vector4.Y"/>, <see cref="Vector4.Z"/>, and <see cref="Vector4.W"/> fields map the RGBA channels respectively.</remarks>
|
|||
public delegate void PositionAwarePixelShader(Span<Vector4> span, Point offset); |
|||
} |
|||
@ -0,0 +1,61 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
using SixLabors.Primitives; |
|||
|
|||
namespace SixLabors.ImageSharp.Processing.Processors.Effects |
|||
{ |
|||
/// <summary>
|
|||
/// Applies a user defined pixel shader effect through a given delegate.
|
|||
/// </summary>
|
|||
public sealed class PixelShaderProcessor : IImageProcessor |
|||
{ |
|||
/// <summary>
|
|||
/// The default <see cref="PixelConversionModifiers"/> to apply during the pixel conversions.
|
|||
/// </summary>
|
|||
public const PixelConversionModifiers DefaultModifiers = PixelConversionModifiers.None; |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="PixelShaderProcessor"/> class.
|
|||
/// </summary>
|
|||
/// <param name="pixelShader">
|
|||
/// The user defined pixel shader to use to modify images.
|
|||
/// </param>
|
|||
public PixelShaderProcessor(PixelShader pixelShader) |
|||
{ |
|||
this.PixelShader = pixelShader; |
|||
this.Modifiers = DefaultModifiers; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="PixelShaderProcessor"/> class.
|
|||
/// </summary>
|
|||
/// <param name="pixelShader">
|
|||
/// The user defined pixel shader to use to modify images.
|
|||
/// </param>
|
|||
/// <param name="modifiers">The <see cref="PixelConversionModifiers"/> to apply during the pixel conversions.</param>
|
|||
public PixelShaderProcessor(PixelShader pixelShader, PixelConversionModifiers modifiers) |
|||
{ |
|||
this.PixelShader = pixelShader; |
|||
this.Modifiers = modifiers; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the user defined pixel shader.
|
|||
/// </summary>
|
|||
public PixelShader PixelShader { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the <see cref="PixelConversionModifiers"/> to apply during the pixel conversions.
|
|||
/// </summary>
|
|||
public PixelConversionModifiers Modifiers { get; } |
|||
|
|||
/// <inheritdoc />
|
|||
public IImageProcessor<TPixel> CreatePixelSpecificProcessor<TPixel>(Image<TPixel> source, Rectangle sourceRectangle) |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
return new PixelShaderProcessor<TPixel>(this, source, sourceRectangle); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,73 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System; |
|||
using System.Numerics; |
|||
|
|||
using SixLabors.ImageSharp.Advanced; |
|||
using SixLabors.ImageSharp.Advanced.ParallelUtils; |
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
using SixLabors.Primitives; |
|||
|
|||
namespace SixLabors.ImageSharp.Processing.Processors.Effects |
|||
{ |
|||
/// <summary>
|
|||
/// Applies a user defined pixel shader effect through a given delegate.
|
|||
/// </summary>
|
|||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|||
internal abstract class PixelShaderProcessorBase<TPixel> : ImageProcessor<TPixel> |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
/// <summary>
|
|||
/// The <see cref="PixelConversionModifiers"/> to apply during the pixel conversions.
|
|||
/// </summary>
|
|||
private readonly PixelConversionModifiers modifiers; |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="PixelShaderProcessorBase{TPixel}"/> class.
|
|||
/// </summary>
|
|||
/// <param name="modifiers">The <see cref="PixelConversionModifiers"/> to apply during the pixel conversions.</param>
|
|||
/// <param name="source">The source <see cref="Image{TPixel}"/> for the current processor instance.</param>
|
|||
/// <param name="sourceRectangle">The source area to process for the current processor instance.</param>
|
|||
protected PixelShaderProcessorBase(PixelConversionModifiers modifiers, Image<TPixel> source, Rectangle sourceRectangle) |
|||
: base(source, sourceRectangle) |
|||
{ |
|||
this.modifiers = modifiers; |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
protected override void OnFrameApply(ImageFrame<TPixel> source) |
|||
{ |
|||
var interest = Rectangle.Intersect(this.SourceRectangle, source.Bounds()); |
|||
int startX = interest.X; |
|||
Configuration configuration = this.Configuration; |
|||
PixelConversionModifiers modifiers = this.modifiers; |
|||
|
|||
ParallelHelper.IterateRowsWithTempBuffer<Vector4>( |
|||
interest, |
|||
this.Configuration, |
|||
(rows, vectorBuffer) => |
|||
{ |
|||
for (int y = rows.Min; y < rows.Max; y++) |
|||
{ |
|||
Span<Vector4> vectorSpan = vectorBuffer.Span; |
|||
int length = vectorSpan.Length; |
|||
Span<TPixel> rowSpan = source.GetPixelRowSpan(y).Slice(startX, length); |
|||
PixelOperations<TPixel>.Instance.ToVector4(configuration, rowSpan, vectorSpan, modifiers); |
|||
|
|||
// Run the user defined pixel shader on the current row of pixels
|
|||
this.ApplyPixelShader(vectorSpan, new Point(startX, y)); |
|||
|
|||
PixelOperations<TPixel>.Instance.FromVector4Destructive(configuration, vectorSpan, rowSpan, modifiers); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Applies the current pixel shader effect on a target row of preprocessed pixels.
|
|||
/// </summary>
|
|||
/// <param name="span">The target row of <see cref="Vector4"/> pixels to process.</param>
|
|||
/// <param name="offset">The initial horizontal and vertical offset for the input pixels to process.</param>
|
|||
protected abstract void ApplyPixelShader(Span<Vector4> span, Point offset); |
|||
} |
|||
} |
|||
@ -0,0 +1,39 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System; |
|||
using System.Numerics; |
|||
|
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
using SixLabors.Primitives; |
|||
|
|||
namespace SixLabors.ImageSharp.Processing.Processors.Effects |
|||
{ |
|||
/// <summary>
|
|||
/// Applies a user defined pixel shader effect through a given delegate.
|
|||
/// </summary>
|
|||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|||
internal sealed class PixelShaderProcessor<TPixel> : PixelShaderProcessorBase<TPixel> |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
/// <summary>
|
|||
/// The user defined pixel shader.
|
|||
/// </summary>
|
|||
private readonly PixelShader pixelShader; |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="PixelShaderProcessor{TPixel}"/> class.
|
|||
/// </summary>
|
|||
/// <param name="definition">The <see cref="PixelShaderProcessor"/> defining the processor parameters.</param>
|
|||
/// <param name="source">The source <see cref="Image{TPixel}"/> for the current processor instance.</param>
|
|||
/// <param name="sourceRectangle">The source area to process for the current processor instance.</param>
|
|||
public PixelShaderProcessor(PixelShaderProcessor definition, Image<TPixel> source, Rectangle sourceRectangle) |
|||
: base(definition.Modifiers, source, sourceRectangle) |
|||
{ |
|||
this.pixelShader = definition.PixelShader; |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
protected override void ApplyPixelShader(Span<Vector4> span, Point offset) => this.pixelShader(span); |
|||
} |
|||
} |
|||
@ -0,0 +1,61 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
using SixLabors.Primitives; |
|||
|
|||
namespace SixLabors.ImageSharp.Processing.Processors.Effects |
|||
{ |
|||
/// <summary>
|
|||
/// Applies a user defined pixel shader effect through a given delegate.
|
|||
/// </summary>
|
|||
public sealed class PositionAwarePixelShaderProcessor : IImageProcessor |
|||
{ |
|||
/// <summary>
|
|||
/// The default <see cref="PixelConversionModifiers"/> to apply during the pixel conversions.
|
|||
/// </summary>
|
|||
public const PixelConversionModifiers DefaultModifiers = PixelConversionModifiers.None; |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="PositionAwarePixelShaderProcessor"/> class.
|
|||
/// </summary>
|
|||
/// <param name="pixelShader">
|
|||
/// The user defined pixel shader to use to modify images.
|
|||
/// </param>
|
|||
public PositionAwarePixelShaderProcessor(PositionAwarePixelShader pixelShader) |
|||
{ |
|||
this.PixelShader = pixelShader; |
|||
this.Modifiers = DefaultModifiers; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="PositionAwarePixelShaderProcessor"/> class.
|
|||
/// </summary>
|
|||
/// <param name="pixelShader">
|
|||
/// The user defined pixel shader to use to modify images.
|
|||
/// </param>
|
|||
/// <param name="modifiers">The <see cref="PixelConversionModifiers"/> to apply during the pixel conversions.</param>
|
|||
public PositionAwarePixelShaderProcessor(PositionAwarePixelShader pixelShader, PixelConversionModifiers modifiers) |
|||
{ |
|||
this.PixelShader = pixelShader; |
|||
this.Modifiers = modifiers; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the user defined pixel shader.
|
|||
/// </summary>
|
|||
public PositionAwarePixelShader PixelShader { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the <see cref="PixelConversionModifiers"/> to apply during the pixel conversions.
|
|||
/// </summary>
|
|||
public PixelConversionModifiers Modifiers { get; } |
|||
|
|||
/// <inheritdoc />
|
|||
public IImageProcessor<TPixel> CreatePixelSpecificProcessor<TPixel>(Image<TPixel> source, Rectangle sourceRectangle) |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
return new PositionAwarePixelShaderProcessor<TPixel>(this, source, sourceRectangle); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,39 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System; |
|||
using System.Numerics; |
|||
|
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
using SixLabors.Primitives; |
|||
|
|||
namespace SixLabors.ImageSharp.Processing.Processors.Effects |
|||
{ |
|||
/// <summary>
|
|||
/// Applies a user defined pixel shader effect through a given delegate.
|
|||
/// </summary>
|
|||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|||
internal sealed class PositionAwarePixelShaderProcessor<TPixel> : PixelShaderProcessorBase<TPixel> |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
/// <summary>
|
|||
/// The user defined pixel shader.
|
|||
/// </summary>
|
|||
private readonly PositionAwarePixelShader pixelShader; |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="PositionAwarePixelShaderProcessor{TPixel}"/> class.
|
|||
/// </summary>
|
|||
/// <param name="definition">The <see cref="PositionAwarePixelShaderProcessor"/> defining the processor parameters.</param>
|
|||
/// <param name="source">The source <see cref="Image{TPixel}"/> for the current processor instance.</param>
|
|||
/// <param name="sourceRectangle">The source area to process for the current processor instance.</param>
|
|||
public PositionAwarePixelShaderProcessor(PositionAwarePixelShaderProcessor definition, Image<TPixel> source, Rectangle sourceRectangle) |
|||
: base(definition.Modifiers, source, sourceRectangle) |
|||
{ |
|||
this.pixelShader = definition.PixelShader; |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
protected override void ApplyPixelShader(Span<Vector4> span, Point offset) => this.pixelShader(span, offset); |
|||
} |
|||
} |
|||
@ -0,0 +1,113 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System; |
|||
using System.Numerics; |
|||
|
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
using SixLabors.ImageSharp.Processing; |
|||
|
|||
using Xunit; |
|||
|
|||
namespace SixLabors.ImageSharp.Tests.Processing.Processors.Effects |
|||
{ |
|||
[GroupOutput("Effects")] |
|||
public class PixelShaderTest |
|||
{ |
|||
[Theory] |
|||
[WithFile(TestImages.Png.CalliphoraPartial, PixelTypes.Rgba32)] |
|||
public void FullImage<TPixel>(TestImageProvider<TPixel> provider) |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
provider.RunValidatingProcessorTest( |
|||
x => x.ApplyPixelShaderProcessor( |
|||
span => |
|||
{ |
|||
for (int i = 0; i < span.Length; i++) |
|||
{ |
|||
Vector4 v4 = span[i]; |
|||
float avg = (v4.X + v4.Y + v4.Z) / 3f; |
|||
span[i] = new Vector4(avg); |
|||
} |
|||
}), |
|||
appendPixelTypeToFileName: false); |
|||
} |
|||
|
|||
[Theory] |
|||
[WithFile(TestImages.Png.CalliphoraPartial, PixelTypes.Rgba32)] |
|||
public void InBox<TPixel>(TestImageProvider<TPixel> provider) |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
provider.RunRectangleConstrainedValidatingProcessorTest( |
|||
(x, rect) => x.ApplyPixelShaderProcessor( |
|||
span => |
|||
{ |
|||
for (int i = 0; i < span.Length; i++) |
|||
{ |
|||
Vector4 v4 = span[i]; |
|||
float avg = (v4.X + v4.Y + v4.Z) / 3f; |
|||
span[i] = new Vector4(avg); |
|||
} |
|||
}, rect)); |
|||
} |
|||
|
|||
[Theory] |
|||
[WithFile(TestImages.Png.CalliphoraPartial, PixelTypes.Rgba32)] |
|||
public void PositionAwareFullImage<TPixel>(TestImageProvider<TPixel> provider) |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
provider.RunValidatingProcessorTest( |
|||
c => c.ApplyPixelShaderProcessor( |
|||
(span, offset) => |
|||
{ |
|||
int y = offset.Y; |
|||
int x = offset.X; |
|||
for (int i = 0; i < span.Length; i++) |
|||
{ |
|||
float |
|||
sine = MathF.Sin(y), |
|||
cosine = MathF.Cos(x + i), |
|||
sum = sine + cosine, |
|||
abs = MathF.Abs(sum), |
|||
a = 0.5f + (abs / 2); // Max value for sin(y) + cos(x) is 2
|
|||
|
|||
Vector4 v4 = span[i]; |
|||
float avg = (v4.X + v4.Y + v4.Z) / 3f; |
|||
var gray = new Vector4(avg, avg, avg, a); |
|||
|
|||
span[i] = Vector4.Clamp(gray, Vector4.Zero, Vector4.One); |
|||
} |
|||
}), |
|||
appendPixelTypeToFileName: false); |
|||
} |
|||
|
|||
[Theory] |
|||
[WithFile(TestImages.Png.CalliphoraPartial, PixelTypes.Rgba32)] |
|||
public void PositionAwareInBox<TPixel>(TestImageProvider<TPixel> provider) |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
provider.RunRectangleConstrainedValidatingProcessorTest( |
|||
(c, rect) => c.ApplyPixelShaderProcessor( |
|||
(span, offset) => |
|||
{ |
|||
int y = offset.Y; |
|||
int x = offset.X; |
|||
for (int i = 0; i < span.Length; i++) |
|||
{ |
|||
float |
|||
sine = MathF.Sin(y), |
|||
cosine = MathF.Cos(x + i), |
|||
sum = sine + cosine, |
|||
abs = MathF.Abs(sum), |
|||
a = 0.5f + (abs / 2); |
|||
|
|||
Vector4 v4 = span[i]; |
|||
float avg = (v4.X + v4.Y + v4.Z) / 3f; |
|||
var gray = new Vector4(avg, avg, avg, a); |
|||
|
|||
span[i] = Vector4.Clamp(gray, Vector4.Zero, Vector4.One); |
|||
} |
|||
}, rect)); |
|||
} |
|||
} |
|||
} |
|||
@ -1 +1 @@ |
|||
Subproject commit d7c099cebd58f1d3ff997383351d52d28a29df3d |
|||
Subproject commit d8ea82085ac39a6aa6ca8e0806a9518d3a7d3337 |
|||
Loading…
Reference in new issue