mirror of https://github.com/SixLabors/ImageSharp
Browse Source
Former-commit-id: abafddef9276f279c204a312c097cd28aa1d3e58 Former-commit-id: 27079155a41cd95690c7b676601e9df4044a05ca Former-commit-id: 0c77f74fd0194f4bab444d9bb4522422f65ad029af/merge-core
3 changed files with 163 additions and 0 deletions
@ -0,0 +1,41 @@ |
|||||
|
// <copyright file="BackgroundColor.cs" company="James Jackson-South">
|
||||
|
// Copyright (c) James Jackson-South and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>
|
||||
|
|
||||
|
namespace ImageProcessorCore |
||||
|
{ |
||||
|
using Processors; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Extension methods for the <see cref="Image{T,TP}"/> type.
|
||||
|
/// </summary>
|
||||
|
public static partial class ImageExtensions |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Replaces the background color of image with the given one.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="T">The pixel format.</typeparam>
|
||||
|
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="color">The color to set as the background.</param>
|
||||
|
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
|
||||
|
/// <returns>The <see cref="Image{T,TP}"/>.</returns>
|
||||
|
public static Image<T, TP> BackgroundColor<T, TP>(this Image<T, TP> source, T color, ProgressEventHandler progressHandler = null) |
||||
|
where T : IPackedVector<TP> |
||||
|
where TP : struct |
||||
|
{ |
||||
|
BackgroundColorProcessor<T, TP> processor = new BackgroundColorProcessor<T, TP>(color); |
||||
|
processor.OnProgress += progressHandler; |
||||
|
|
||||
|
try |
||||
|
{ |
||||
|
return source.Process(source.Bounds, processor); |
||||
|
} |
||||
|
finally |
||||
|
{ |
||||
|
processor.OnProgress -= progressHandler; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,84 @@ |
|||||
|
// <copyright file="BackgroundColorProcessor.cs" company="James Jackson-South">
|
||||
|
// Copyright (c) James Jackson-South and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>
|
||||
|
|
||||
|
namespace ImageProcessorCore.Processors |
||||
|
{ |
||||
|
using System; |
||||
|
using System.Numerics; |
||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Sets the background color of the image.
|
||||
|
/// </summary>
|
||||
|
public class BackgroundColorProcessor<T, TP> : ImageProcessor<T, TP> |
||||
|
where T : IPackedVector<TP> |
||||
|
where TP : struct |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// The epsilon for comparing floating point numbers.
|
||||
|
/// </summary>
|
||||
|
private const float Epsilon = 0.001f; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="BackgroundColorProcessor{T,TP}"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="color">The <see cref="T"/> to set the background color to.</param>
|
||||
|
public BackgroundColorProcessor(T color) |
||||
|
{ |
||||
|
this.Value = color; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the background color value.
|
||||
|
/// </summary>
|
||||
|
public T Value { get; } |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
protected override void Apply(ImageBase<T, TP> target, ImageBase<T, TP> source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) |
||||
|
{ |
||||
|
int sourceY = sourceRectangle.Y; |
||||
|
int sourceBottom = sourceRectangle.Bottom; |
||||
|
int startX = sourceRectangle.X; |
||||
|
int endX = sourceRectangle.Right; |
||||
|
Vector4 backgroundColor = this.Value.ToVector4(); |
||||
|
|
||||
|
using (IPixelAccessor<T, TP> sourcePixels = source.Lock()) |
||||
|
using (IPixelAccessor<T, TP> targetPixels = target.Lock()) |
||||
|
{ |
||||
|
Parallel.For( |
||||
|
startY, |
||||
|
endY, |
||||
|
Bootstrapper.Instance.ParallelOptions, |
||||
|
y => |
||||
|
{ |
||||
|
if (y >= sourceY && y < sourceBottom) |
||||
|
{ |
||||
|
for (int x = startX; x < endX; x++) |
||||
|
{ |
||||
|
Vector4 color = sourcePixels[x, y].ToVector4(); |
||||
|
float a = color.W; |
||||
|
|
||||
|
if (a < 1 && a > 0) |
||||
|
{ |
||||
|
color = Vector4.Lerp(color, backgroundColor, .5f); |
||||
|
} |
||||
|
|
||||
|
if (Math.Abs(a) < Epsilon) |
||||
|
{ |
||||
|
color = backgroundColor; |
||||
|
} |
||||
|
|
||||
|
T packed = default(T); |
||||
|
packed.PackVector(color); |
||||
|
targetPixels[x, y] = packed; |
||||
|
} |
||||
|
|
||||
|
this.OnRowProcessed(); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,38 @@ |
|||||
|
// <copyright file="BackgroundColorTest.cs" company="James Jackson-South">
|
||||
|
// Copyright (c) James Jackson-South and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>
|
||||
|
|
||||
|
namespace ImageProcessorCore.Tests |
||||
|
{ |
||||
|
using System.IO; |
||||
|
|
||||
|
using Xunit; |
||||
|
|
||||
|
public class BackgroundColorTest : FileTestBase |
||||
|
{ |
||||
|
[Fact] |
||||
|
public void ImageShouldApplyBackgroundColorFilter() |
||||
|
{ |
||||
|
const string path = "TestOutput/BackgroundColor"; |
||||
|
if (!Directory.Exists(path)) |
||||
|
{ |
||||
|
Directory.CreateDirectory(path); |
||||
|
} |
||||
|
|
||||
|
foreach (string file in Files) |
||||
|
{ |
||||
|
using (FileStream stream = File.OpenRead(file)) |
||||
|
{ |
||||
|
string filename = Path.GetFileName(file); |
||||
|
Image image = new Image(stream); |
||||
|
using (FileStream output = File.OpenWrite($"{path}/{filename}")) |
||||
|
{ |
||||
|
image.BackgroundColor(Color.HotPink) |
||||
|
.Save(output); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue