Browse Source

Invert

Former-commit-id: 543588719050a2a824a61b3578bad8b1453937d4
Former-commit-id: 0e0ca33a0e82a2696f63609b1332c85949f42fda
Former-commit-id: 2750fc6e82392ec3c9368d9b2f062e8823ffb363
af/merge-core
James Jackson-South 10 years ago
parent
commit
6525ca10ef
  1. 54
      src/ImageProcessorCore/Filters/Invert.cs
  2. 2
      src/ImageProcessorCore/Filters/Processors/BrightnessProcessor.cs
  3. 2
      src/ImageProcessorCore/Filters/Processors/ColorMatrix/ColorMatrixFilter.cs
  4. 54
      src/ImageProcessorCore/Filters/Processors/InvertProcessor.cs
  5. 38
      tests/ImageProcessorCore.Tests/Processors/Filters/InvertTest.cs

54
src/ImageProcessorCore/Filters/Invert.cs

@ -0,0 +1,54 @@
// <copyright file="Invert.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"/> type.
/// </summary>
public static partial class ImageExtensions
{
/// <summary>
/// Inverts the colors of the image.
/// </summary>
/// <param name="source">The image this method extends.</param>
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
/// <returns>The <see cref="Image"/>.</returns>
public static Image<T, TP> Invert<T, TP>(this Image<T, TP> source, ProgressEventHandler progressHandler = null)
where T : IPackedVector<TP>
where TP : struct
{
return Invert(source, source.Bounds, progressHandler);
}
/// <summary>
/// Inverts the colors of the image.
/// </summary>
/// <param name="source">The image this method extends.</param>
/// <param name="rectangle">
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param>
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
/// <returns>The <see cref="Image"/>.</returns>
public static Image<T, TP> Invert<T, TP>(this Image<T, TP> source, Rectangle rectangle, ProgressEventHandler progressHandler = null)
where T : IPackedVector<TP>
where TP : struct
{
InvertProcessor<T, TP> processor = new InvertProcessor<T, TP>();
processor.OnProgress += progressHandler;
try
{
return source.Process(rectangle, processor);
}
finally
{
processor.OnProgress -= progressHandler;
}
}
}
}

2
src/ImageProcessorCore/Filters/Processors/BrightnessProcessor.cs

@ -60,7 +60,7 @@ namespace ImageProcessorCore.Processors
Vector4 vector = sourcePixels[x, y].ToVector4().Expand();
Vector3 transformed = new Vector3(vector.X, vector.Y, vector.Z);
transformed += new Vector3(brightness);
vector = new Vector4(transformed.X, transformed.Y, transformed.Z, vector.W);
vector = new Vector4(transformed, vector.W);
T packed = default(T);
packed.PackVector(vector.Compress());

2
src/ImageProcessorCore/Filters/Processors/ColorMatrix/ColorMatrixFilter.cs

@ -68,7 +68,7 @@ namespace ImageProcessorCore.Processors
}
Vector3 transformed = Vector3.Transform(new Vector3(vector.X, vector.Y, vector.Z), matrix);
vector = new Vector4(transformed.X, transformed.Y, transformed.Z, vector.W);
vector = new Vector4(transformed, vector.W);
T packed = default(T);
packed.PackVector(compand ? vector.Compress() : vector);
return packed;

54
src/ImageProcessorCore/Filters/Processors/InvertProcessor.cs

@ -0,0 +1,54 @@
// <copyright file="InvertProcessor.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.Numerics;
using System.Threading.Tasks;
/// <summary>
/// An <see cref="IImageProcessor"/> to invert the colors of an <see cref="Image"/>.
/// </summary>
public class InvertProcessor<T, TP> : ImageProcessor<T, TP>
where T : IPackedVector<TP>
where TP : struct
{
/// <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;
Vector3 inverseVector = Vector3.One;
using (IPixelAccessor<T, TP> sourcePixels = source.Lock())
using (IPixelAccessor<T, TP> targetPixels = target.Lock())
{
Parallel.For(
startY,
endY,
y =>
{
if (y >= sourceY && y < sourceBottom)
{
for (int x = startX; x < endX; x++)
{
Vector4 color = sourcePixels[x, y].ToVector4();
Vector3 vector = inverseVector - new Vector3(color.X, color.Y, color.Z);
T packed = default(T);
packed.PackVector(new Vector4(vector, color.W));
targetPixels[x, y] = packed;
}
this.OnRowProcessed();
}
});
}
}
}
}

38
tests/ImageProcessorCore.Tests/Processors/Filters/InvertTest.cs

@ -0,0 +1,38 @@
// <copyright file="InvertTest.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 InvertTest : FileTestBase
{
[Fact]
public void ImageShouldApplyInvertFilter()
{
const string path = "TestOutput/Invert";
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.Invert()
.Save(output);
}
}
}
}
}
}
Loading…
Cancel
Save