Browse Source

pixelate no longer blanks out background

pull/195/head
Scott Williams 9 years ago
parent
commit
a999a0b33b
  1. 65
      src/ImageSharp/Processing/Processors/Effects/PixelateProcessor.cs
  2. 8
      tests/ImageSharp.Tests/Formats/Png/PngSmokeTests.cs
  3. 5
      tests/ImageSharp.Tests/ImageComparer.cs
  4. 79
      tests/ImageSharp.Tests/Processors/Filters/PixelateTest.cs
  5. 118
      tests/ImageSharp.Tests/TestUtilities/Attributes/ImageDataAttributeBase.cs
  6. 16
      tests/ImageSharp.Tests/TestUtilities/Attributes/WithBlankImageAttribute.cs
  7. 15
      tests/ImageSharp.Tests/TestUtilities/Attributes/WithFileAttribute.cs
  8. 19
      tests/ImageSharp.Tests/TestUtilities/Attributes/WithFileCollectionAttribute.cs
  9. 2
      tests/ImageSharp.Tests/TestUtilities/Attributes/WithMemberFactoryAttribute.cs
  10. 14
      tests/ImageSharp.Tests/TestUtilities/Attributes/WithTestPatternImageAttribute.cs
  11. 8
      tests/ImageSharp.Tests/TestUtilities/ImageProviders/TestImageProvider.cs
  12. 4
      tests/ImageSharp.Tests/TestUtilities/ImagingTestCaseUtility.cs
  13. 17
      tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs

65
src/ImageSharp/Processing/Processors/Effects/PixelateProcessor.cs

@ -66,51 +66,46 @@ namespace ImageSharp.Processing.Processors
// Get the range on the y-plane to choose from. // Get the range on the y-plane to choose from.
IEnumerable<int> range = EnumerableExtensions.SteppedRange(minY, i => i < maxY, size); IEnumerable<int> range = EnumerableExtensions.SteppedRange(minY, i => i < maxY, size);
using (PixelAccessor<TPixel> targetPixels = new PixelAccessor<TPixel>(source.Width, source.Height)) using (PixelAccessor<TPixel> sourcePixels = source.Lock())
{ {
using (PixelAccessor<TPixel> sourcePixels = source.Lock()) Parallel.ForEach(
{ range,
Parallel.ForEach( this.ParallelOptions,
range, y =>
this.ParallelOptions, {
y => int offsetY = y - startY;
int offsetPy = offset;
for (int x = minX; x < maxX; x += size)
{ {
int offsetY = y - startY; int offsetX = x - startX;
int offsetPy = offset; int offsetPx = offset;
for (int x = minX; x < maxX; x += size) // Make sure that the offset is within the boundary of the image.
while (offsetY + offsetPy >= maxY)
{ {
int offsetX = x - startX; offsetPy--;
int offsetPx = offset; }
// Make sure that the offset is within the boundary of the image.
while (offsetY + offsetPy >= maxY)
{
offsetPy--;
}
while (x + offsetPx >= maxX) while (x + offsetPx >= maxX)
{ {
offsetPx--; offsetPx--;
} }
// Get the pixel color in the centre of the soon to be pixelated area. // Get the pixel color in the centre of the soon to be pixelated area.
// ReSharper disable AccessToDisposedClosure // ReSharper disable AccessToDisposedClosure
TPixel pixel = sourcePixels[offsetX + offsetPx, offsetY + offsetPy]; TPixel pixel = sourcePixels[offsetX + offsetPx, offsetY + offsetPy];
// For each pixel in the pixelate size, set it to the centre color. // For each pixel in the pixelate size, set it to the centre color.
for (int l = offsetY; l < offsetY + size && l < maxY; l++) for (int l = offsetY; l < offsetY + size && l < maxY; l++)
{
for (int k = offsetX; k < offsetX + size && k < maxX; k++)
{ {
for (int k = offsetX; k < offsetX + size && k < maxX; k++) sourcePixels[k, l] = pixel;
{
targetPixels[k, l] = pixel;
}
} }
} }
}); }
});
source.SwapPixelsBuffers(targetPixels);
}
} }
} }
} }

8
tests/ImageSharp.Tests/Formats/Png/PngSmokeTests.cs

@ -20,7 +20,7 @@ namespace ImageSharp.Tests.Formats.Png
public class PngSmokeTests public class PngSmokeTests
{ {
[Theory] [Theory]
[WithTestPatternImages(300, 300, PixelTypes.All)] [WithTestPatternImages(300, 300, PixelTypes.StandardImageClass)]
public void GeneralTest<TPixel>(TestImageProvider<TPixel> provider) public void GeneralTest<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
@ -41,7 +41,7 @@ namespace ImageSharp.Tests.Formats.Png
} }
[Theory] [Theory]
[WithTestPatternImages(100, 100, PixelTypes.All)] [WithTestPatternImages(100, 100, PixelTypes.StandardImageClass)]
public void CanSaveIndexedPng<TPixel>(TestImageProvider<TPixel> provider) public void CanSaveIndexedPng<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
@ -56,7 +56,7 @@ namespace ImageSharp.Tests.Formats.Png
using (Image img2 = Image.Load(ms, new PngDecoder())) using (Image img2 = Image.Load(ms, new PngDecoder()))
{ {
// img2.Save(provider.Utility.GetTestOutputFileName("bmp", "_loaded"), new BmpEncoder()); // img2.Save(provider.Utility.GetTestOutputFileName("bmp", "_loaded"), new BmpEncoder());
ImageComparer.CheckSimilarity(image, img2); ImageComparer.CheckSimilarity(image, img2, 0.03f);
} }
} }
} }
@ -105,7 +105,7 @@ namespace ImageSharp.Tests.Formats.Png
//} //}
[Theory] [Theory]
[WithTestPatternImages(300, 300, PixelTypes.All)] [WithTestPatternImages(300, 300, PixelTypes.StandardImageClass)]
public void Resize<TPixel>(TestImageProvider<TPixel> provider) public void Resize<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {

5
tests/ImageSharp.Tests/ImageComparer.cs

@ -73,7 +73,7 @@
if (b > segmentThreshold) { diffPixels++; } if (b > segmentThreshold) { diffPixels++; }
} }
return diffPixels / (scalingFactor * scalingFactor); return (float)diffPixels / (float)(scalingFactor * scalingFactor);
} }
private static Fast2DArray<byte> GetDifferences<TPixelA, TPixelB>(Image<TPixelA> source, Image<TPixelB> target, int scalingFactor) private static Fast2DArray<byte> GetDifferences<TPixelA, TPixelB>(Image<TPixelA> source, Image<TPixelB> target, int scalingFactor)
@ -88,7 +88,8 @@
{ {
for (int x = 0; x < scalingFactor; x++) for (int x = 0; x < scalingFactor; x++)
{ {
differences[x, y] = (byte)Math.Abs(firstGray[x, y] - secondGray[x, y]); var diff = firstGray[x, y] - secondGray[x, y];
differences[x, y] = (byte)Math.Abs(diff);
} }
} }

79
tests/ImageSharp.Tests/Processors/Filters/PixelateTest.cs

@ -6,10 +6,10 @@
namespace ImageSharp.Tests namespace ImageSharp.Tests
{ {
using System.IO; using System.IO;
using ImageSharp.PixelFormats;
using Xunit; using Xunit;
public class PixelateTest : FileTestBase public class PixelateTest
{ {
public static readonly TheoryData<int> PixelateValues public static readonly TheoryData<int> PixelateValues
= new TheoryData<int> = new TheoryData<int>
@ -19,37 +19,74 @@ namespace ImageSharp.Tests
}; };
[Theory] [Theory]
[MemberData(nameof(PixelateValues))] [WithTestPatternImages(nameof(PixelateValues), 320, 240, PixelTypes.StandardImageClass)]
public void ImageShouldApplyPixelateFilter(int value) public void ImageShouldApplyPixelateFilter<TPixel>(TestImageProvider<TPixel> provider, int value)
where TPixel : struct, IPixel<TPixel>
{ {
string path = CreateOutputDirectory("Pixelate"); using (Image<TPixel> image = provider.GetImage())
foreach (TestFile file in Files)
{ {
string filename = file.GetFileName(value); image.Pixelate(value)
Image image = file.CreateImage(); .DebugSave(provider, new
{
size = value
});
using (FileStream output = File.OpenWrite($"{path}/{filename}")) using (PixelAccessor<TPixel> pixels = image.Lock())
{ {
image.Pixelate(value) for (int y = 0; y < pixels.Height; y += value)
.Save(output); {
for (int x = 0; x < pixels.Width; x += value)
{
TPixel source = pixels[x, y];
for (int pixY = y; pixY < y + value && pixY < pixels.Height; pixY++)
{
for (int pixX = x; pixX < x + value && pixX < pixels.Width; pixX++)
{
Assert.Equal(source, pixels[pixX, pixY]);
}
}
}
}
} }
} }
} }
[Theory] [Theory]
[MemberData(nameof(PixelateValues))] [WithTestPatternImages(nameof(PixelateValues), 320, 240, PixelTypes.StandardImageClass)]
public void ImageShouldApplyPixelateFilterInBox(int value) public void ImageShouldApplyPixelateFilterInBox<TPixel>(TestImageProvider<TPixel> provider, int value)
where TPixel : struct, IPixel<TPixel>
{ {
string path = this.CreateOutputDirectory("Pixelate"); using (Image<TPixel> source = provider.GetImage())
using (Image<TPixel> image = new Image<TPixel>(source))
foreach (TestFile file in Files)
{ {
string filename = file.GetFileName(value + "-InBox"); Rectangle rect = new Rectangle(image.Width/4, image.Height / 4, image.Width / 2, image.Height / 2);
using (Image image = file.CreateImage())
using (FileStream output = File.OpenWrite($"{path}/{filename}")) image.Pixelate(value, rect)
.DebugSave(provider, new
{
size = value
});
using (PixelAccessor<TPixel> pixels = image.Lock())
using (PixelAccessor<TPixel> sourcePixels = source.Lock())
{ {
image.Pixelate(value, new Rectangle(10, 10, image.Width / 2, image.Height / 2)).Save(output); for (int y = 0; y < pixels.Height; y++)
{
for (int x = 0; x < pixels.Width; x++)
{
var tx = x;
var ty = y;
TPixel sourceColor = sourcePixels[tx, ty];
if (rect.Contains(tx, ty))
{
var sourceX = tx - ((tx - rect.Left) % value) + (value / 2);
var sourceY = ty - ((ty - rect.Top) % value) + (value / 2);
sourceColor = pixels[sourceX, sourceY];
}
Assert.Equal(sourceColor, pixels[tx, ty]);
}
}
} }
} }
} }

118
tests/ImageSharp.Tests/TestUtilities/Attributes/ImageDataAttributeBase.cs

@ -21,26 +21,72 @@ namespace ImageSharp.Tests
protected readonly PixelTypes PixelTypes; protected readonly PixelTypes PixelTypes;
protected ImageDataAttributeBase(PixelTypes pixelTypes, object[] additionalParameters) protected ImageDataAttributeBase(string memberName, PixelTypes pixelTypes, object[] additionalParameters)
{ {
this.PixelTypes = pixelTypes; this.PixelTypes = pixelTypes;
this.AdditionalParameters = additionalParameters; this.AdditionalParameters = additionalParameters;
this.MemberName = memberName;
} }
public string MemberName { get; private set; }
public Type MemberType { get; set; }
public override IEnumerable<object[]> GetData(MethodInfo testMethod) public override IEnumerable<object[]> GetData(MethodInfo testMethod)
{ {
TypeInfo type = testMethod.GetParameters().First().ParameterType.GetTypeInfo(); IEnumerable<object[]> addedRows = Enumerable.Empty<object[]>();
if (!type.IsGenericType || type.GetGenericTypeDefinition() != typeof(TestImageProvider<>)) if (!string.IsNullOrWhiteSpace(this.MemberName))
{
Type type = this.MemberType ?? testMethod.DeclaringType;
Func<object> accessor = GetPropertyAccessor(type) ?? GetFieldAccessor(type);// ?? GetMethodAccessor(type);
if (accessor != null)
{
object obj = accessor();
if (obj is IEnumerable<object> memberItems)
{
addedRows = memberItems.Select(x => x as object[]);
if (addedRows.Any(x => x == null))
{
throw new ArgumentException($"Property {MemberName} on {MemberType ?? testMethod.DeclaringType} yielded an item that is not an object[]");
}
}
}
}
if (!addedRows.Any())
{ {
yield return this.AdditionalParameters; addedRows = new[] { new object[0] };
}
bool firstIsprovider = FirstIsProvider(testMethod);
IEnumerable<object[]> dataItems = Enumerable.Empty<object[]>();
if (firstIsprovider)
{
return InnerGetData(testMethod, addedRows);
} }
else else
{ {
foreach (KeyValuePair<PixelTypes, Type> kv in this.PixelTypes.ExpandAllTypes()) return addedRows.Select(x => x.Concat(this.AdditionalParameters).ToArray());
{ }
Type factoryType = typeof(TestImageProvider<>).MakeGenericType(kv.Value); }
private bool FirstIsProvider(MethodInfo testMethod)
{
TypeInfo dataType = testMethod.GetParameters().First().ParameterType.GetTypeInfo();
return dataType.IsGenericType && dataType.GetGenericTypeDefinition() == typeof(TestImageProvider<>);
}
private IEnumerable<object[]> InnerGetData(MethodInfo testMethod, IEnumerable<object[]> memberData)
{
foreach (KeyValuePair<PixelTypes, Type> kv in this.PixelTypes.ExpandAllTypes())
{
Type factoryType = typeof(TestImageProvider<>).MakeGenericType(kv.Value);
foreach (object[] originalFacoryMethodArgs in this.GetAllFactoryMethodArgs(testMethod, factoryType)) foreach (object[] originalFacoryMethodArgs in this.GetAllFactoryMethodArgs(testMethod, factoryType))
{
foreach (object[] row in memberData)
{ {
object[] actualFactoryMethodArgs = new object[originalFacoryMethodArgs.Length + 2]; object[] actualFactoryMethodArgs = new object[originalFacoryMethodArgs.Length + 2];
Array.Copy(originalFacoryMethodArgs, actualFactoryMethodArgs, originalFacoryMethodArgs.Length); Array.Copy(originalFacoryMethodArgs, actualFactoryMethodArgs, originalFacoryMethodArgs.Length);
@ -50,9 +96,10 @@ namespace ImageSharp.Tests
object factory = factoryType.GetMethod(this.GetFactoryMethodName(testMethod)) object factory = factoryType.GetMethod(this.GetFactoryMethodName(testMethod))
.Invoke(null, actualFactoryMethodArgs); .Invoke(null, actualFactoryMethodArgs);
object[] result = new object[this.AdditionalParameters.Length + 1]; object[] result = new object[this.AdditionalParameters.Length + 1 + row.Length];
result[0] = factory; result[0] = factory;
Array.Copy(this.AdditionalParameters, 0, result, 1, this.AdditionalParameters.Length); Array.Copy(row, 0, result, 1, row.Length);
Array.Copy(this.AdditionalParameters, 0, result, 1 + row.Length, this.AdditionalParameters.Length);
yield return result; yield return result;
} }
} }
@ -71,5 +118,56 @@ namespace ImageSharp.Tests
} }
protected abstract string GetFactoryMethodName(MethodInfo testMethod); protected abstract string GetFactoryMethodName(MethodInfo testMethod);
Func<object> GetFieldAccessor(Type type)
{
FieldInfo fieldInfo = null;
for (Type reflectionType = type; reflectionType != null; reflectionType = reflectionType.GetTypeInfo().BaseType)
{
fieldInfo = reflectionType.GetRuntimeField(MemberName);
if (fieldInfo != null)
break;
}
if (fieldInfo == null || !fieldInfo.IsStatic)
return null;
return () => fieldInfo.GetValue(null);
}
//Func<object> GetMethodAccessor(Type type)
//{
// MethodInfo methodInfo = null;
// var parameterTypes = Parameters == null ? new Type[0] : Parameters.Select(p => p?.GetType()).ToArray();
// for (var reflectionType = type; reflectionType != null; reflectionType = reflectionType.GetTypeInfo().BaseType)
// {
// methodInfo = reflectionType.GetRuntimeMethods()
// .FirstOrDefault(m => m.Name == MemberName && ParameterTypesCompatible(m.GetParameters(), parameterTypes));
// if (methodInfo != null)
// break;
// }
// if (methodInfo == null || !methodInfo.IsStatic)
// return null;
// return () => methodInfo.Invoke(null, Parameters);
//}
Func<object> GetPropertyAccessor(Type type)
{
PropertyInfo propInfo = null;
for (Type reflectionType = type; reflectionType != null; reflectionType = reflectionType.GetTypeInfo().BaseType)
{
propInfo = reflectionType.GetRuntimeProperty(MemberName);
if (propInfo != null)
break;
}
if (propInfo == null || propInfo.GetMethod == null || !propInfo.GetMethod.IsStatic)
return null;
return () => propInfo.GetValue(null, null);
}
} }
} }

16
tests/ImageSharp.Tests/TestUtilities/Attributes/WithBlankImageAttribute.cs

@ -22,7 +22,21 @@ namespace ImageSharp.Tests
/// <param name="pixelTypes">The requested parameter</param> /// <param name="pixelTypes">The requested parameter</param>
/// <param name="additionalParameters">Additional theory parameter values</param> /// <param name="additionalParameters">Additional theory parameter values</param>
public WithBlankImagesAttribute(int width, int height, PixelTypes pixelTypes, params object[] additionalParameters) public WithBlankImagesAttribute(int width, int height, PixelTypes pixelTypes, params object[] additionalParameters)
: base(pixelTypes, additionalParameters) : base(null, pixelTypes, additionalParameters)
{
this.Width = width;
this.Height = height;
}
/// <summary>
/// Triggers passing an <see cref="TestImageProvider{TPixel}"/> that produces a blank image of size width * height
/// </summary>
/// <param name="width">The required width</param>
/// <param name="height">The required height</param>
/// <param name="pixelTypes">The requested parameter</param>
/// <param name="additionalParameters">Additional theory parameter values</param>
public WithBlankImagesAttribute(string memberData, int width, int height, PixelTypes pixelTypes, params object[] additionalParameters)
: base(memberData, pixelTypes, additionalParameters)
{ {
this.Width = width; this.Width = width;
this.Height = height; this.Height = height;

15
tests/ImageSharp.Tests/TestUtilities/Attributes/WithFileAttribute.cs

@ -24,7 +24,20 @@ namespace ImageSharp.Tests
/// <param name="pixelTypes">The requested pixel types</param> /// <param name="pixelTypes">The requested pixel types</param>
/// <param name="additionalParameters">Additional theory parameter values</param> /// <param name="additionalParameters">Additional theory parameter values</param>
public WithFileAttribute(string fileName, PixelTypes pixelTypes, params object[] additionalParameters) public WithFileAttribute(string fileName, PixelTypes pixelTypes, params object[] additionalParameters)
: base(pixelTypes, additionalParameters) : base(null, pixelTypes, additionalParameters)
{
this.fileName = fileName;
}
/// <summary>
/// Triggers passing <see cref="TestImageProvider{TPixel}"/> instances which read an image from the given file
/// One <see cref="TestImageProvider{TPixel}"/> instance will be passed for each the pixel format defined by the pixelTypes parameter
/// </summary>
/// <param name="fileName">The name of the file</param>
/// <param name="pixelTypes">The requested pixel types</param>
/// <param name="additionalParameters">Additional theory parameter values</param>
public WithFileAttribute(string fileName, string dataMemberName, PixelTypes pixelTypes, params object[] additionalParameters)
: base(dataMemberName, pixelTypes, additionalParameters)
{ {
this.fileName = fileName; this.fileName = fileName;
} }

19
tests/ImageSharp.Tests/TestUtilities/Attributes/WithFileCollectionAttribute.cs

@ -29,7 +29,24 @@ namespace ImageSharp.Tests
string enumeratorMemberName, string enumeratorMemberName,
PixelTypes pixelTypes, PixelTypes pixelTypes,
params object[] additionalParameters) params object[] additionalParameters)
: base(pixelTypes, additionalParameters) : base(null, pixelTypes, additionalParameters)
{
this.enumeratorMemberName = enumeratorMemberName;
}
/// <summary>
/// Triggers passing <see cref="TestImageProvider{TPixel}"/> instances which read an image for each file being enumerated by the (static) test class field/property defined by enumeratorMemberName
/// <see cref="TestImageProvider{TPixel}"/> instances will be passed for each the pixel format defined by the pixelTypes parameter
/// </summary>
/// <param name="enumeratorMemberName">The name of the static test class field/property enumerating the files</param>
/// <param name="pixelTypes">The requested pixel types</param>
/// <param name="additionalParameters">Additional theory parameter values</param>
public WithFileCollectionAttribute(
string enumeratorMemberName,
string DataMemberName,
PixelTypes pixelTypes,
params object[] additionalParameters)
: base(DataMemberName, pixelTypes, additionalParameters)
{ {
this.enumeratorMemberName = enumeratorMemberName; this.enumeratorMemberName = enumeratorMemberName;
} }

