mirror of https://github.com/SixLabors/ImageSharp
28 changed files with 351 additions and 258 deletions
@ -1,98 +0,0 @@ |
|||
// <copyright file="GlowProcessor.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp.Processing.Processors |
|||
{ |
|||
using System; |
|||
using System.Numerics; |
|||
using System.Threading.Tasks; |
|||
|
|||
using ImageSharp.PixelFormats; |
|||
|
|||
/// <summary>
|
|||
/// An <see cref="IImageProcessor{TPixel}"/> that applies a radial glow effect an <see cref="Image{TPixel}"/>.
|
|||
/// </summary>
|
|||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|||
internal class GlowProcessorParallel<TPixel> : ImageProcessor<TPixel> |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="GlowProcessorParallel{TPixel}" /> class.
|
|||
/// </summary>
|
|||
/// <param name="color">The color or the glow.</param>
|
|||
public GlowProcessorParallel(TPixel color) |
|||
{ |
|||
this.GlowColor = color; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the glow color to apply.
|
|||
/// </summary>
|
|||
public TPixel GlowColor { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the the radius.
|
|||
/// </summary>
|
|||
public float Radius { get; set; } |
|||
|
|||
/// <inheritdoc/>
|
|||
protected override void OnApply(ImageBase<TPixel> source, Rectangle sourceRectangle) |
|||
{ |
|||
int startY = sourceRectangle.Y; |
|||
int endY = sourceRectangle.Bottom; |
|||
int startX = sourceRectangle.X; |
|||
int endX = sourceRectangle.Right; |
|||
TPixel glowColor = this.GlowColor; |
|||
Vector2 centre = Rectangle.Center(sourceRectangle).ToVector2(); |
|||
float maxDistance = this.Radius > 0 ? MathF.Min(this.Radius, 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 (Buffer<TPixel> rowColors = new Buffer<TPixel>(width)) |
|||
using (PixelAccessor<TPixel> sourcePixels = source.Lock()) |
|||
{ |
|||
for (int i = 0; i < width; i++) |
|||
{ |
|||
rowColors[i] = glowColor; |
|||
} |
|||
|
|||
Parallel.For( |
|||
minY, |
|||
maxY, |
|||
this.ParallelOptions, |
|||
y => |
|||
{ |
|||
int offsetY = y - startY; |
|||
|
|||
for (int x = minX; x < maxX; x++) |
|||
{ |
|||
int offsetX = x - startX; |
|||
float distance = Vector2.Distance(centre, new Vector2(offsetX, offsetY)); |
|||
Vector4 sourceColor = sourcePixels[offsetX, offsetY].ToVector4(); |
|||
TPixel packed = default(TPixel); |
|||
packed.PackFromVector4(Vector4BlendTransforms.PremultipliedLerp(sourceColor, glowColor.ToVector4(), 1 - (.95F * (distance / maxDistance)))); |
|||
sourcePixels[offsetX, offsetY] = packed; |
|||
} |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,56 @@ |
|||
// <copyright file="DrawImageEffectTest.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp.Tests.Drawing |
|||
{ |
|||
using System; |
|||
using System.Linq; |
|||
using System.Collections.Generic; |
|||
using System.Text; |
|||
using ImageSharp.PixelFormats; |
|||
using Xunit; |
|||
|
|||
public class BlendedShapes |
|||
{ |
|||
public static IEnumerable<object[]> modes = ((PixelBlenderMode[])Enum.GetValues(typeof(PixelBlenderMode))) |
|||
.Select(x=> new object[] { x }); |
|||
|
|||
[Theory] |
|||
[WithBlankImages(nameof(modes), 100, 100, PixelTypes.StandardImageClass)] |
|||
public void DrawBlendedValues<TPixel>(TestImageProvider<TPixel> provider, PixelBlenderMode mode) |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
using (var img = provider.GetImage()) |
|||
{ |
|||
img.Fill(NamedColors<TPixel>.DarkBlue, new Rectangle(0, 40, 100, 20)); |
|||
img.Fill(NamedColors<TPixel>.HotPink, new Rectangle(40, 0, 20, 100), new ImageSharp.GraphicsOptions(true) |
|||
{ |
|||
BlenderMode = mode |
|||
}); |
|||
img.DebugSave(provider, new { mode }); |
|||
} |
|||
} |
|||
|
|||
[Theory] |
|||
[WithBlankImages(nameof(modes), 100, 100, PixelTypes.StandardImageClass)] |
|||
public void DrawBlendedValues_transparent<TPixel>(TestImageProvider<TPixel> provider, PixelBlenderMode mode) |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
using (var img = provider.GetImage()) |
|||
{ |
|||
img.Fill(NamedColors<TPixel>.DarkBlue, new Rectangle(0, 40, 100, 20)); |
|||
img.Fill(NamedColors<TPixel>.HotPink, new Rectangle(20, 0, 40, 100), new ImageSharp.GraphicsOptions(true) |
|||
{ |
|||
BlenderMode = mode |
|||
}); |
|||
img.Fill(NamedColors<TPixel>.Transparent, new Rectangle(40, 0, 20, 100), new ImageSharp.GraphicsOptions(true) |
|||
{ |
|||
BlenderMode = mode |
|||
}); |
|||
img.DebugSave(provider, new { mode }); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue