mirror of https://github.com/SixLabors/ImageSharp
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
236 lines
7.7 KiB
236 lines
7.7 KiB
// <copyright file="ImagingTestCaseUtility.cs" company="James Jackson-South">
|
|
// Copyright (c) James Jackson-South and contributors.
|
|
// Licensed under the Apache License, Version 2.0.
|
|
// </copyright>
|
|
|
|
namespace ImageSharp.Tests
|
|
{
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
|
|
using ImageSharp.Formats;
|
|
using ImageSharp.PixelFormats;
|
|
|
|
/// <summary>
|
|
/// Utility class to provide information about the test image & the test case for the test code,
|
|
/// and help managing IO.
|
|
/// </summary>
|
|
public class ImagingTestCaseUtility : TestBase
|
|
{
|
|
/// <summary>
|
|
/// Name of the TPixel in the owner <see cref="TestImageProvider{TPixel}"/>
|
|
/// </summary>
|
|
public string PixelTypeName { get; set; } = String.Empty;
|
|
|
|
/// <summary>
|
|
/// The name of the file which is provided by <see cref="TestImageProvider{TPixel}"/>
|
|
/// Or a short string describing the image in the case of a non-file based image provider.
|
|
/// </summary>
|
|
public string SourceFileOrDescription { get; set; } = String.Empty;
|
|
|
|
/// <summary>
|
|
/// By default this is the name of the test class, but it's possible to change it
|
|
/// </summary>
|
|
public string TestGroupName { get; set; } = String.Empty;
|
|
|
|
/// <summary>
|
|
/// The name of the test case (by default)
|
|
/// </summary>
|
|
public string TestName { get; set; } = String.Empty;
|
|
|
|
|
|
private string GetTestOutputFileNameImpl(string extension, string tag)
|
|
{
|
|
string fn = String.Empty;
|
|
|
|
if (String.IsNullOrWhiteSpace(extension))
|
|
{
|
|
extension = null;
|
|
}
|
|
|
|
fn = Path.GetFileNameWithoutExtension(this.SourceFileOrDescription);
|
|
|
|
if (String.IsNullOrWhiteSpace(extension))
|
|
{
|
|
extension = Path.GetExtension(this.SourceFileOrDescription);
|
|
}
|
|
|
|
if (String.IsNullOrWhiteSpace(extension))
|
|
{
|
|
extension = ".bmp";
|
|
}
|
|
|
|
if (extension[0] != '.')
|
|
{
|
|
extension = '.' + extension;
|
|
}
|
|
|
|
if (fn != String.Empty) fn = '_' + fn;
|
|
|
|
string pixName = this.PixelTypeName;
|
|
if (pixName != String.Empty)
|
|
{
|
|
pixName = '_' + pixName;
|
|
}
|
|
|
|
tag = tag ?? String.Empty;
|
|
if (tag != String.Empty)
|
|
{
|
|
tag = '_' + tag;
|
|
}
|
|
|
|
|
|
return $"{this.GetTestOutputDir()}/{this.TestName}{pixName}{fn}{tag}{extension}";
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the recommended file name for the output of the test
|
|
/// </summary>
|
|
/// <param name="extension">The required extension</param>
|
|
/// <param name="settings">The settings modifying the output path</param>
|
|
/// <returns>The file test name</returns>
|
|
public string GetTestOutputFileName(string extension = null, object settings = null)
|
|
{
|
|
string tag = null;
|
|
string s = settings as string;
|
|
|
|
if (s != null)
|
|
{
|
|
tag = s;
|
|
}
|
|
else if (settings != null)
|
|
{
|
|
Type type = settings.GetType();
|
|
TypeInfo info = type.GetTypeInfo();
|
|
if (info.IsPrimitive || info.IsEnum || type == typeof(decimal))
|
|
{
|
|
tag = settings.ToString();
|
|
}
|
|
else
|
|
{
|
|
IEnumerable<PropertyInfo> properties = settings.GetType().GetRuntimeProperties();
|
|
|
|
tag = String.Join("_", properties.ToDictionary(x => x.Name, x => x.GetValue(settings)).Select(x => $"{x.Key}-{x.Value}"));
|
|
}
|
|
}
|
|
return this.GetTestOutputFileNameImpl(extension, tag);
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Encodes image by the format matching the required extension, than saves it to the recommended output file.
|
|
/// </summary>
|
|
/// <typeparam name="TPixel">The pixel format of the image</typeparam>
|
|
/// <param name="image">The image instance</param>
|
|
/// <param name="extension">The requested extension</param>
|
|
/// <param name="encoder">Optional encoder</param>
|
|
public void SaveTestOutputFile<TPixel>(
|
|
Image<TPixel> image,
|
|
string extension = null,
|
|
IImageEncoder encoder = null,
|
|
object testOutputDetails = null,
|
|
bool grayscale = false)
|
|
where TPixel : struct, IPixel<TPixel>
|
|
{
|
|
string path = this.GetTestOutputFileName(extension: extension, settings: testOutputDetails);
|
|
string extension1 = Path.GetExtension(path);
|
|
encoder = encoder ?? GetImageFormatByExtension(extension1, grayscale);
|
|
|
|
using (FileStream stream = File.OpenWrite(path))
|
|
{
|
|
image.Save(stream, encoder);
|
|
}
|
|
}
|
|
|
|
internal string GetReferenceOutputFileName(string extension = null, object settings = null) =>
|
|
TestEnvironment.GetReferenceOutputFileName(this.GetTestOutputFileName(extension, settings));
|
|
|
|
internal void Init(string typeName, string methodName)
|
|
{
|
|
this.TestGroupName = typeName;
|
|
this.TestName = methodName;
|
|
}
|
|
|
|
internal void Init(MethodInfo method)
|
|
{
|
|
this.Init(method.DeclaringType.Name, method.Name);
|
|
}
|
|
|
|
private static IImageEncoder GetImageFormatByExtension(string extension, bool grayscale)
|
|
{
|
|
extension = extension?.TrimStart('.');
|
|
var format = Configuration.Default.FindFormatByFileExtensions(extension);
|
|
IImageEncoder encoder = Configuration.Default.FindEncoder(format);
|
|
PngEncoder pngEncoder = encoder as PngEncoder;
|
|
if (pngEncoder != null)
|
|
{
|
|
pngEncoder = new PngEncoder();
|
|
encoder = pngEncoder;
|
|
pngEncoder.CompressionLevel = 9;
|
|
|
|
if (grayscale)
|
|
{
|
|
pngEncoder.PngColorType = PngColorType.Grayscale;
|
|
}
|
|
}
|
|
|
|
return encoder;
|
|
}
|
|
|
|
private string GetTestOutputDir()
|
|
{
|
|
string testGroupName = Path.GetFileNameWithoutExtension(this.TestGroupName);
|
|
return this.CreateOutputDirectory(testGroupName);
|
|
}
|
|
|
|
public static void ModifyPixel<TPixel>(ImageBase<TPixel> img, int x, int y, byte perChannelChange)
|
|
where TPixel : struct, IPixel<TPixel>
|
|
{
|
|
TPixel pixel = img[x, y];
|
|
var rgbaPixel = default(Rgba32);
|
|
pixel.ToRgba32(ref rgbaPixel);
|
|
|
|
if (rgbaPixel.R + perChannelChange <= 255)
|
|
{
|
|
rgbaPixel.R += perChannelChange;
|
|
}
|
|
else
|
|
{
|
|
rgbaPixel.R -= perChannelChange;
|
|
}
|
|
|
|
if (rgbaPixel.G + perChannelChange <= 255)
|
|
{
|
|
rgbaPixel.G += perChannelChange;
|
|
}
|
|
else
|
|
{
|
|
rgbaPixel.G -= perChannelChange;
|
|
}
|
|
|
|
if (rgbaPixel.B + perChannelChange <= 255)
|
|
{
|
|
rgbaPixel.B += perChannelChange;
|
|
}
|
|
else
|
|
{
|
|
rgbaPixel.B -= perChannelChange;
|
|
}
|
|
|
|
if (rgbaPixel.A + perChannelChange <= 255)
|
|
{
|
|
rgbaPixel.A += perChannelChange;
|
|
}
|
|
else
|
|
{
|
|
rgbaPixel.A -= perChannelChange;
|
|
}
|
|
|
|
pixel.PackFromRgba32(rgbaPixel);
|
|
img[x, y] = pixel;
|
|
}
|
|
}
|
|
}
|