Browse Source

Add brightness

Former-commit-id: 0ccb55b3b1d634cbdf289c4496006174d8e382dc
Former-commit-id: ea1ba7bbf746e2cf0833e591e451b6ca4df78458
Former-commit-id: 1a6addaf532b4a547bd84d37d74db7198d940d30
af/merge-core
James Jackson-South 11 years ago
parent
commit
19c28047d9
  1. 77
      src/ImageProcessor/Filters/Brightness.cs
  2. 2
      src/ImageProcessor/Filters/ColorMatrix/ColorMatrix.cs
  3. 1
      src/ImageProcessor/Filters/Contrast.cs
  4. 78
      src/ImageProcessor/Filters/Saturation.cs
  5. 3
      src/ImageProcessor/ImageProcessor.csproj
  6. 18
      tests/ImageProcessor.Tests/Processors/Filters/FilterTests.cs

77
src/ImageProcessor/Filters/Brightness.cs

@ -0,0 +1,77 @@
// <copyright file="Brightness.cs" company="James South">
// Copyright (c) James South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageProcessor.Filters
{
using System;
using System.Numerics;
using System.Threading.Tasks;
/// <summary>
/// An <see cref="IImageProcessor"/> to change the brightness of an <see cref="Image"/>.
/// </summary>
public class Brightness : ParallelImageProcessor
{
/// <summary>
/// Initializes a new instance of the <see cref="Brightness"/> class.
/// </summary>
/// <param name="brightness">The new brightness of the image. Must be between -100 and 100.</param>
/// <exception cref="ArgumentException">
/// <paramref name="brightness"/> is less than -100 or is greater than 100.
/// </exception>
public Brightness(int brightness)
{
Guard.MustBeBetweenOrEqualTo(brightness, -100, 100, nameof(brightness));
this.Value = brightness;
}
/// <summary>
/// Gets the brightness value.
/// </summary>
public int Value { get; }
/// <inheritdoc/>
protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
{
float brightness = this.Value / 100f;
int sourceY = sourceRectangle.Y;
int sourceBottom = sourceRectangle.Bottom;
int startX = sourceRectangle.X;
int endX = sourceRectangle.Right;
Parallel.For(
startY,
endY,
y =>
{
if (y >= sourceY && y < sourceBottom)
{
for (int x = startX; x < endX; x++)
{
target[x, y] = AdjustBrightness(source[x, y], brightness);
}
}
});
}
/// <summary>
/// Returns a <see cref="Color"/> with the brightness adjusted.
/// </summary>
/// <param name="color">The source color.</param>
/// <param name="brightness">The brightness adjustment factor.</param>
/// <returns>
/// The <see cref="Color"/>.
/// </returns>
private static Color AdjustBrightness(Color color, float brightness)
{
color = PixelOperations.ToLinear(color);
Vector3 vector3 = color.ToVector3();
vector3 += new Vector3(brightness, brightness, brightness);
return PixelOperations.ToSrgb(new Color(vector3, color.A));
}
}
}

2
src/ImageProcessor/Filters/ColorMatrix/ColorMatrix.cs

@ -8,7 +8,7 @@
namespace ImageProcessor.Filters
{
/// <summary>
/// Defines a 5 x 5 matrix that contains the coordinates for the RGBAW color space.
/// Defines a 5x5 matrix that contains the coordinates for the RGBAW color space.
/// </summary>
public sealed class ColorMatrix
{

1
src/ImageProcessor/Filters/Contrast.cs

@ -67,6 +67,7 @@ namespace ImageProcessor.Filters
{
color = PixelOperations.ToLinear(color);
// Seems to be faster than Vector3.
color.R -= 0.5f;
color.R *= contrast;
color.R += 0.5f;

78
src/ImageProcessor/Filters/Saturation.cs

@ -0,0 +1,78 @@
// <copyright file="Saturation.cs" company="James South">
// Copyright (c) James South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageProcessor.Filters
{
using System;
using System.Numerics;
using System.Threading.Tasks;
/// <summary>
/// An <see cref="IImageProcessor"/> to change the saturation of an <see cref="Image"/>.
/// </summary>
public class Saturation : ParallelImageProcessor
{
/// <summary>
/// Initializes a new instance of the <see cref="Saturation"/> class.
/// </summary>
/// <param name="saturation">The new saturation of the image. Must be between -100 and 100.</param>
/// <exception cref="ArgumentException">
/// <paramref name="saturation"/> is less than -100 or is greater than 100.
/// </exception>
public Saturation(int saturation)
{
Guard.MustBeBetweenOrEqualTo(saturation, -100, 100, nameof(saturation));
this.Value = saturation;
}
/// <summary>
/// Gets the saturation value.
/// </summary>
public int Value { get; }
/// <inheritdoc/>
protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
{
float saturation = this.Value / 100f;
int sourceY = sourceRectangle.Y;
int sourceBottom = sourceRectangle.Bottom;
int startX = sourceRectangle.X;
int endX = sourceRectangle.Right;
Parallel.For(
startY,
endY,
y =>
{
if (y >= sourceY && y < sourceBottom)
{
for (int x = startX; x < endX; x++)
{
target[x, y] = AdjustSaturation(source[x, y], saturation);
}
}
});
}
/// <summary>
/// Returns a <see cref="Color"/> with the saturation adjusted.
/// </summary>
/// <param name="color">The source color.</param>
/// <param name="saturation">The saturation adjustment factor.</param>
/// <returns>
/// The <see cref="Color"/>.
/// </returns>
private static Color AdjustSaturation(Color color, float saturation)
{
//color = PixelOperations.ToLinear(color);
// TODO: This can be done with a matrix. But why can I not get conversion to work?
Hsv hsv = color;
return new Hsv(hsv.H, saturation, hsv.V);
//return PixelOperations.ToSrgb(newHsv);
}
}
}

3
src/ImageProcessor/ImageProcessor.csproj

@ -48,6 +48,9 @@
<Compile Include="Common\Extensions\EnumerableExtensions.cs" />
<Compile Include="Common\Helpers\ImageMaths.cs" />
<Compile Include="Common\Helpers\PixelOperations.cs" />
<Compile Include="Filters\Saturation.cs" />
<Compile Include="Filters\ColorMatrix\GreyscaleMode.cs" />
<Compile Include="Filters\Brightness.cs" />
<Compile Include="Filters\Invert.cs" />
<Compile Include="Filters\Alpha.cs" />
<Compile Include="Filters\ColorMatrix\ColorMatrix.cs" />

18
tests/ImageProcessor.Tests/Processors/Filters/FilterTests.cs

@ -12,16 +12,20 @@ namespace ImageProcessor.Tests
{
public static readonly TheoryData<string, IImageProcessor> Filters = new TheoryData<string, IImageProcessor>
{
//{ "Brightness-50", new Brightness(50) },
//{ "Brightness--50", new Brightness(-50) },
//{ "Contrast-50", new Contrast(50) },
//{ "Contrast--50", new Contrast(-50) },
{ "Saturation-100", new Saturation(100) },
{ "Saturation--0", new Saturation(0) },
//{ "Alpha--50", new Alpha(50) },
{ "Invert", new Invert() },
{ "Sepia", new Sepia() },
{ "BlackWhite", new BlackWhite() },
{ "Lomograph", new Lomograph() },
{ "Polaroid", new Polaroid() },
{ "GreyscaleBt709", new GreyscaleBt709() },
{ "GreyscaleBt601", new GreyscaleBt601() },
//{ "Invert", new Invert() },
//{ "Sepia", new Sepia() },
//{ "BlackWhite", new BlackWhite() },
//{ "Lomograph", new Lomograph() },
//{ "Polaroid", new Polaroid() },
//{ "GreyscaleBt709", new GreyscaleBt709() },
//{ "GreyscaleBt601", new GreyscaleBt601() },
};
[Theory]

Loading…
Cancel
Save