From fc7b42900d7d64a89dccc60561a53e3d8b00f4f2 Mon Sep 17 00:00:00 2001 From: Ionite Date: Fri, 4 Aug 2023 17:35:37 -0400 Subject: [PATCH] Add image processor and tests --- StabilityMatrix.Core/Helper/ImageProcessor.cs | 61 +++++++++++++++++++ .../Core/ImageProcessorTests.cs | 21 +++++++ 2 files changed, 82 insertions(+) create mode 100644 StabilityMatrix.Core/Helper/ImageProcessor.cs create mode 100644 StabilityMatrix.Tests/Core/ImageProcessorTests.cs diff --git a/StabilityMatrix.Core/Helper/ImageProcessor.cs b/StabilityMatrix.Core/Helper/ImageProcessor.cs new file mode 100644 index 00000000..69318237 --- /dev/null +++ b/StabilityMatrix.Core/Helper/ImageProcessor.cs @@ -0,0 +1,61 @@ +using SixLabors.ImageSharp; +using StabilityMatrix.Core.Extensions; + +namespace StabilityMatrix.Core.Helper; + +public static class ImageProcessor +{ + /// + /// Get the dimensions of a grid that can hold the given amount of images. + /// + public static (int rows, int columns) GetGridDimensionsFromImageCount(int count) + { + if (count <= 1) return (1, 1); + if (count == 2) return (1, 2); + + // Prefer one extra row over one extra column, + // the row count will be the floor of the square root + // and the column count will be floor of count / rows + var rows = (int) Math.Floor(Math.Sqrt(count)); + var columns = (int) Math.Floor((double) count / rows); + return (rows, columns); + } + + public static Image CreateImageGrid( + IReadOnlyList> images, + int spacing = 0) where TPixel : unmanaged, IPixel + { + var (rows, columns) = GetGridDimensionsFromImageCount(images.Count); + + var singleWidth = images[0].Width; + var singleHeight = images[0].Height; + + // Make output image + var output = new Image( + singleWidth * columns + spacing * (columns - 1), + singleHeight * rows + spacing * (rows - 1)); + + + // Draw images + foreach (var (row, column) in + Enumerable.Range(0, rows).Product(Enumerable.Range(0, columns))) + { + // Stop if we have drawn all images + var index = row * columns + column; + if (index >= images.Count) break; + + // Get image + var image = images[index]; + + // Draw image + output.Mutate(op => + { + op.DrawImage(image, + new Point(singleWidth * column + spacing * column, + singleHeight * row + spacing * row), 1); + }); + } + + return output; + } +} diff --git a/StabilityMatrix.Tests/Core/ImageProcessorTests.cs b/StabilityMatrix.Tests/Core/ImageProcessorTests.cs new file mode 100644 index 00000000..31477115 --- /dev/null +++ b/StabilityMatrix.Tests/Core/ImageProcessorTests.cs @@ -0,0 +1,21 @@ +using StabilityMatrix.Core.Helper; + +namespace StabilityMatrix.Tests.Core; + +[TestClass] +public class ImageProcessorTests +{ + [DataTestMethod] + [DataRow(0, 1, 1)] + [DataRow(1, 1, 1)] + [DataRow(4, 2, 2)] + [DataRow(8, 2, 4)] + [DataRow(12, 3, 4)] + [DataRow(20, 4, 5)] + public void TestGetGridDimensionsFromImageCount(int count, int expectedRow, int expectedCols) + { + var result = ImageProcessor.GetGridDimensionsFromImageCount(count); + Assert.AreEqual(expectedRow, result.rows); + Assert.AreEqual(expectedCols, result.columns); + } +}