2
tests/ImageSharp.Tests/TestUtilities/Attributes/WithMemberFactoryAttribute.cs

@ -26,7 +26,7 @@ namespace ImageSharp.Tests
/// <param name="pixelTypes">The requested pixel types</param> /// <param name="pixelTypes">The requested pixel types</param>
/// <param name="additionalParameters">Additional theory parameter values</param> /// <param name="additionalParameters">Additional theory parameter values</param>
public WithMemberFactoryAttribute(string memberMethodName, PixelTypes pixelTypes, params object[] additionalParameters) public WithMemberFactoryAttribute(string memberMethodName, PixelTypes pixelTypes, params object[] additionalParameters)
: base(pixelTypes, additionalParameters) : base(null, pixelTypes, additionalParameters)
{ {
this.memberMethodName = memberMethodName; this.memberMethodName = memberMethodName;
} }

14
tests/ImageSharp.Tests/TestUtilities/Attributes/WithTestPatternImageAttribute.cs

@ -22,7 +22,19 @@ namespace ImageSharp.Tests
/// <param name="pixelTypes">The requested parameter</param> /// <param name="pixelTypes">The requested parameter</param>
/// <param name="additionalParameters">Additional theory parameter values</param> /// <param name="additionalParameters">Additional theory parameter values</param>
public WithTestPatternImagesAttribute(int width, int height, PixelTypes pixelTypes, params object[] additionalParameters) public WithTestPatternImagesAttribute(int width, int height, PixelTypes pixelTypes, params object[] additionalParameters)
: base(pixelTypes, additionalParameters) : this(null, width, height, pixelTypes,additionalParameters)
{
}
/// <summary>
/// Triggers passing an <see cref="TestImageProvider{TPixel}"/> that produces a test pattern image of size width * height
/// </summary>
/// <param name="width">The required width</param>
/// <param name="height">The required height</param>
/// <param name="pixelTypes">The requested parameter</param>
/// <param name="additionalParameters">Additional theory parameter values</param>
public WithTestPatternImagesAttribute(string memberData, int width, int height, PixelTypes pixelTypes, params object[] additionalParameters)
: base(memberData, pixelTypes, additionalParameters)
{ {
this.Width = width; this.Width = width;
this.Height = height; this.Height = height;

8
tests/ImageSharp.Tests/TestUtilities/ImageProviders/TestImageProvider.cs

@ -11,12 +11,16 @@ namespace ImageSharp.Tests
using ImageSharp.PixelFormats; using ImageSharp.PixelFormats;
using Xunit.Abstractions; using Xunit.Abstractions;
public interface ITestImageProvider
{
PixelTypes PixelType { get; }
ImagingTestCaseUtility Utility { get; }
}
/// <summary> /// <summary>
/// Provides <see cref="Image{TPixel}" /> instances for parametric unit tests. /// Provides <see cref="Image{TPixel}" /> instances for parametric unit tests.
/// </summary> /// </summary>
/// <typeparam name="TPixel">The pixel format of the image</typeparam> /// <typeparam name="TPixel">The pixel format of the image</typeparam>
public abstract partial class TestImageProvider<TPixel> public abstract partial class TestImageProvider<TPixel> : ITestImageProvider
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
public PixelTypes PixelType { get; private set; } = typeof(TPixel).GetPixelType(); public PixelTypes PixelType { get; private set; } = typeof(TPixel).GetPixelType();

4
tests/ImageSharp.Tests/TestUtilities/ImagingTestCaseUtility.cs

@ -97,10 +97,10 @@ namespace ImageSharp.Tests
/// <param name="extension">The requested extension</param> /// <param name="extension">The requested extension</param>
/// <param name="encoder">Optional encoder</param> /// <param name="encoder">Optional encoder</param>
/// <param name="options">Optional encoder options</param> /// <param name="options">Optional encoder options</param>
public void SaveTestOutputFile<TPixel>(Image<TPixel> image, string extension = null, IImageEncoder encoder = null, IEncoderOptions options = null) public void SaveTestOutputFile<TPixel>(Image<TPixel> image, string extension = null, IImageEncoder encoder = null, IEncoderOptions options = null, string tag = null)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
string path = this.GetTestOutputFileName(extension); string path = this.GetTestOutputFileName(extension: extension, tag:tag);
extension = Path.GetExtension(path); extension = Path.GetExtension(path);
IImageFormat format = GetImageFormatByExtension(extension); IImageFormat format = GetImageFormatByExtension(extension);

17
tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs

@ -3,19 +3,32 @@ namespace ImageSharp.Tests
{ {
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text; using System.Text;
using ImageSharp.PixelFormats; using ImageSharp.PixelFormats;
public static class TestImageExtensions public static class TestImageExtensions
{ {
public static void DebugSave<TPixel>(this Image<TPixel> img, TestImageProvider<TPixel> provider, string extension = "png") public static void DebugSave<TPixel>(this Image<TPixel> img, ITestImageProvider provider, object settings = null, string extension = "png")
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
string tag = null;
if (settings is string)
{
tag = (string)settings;
}
else if (settings != null)
{
var properties = settings.GetType().GetRuntimeProperties();
tag = string.Join("_", properties.ToDictionary(x => x.Name, x => x.GetValue(settings)).Select(x => $"{x.Key}-{x.Value}"));
}
if(!bool.TryParse(Environment.GetEnvironmentVariable("CI"), out bool isCI) || !isCI) if(!bool.TryParse(Environment.GetEnvironmentVariable("CI"), out bool isCI) || !isCI)
{ {
// we are running locally then we want to save it out // we are running locally then we want to save it out
provider.Utility.SaveTestOutputFile(img, extension); provider.Utility.SaveTestOutputFile(img, extension, tag: tag);
} }
} }
} }

Loading…
Cancel
Save