Browse Source

More edge detection

TODO: Fix range in loop

Former-commit-id: ae78dcd736549a1e44c5de136668ba6661c62cd7
af/merge-core
James South 12 years ago
parent
commit
2fe297d43d
  1. 16
      src/ImageProcessor/ImageFactory.cs
  2. 4
      src/ImageProcessor/ImageProcessor.csproj
  3. 2
      src/ImageProcessor/Imaging/Convolution.cs
  4. 137
      src/ImageProcessor/Imaging/EdgeDetection/ConvolutionFilter.cs
  5. 68
      src/ImageProcessor/Imaging/EdgeDetection/CostellaEdgeFilter.cs
  6. 25
      src/ImageProcessor/Imaging/EdgeDetection/IEdgeFilter.cs
  7. 52
      src/ImageProcessor/Imaging/EdgeDetection/PrewittEdgeFilter.cs
  8. 50
      src/ImageProcessor/Imaging/EdgeDetection/RobertsCrossEdgeFilter.cs
  9. 52
      src/ImageProcessor/Imaging/EdgeDetection/ScharrEdgeFilter.cs
  10. 47
      src/ImageProcessor/Imaging/EdgeDetection/SobelEdgeFilter.cs
  11. 4
      src/ImageProcessor/Imaging/FastBitmap.cs
  12. 48
      src/ImageProcessor/Processors/DetectEdges.cs
  13. 2
      src/ImageProcessor/Settings.StyleCop
  14. 4
      src/ImageProcessorConsole/Program.cs
  15. 1
      src/ImageProcessorConsole/images/input/Bikesgray.png.REMOVED.git-id
  16. 1
      src/ImageProcessorConsole/images/input/Valve_original_(1).PNG.REMOVED.git-id
  17. 3
      src/ImageProcessorConsole/images/input/circle2.png
  18. 3
      src/ImageProcessorConsole/images/output/Bikesgray.png
  19. 3
      src/ImageProcessorConsole/images/output/Valve_original_(1).PNG
  20. 3
      src/ImageProcessorConsole/images/output/circle.png
  21. 3
      src/ImageProcessorConsole/images/output/circle2.png
  22. 1
      src/ImageProcessorConsole/images/output/monster.png.REMOVED.git-id
  23. 1
      src/ImageProcessorConsole/images/output/night-bridge.png.REMOVED.git-id

16
src/ImageProcessor/ImageFactory.cs

@ -441,11 +441,23 @@ namespace ImageProcessor
return this;
}
public ImageFactory DetectEdges(IEdgeFilter filter)
/// <summary>
/// Detects the edges in the current image.
/// </summary>
/// <param name="filter">
/// The <see cref="IEdgeFilter"/> to detect edges with.
/// </param>
/// <param name="greyscale">
/// Whether to convert the image to greyscale first - Defaults to true.
/// </param>
/// <returns>
/// The current instance of the <see cref="T:ImageProcessor.ImageFactory"/> class.
/// </returns>
public ImageFactory DetectEdges(IEdgeFilter filter, bool greyscale = true)
{
if (this.ShouldProcess)
{
DetectEdges detectEdges = new DetectEdges { DynamicParameter = filter };
DetectEdges detectEdges = new DetectEdges { DynamicParameter = new Tuple<IEdgeFilter, bool>(filter, greyscale) };
this.CurrentImageFormat.ApplyProcessor(detectEdges.ProcessImage, this);
}

4
src/ImageProcessor/ImageProcessor.csproj

@ -78,6 +78,10 @@
<Compile Include="Imaging\Colors\YCbCrColor.cs" />
<Compile Include="Imaging\EdgeDetection\ConvolutionFilter.cs" />
<Compile Include="Imaging\EdgeDetection\IEdgeFilter.cs" />
<Compile Include="Imaging\EdgeDetection\ScharrEdgeFilter.cs" />
<Compile Include="Imaging\EdgeDetection\RobertsCrossEdgeFilter.cs" />
<Compile Include="Imaging\EdgeDetection\PrewittEdgeFilter.cs" />
<Compile Include="Imaging\EdgeDetection\CostellaEdgeFilter.cs" />
<Compile Include="Imaging\EdgeDetection\SobelEdgeFilter.cs" />
<Compile Include="Imaging\FastBitmap.cs">
<SubType>Code</SubType>

2
src/ImageProcessor/Imaging/Convolution.cs

@ -26,7 +26,7 @@ namespace ImageProcessor.Imaging
private readonly double standardDeviation = 1.4;
/// <summary>
/// Whether to use use dynamic divider for edges.
/// Whether to use dynamic divider for edges.
/// </summary>
private bool useDynamicDividerForEdges = true;

137
src/ImageProcessor/Imaging/EdgeDetection/ConvolutionFilter.cs

@ -1,4 +1,13 @@

// --------------------------------------------------------------------------------------------------------------------
// <copyright file="ConvolutionFilter.cs" company="James South">
// Copyright (c) James South.
// Licensed under the Apache License, Version 2.0.
// </copyright>
// <summary>
// The convolution filter for applying gradient operators to detect edges within an image.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace ImageProcessor.Imaging.EdgeDetection
{
using System;
@ -6,61 +15,137 @@ namespace ImageProcessor.Imaging.EdgeDetection
using System.Drawing.Imaging;
using ImageProcessor.Common.Extensions;
using ImageProcessor.Imaging.Filters;
/// <summary>
/// http://pastebin.com/xHHD3pXi
/// The convolution filter for applying gradient operators to detect edges within an image.
/// </summary>
public class ConvolutionFilter
{
/// <summary>
/// The edge filter.
/// </summary>
private readonly IEdgeFilter edgeFilter;
public ConvolutionFilter(IEdgeFilter edgeFilter)
/// <summary>
/// Whether to produce a greyscale output.
/// </summary>
private readonly bool greyscale;
/// <summary>
/// Initializes a new instance of the <see cref="ConvolutionFilter"/> class.
/// </summary>
/// <param name="edgeFilter">
/// The <see cref="IEdgeFilter"/> to apply.
/// </param>
/// <param name="greyscale">
/// Whether to produce a greyscale output.
/// </param>
public ConvolutionFilter(IEdgeFilter edgeFilter, bool greyscale)
{
this.edgeFilter = edgeFilter;
this.greyscale = greyscale;
}
/// <summary>
/// Processes the given bitmap to apply the current instances <see cref="IEdgeFilter"/>.
/// </summary>
/// <param name="source">The image to process.</param>
/// <returns>A processed bitmap.</returns>
public Bitmap ProcessFilter(Bitmap source)
{
double[,] horizontalFilter = this.edgeFilter.HorizontalMatrix;
double[,] verticallFilter = this.edgeFilter.VerticalMatrix;
int width = source.Width;
int height = source.Height;
int maxWidth = width - 1;
int maxHeight = height - 1;
Bitmap destination = new Bitmap(width, height, PixelFormat.Format32bppArgb);
using (FastBitmap sourceBitmap = new FastBitmap(source))
Bitmap input = new Bitmap(width, height, PixelFormat.Format32bppArgb);
using (Graphics graphics = Graphics.FromImage(input))
{
using (FastBitmap destinationBitmap = new FastBitmap(destination))
Rectangle rectangle = new Rectangle(0, 0, width, height);
if (this.greyscale)
{
for (int y = 1; y < maxHeight; y++)
// If it's greyscale apply a colormatix to the image.
using (ImageAttributes attributes = new ImageAttributes())
{
for (int x = 1; x < maxWidth; x++)
{
double newX = 0;
double newY = 0;
attributes.SetColorMatrix(ColorMatrixes.GreyScale);
graphics.DrawImage(source, rectangle, 0, 0, width, height, GraphicsUnit.Pixel, attributes);
}
}
else
{
// Fixes an issue with transparency not converting properly.
graphics.Clear(Color.Transparent);
graphics.DrawImage(source, rectangle);
}
}
try
{
double[,] horizontalFilter = this.edgeFilter.HorizontalGradientOperator;
double[,] verticallFilter = this.edgeFilter.VerticalGradientOperator;
int filterXOffset = (horizontalFilter.GetLength(1) - 1) / 2;
int filterYOffset = (horizontalFilter.GetLength(0) - 1) / 2;
int maxWidth = width - filterXOffset;
int maxHeight = height - filterYOffset;
for (int hw = -1; hw < 2; hw++)
using (FastBitmap sourceBitmap = new FastBitmap(input))
{
using (FastBitmap destinationBitmap = new FastBitmap(destination))
{
// Loop through the pixels.
for (int y = filterYOffset; y < maxHeight; y++)
{
for (int x = filterXOffset; x < maxWidth; x++)
{
for (int wi = -1; wi < 2; wi++)
double rX = 0;
double rY = 0;
double gX = 0;
double gY = 0;
double bX = 0;
double bY = 0;
// Apply each matrix multiplier to the color components for each pixel.
for (int fy = -1; fy < filterYOffset; fy++)
{
double component = sourceBitmap.GetPixel(x + wi, y + hw).B;
newX += horizontalFilter[hw + 1, wi + 1] * component;
newY += verticallFilter[hw + 1, wi + 1] * component;
for (int fx = -1; fx < filterXOffset; fx++)
{
Color currentColor = sourceBitmap.GetPixel(x + fx, y + fy);
double r = currentColor.R;
double g = currentColor.G;
double b = currentColor.B;
rX += horizontalFilter[fy + 1, fx + 1] * r;
rY += verticallFilter[fy + 1, fx + 1] * r;
gX += horizontalFilter[fy + 1, fx + 1] * g;
gY += verticallFilter[fy + 1, fx + 1] * g;
bX += horizontalFilter[fy + 1, fx + 1] * b;
bY += verticallFilter[fy + 1, fx + 1] * b;
}
}
}
byte value = Math.Sqrt((newX * newX) + (newY * newY)).ToByte();
Color tempcolor = Color.FromArgb(value, value, value);
destinationBitmap.SetPixel(x, y, tempcolor);
// Apply the equation and sanitize.
byte red = Math.Sqrt((rX * rX) + (rY * rY)).ToByte();
byte green = Math.Sqrt((gX * gX) + (gY * gY)).ToByte();
byte blue = Math.Sqrt((bX * bX) + (bY * bY)).ToByte();
Color newColor = Color.FromArgb(red, green, blue);
destinationBitmap.SetPixel(x, y, newColor);
}
}
}
}
}
finally
{
// We created a new image. Cleanup.
input.Dispose();
}
return destination;
}
}
}

68
src/ImageProcessor/Imaging/EdgeDetection/CostellaEdgeFilter.cs

@ -0,0 +1,68 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="CostellaEdgeFilter.cs" company="James South">
// Copyright (c) James South.
// Licensed under the Apache License, Version 2.0.
// </copyright>
// <summary>
// The Costella operator filter.
// <see href="http://johncostella.com/edgedetect/" />
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace ImageProcessor.Imaging.EdgeDetection
{
/// <summary>
/// The Costella operator filter.
/// <see href="http://johncostella.com/edgedetect/"/>
/// </summary>
public class CostellaEdgeFilter : IEdgeFilter
{
/// <summary>
/// Gets the horizontal gradient operator.
/// </summary>
public double[,] HorizontalGradientOperator
{
get
{
return new double[,]
{ { -1, -1, -1, -1, -1, },
{ -1, -1, -1, -1, -1, },
{ -1, -1, 24, -1, -1, },
{ -1, -1, -1, -1, -1, },
{ -1, -1, -1, -1, -1 }, };
return new double[,]
{
{ -1, -3, 0, 3, 1 },
{ -1, -3, 0, 3, 1 },
{ -1, -3, 0, 3, 1 },
{ -1, -3, 0, 3, 1 },
{ -1, -3, 0, 3, 1 }
};
}
}
/// <summary>
/// Gets the vertical gradient operator.
/// </summary>
public double[,] VerticalGradientOperator
{
get
{
return new double[,]
{ { -1, -1, -1, -1, -1, },
{ -1, -1, -1, -1, -1, },
{ -1, -1, 24, -1, -1, },
{ -1, -1, -1, -1, -1, },
{ -1, -1, -1, -1, -1 }, };
return new double[,]
{
{ 1, 1, 1, 1, 1 },
{ 3, 3, 3, 3, 3 },
{ 0, 0, 0, 0, 0 },
{ -3, -3, -3, -3, -3 },
{ -1, -1, -1, -1, -1 }
};
}
}
}
}

25
src/ImageProcessor/Imaging/EdgeDetection/IEdgeFilter.cs

@ -1,9 +1,28 @@
namespace ImageProcessor.Imaging.EdgeDetection
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="IEdgeFilter.cs" company="James South">
// Copyright (c) James South.
// Licensed under the Apache License, Version 2.0.
// </copyright>
// <summary>
// Describes properties for creating edge detection filters.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace ImageProcessor.Imaging.EdgeDetection
{
/// <summary>
/// Describes properties for creating edge detection filters.
/// </summary>
public interface IEdgeFilter
{
double[,] HorizontalMatrix { get; }
/// <summary>
/// Gets the horizontal gradient operator.
/// </summary>
double[,] HorizontalGradientOperator { get; }
double[,] VerticalMatrix { get; }
/// <summary>
/// Gets the vertical gradient operator.
/// </summary>
double[,] VerticalGradientOperator { get; }
}
}

52
src/ImageProcessor/Imaging/EdgeDetection/PrewittEdgeFilter.cs

@ -0,0 +1,52 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="PrewittEdgeFilter.cs" company="James South">
// Copyright (c) James South.
// Licensed under the Apache License, Version 2.0.
// </copyright>
// <summary>
// The Prewitt operator filter.
// <see href="http://en.wikipedia.org/wiki/Prewitt_operator" />
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace ImageProcessor.Imaging.EdgeDetection
{
/// <summary>
/// The Prewitt operator filter.
/// <see href="http://en.wikipedia.org/wiki/Prewitt_operator"/>
/// </summary>
public class PrewittEdgeFilter : IEdgeFilter
{
/// <summary>
/// Gets the horizontal gradient operator.
/// </summary>
public double[,] HorizontalGradientOperator
{
get
{
return new double[,]
{
{ -1, 0, 1 },
{ -1, 0, 1 },
{ -1, 0, 1 }
};
}
}
/// <summary>
/// Gets the vertical gradient operator.
/// </summary>
public double[,] VerticalGradientOperator
{
get
{
return new double[,]
{
{ 1, 1, 1 },
{ 0, 0, 0 },
{ -1, -1, -1 }
};
}
}
}
}

50
src/ImageProcessor/Imaging/EdgeDetection/RobertsCrossEdgeFilter.cs

@ -0,0 +1,50 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="RobertsCrossEdgeFilter.cs" company="James South">
// Copyright (c) James South.
// Licensed under the Apache License, Version 2.0.
// </copyright>
// <summary>
// The Roberts Cross operator filter.
// <see href="http://en.wikipedia.org/wiki/Roberts_cross" />
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace ImageProcessor.Imaging.EdgeDetection
{
/// <summary>
/// The Roberts Cross operator filter.
/// <see href="http://en.wikipedia.org/wiki/Roberts_cross"/>
/// </summary>
public class RobertsCrossEdgeFilter : IEdgeFilter
{
/// <summary>
/// Gets the horizontal gradient operator.
/// </summary>
public double[,] HorizontalGradientOperator
{
get
{
return new double[,]
{
{ 1, 0 },
{ 0, -1 }
};
}
}
/// <summary>
/// Gets the vertical gradient operator.
/// </summary>
public double[,] VerticalGradientOperator
{
get
{
return new double[,]
{
{ 0, 1 },
{ -1, 0 }
};
}
}
}
}

52
src/ImageProcessor/Imaging/EdgeDetection/ScharrEdgeFilter.cs

@ -0,0 +1,52 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="ScharrEdgeFilter.cs" company="James South">
// Copyright (c) James South.
// Licensed under the Apache License, Version 2.0.
// </copyright>
// <summary>
// The Scharr operator filter.
// <see href="http://en.wikipedia.org/wiki/Sobel_operator#Alternative_operators" />
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace ImageProcessor.Imaging.EdgeDetection
{
/// <summary>
/// The Scharr operator filter.
/// <see href="http://en.wikipedia.org/wiki/Sobel_operator#Alternative_operators"/>
/// </summary>
public class ScharrEdgeFilter : IEdgeFilter
{
/// <summary>
/// Gets the horizontal gradient operator.
/// </summary>
public double[,] HorizontalGradientOperator
{
get
{
return new double[,]
{
{ -3, 0, 3 },
{ -10, 0, 10 },
{ -3, 0, 3 }
};
}
}
/// <summary>
/// Gets the vertical gradient operator.
/// </summary>
public double[,] VerticalGradientOperator
{
get
{
return new double[,]
{
{ 3, 10, 3 },
{ 0, 0, 0 },
{ -3, -10, -3 }
};
}
}
}
}

47
src/ImageProcessor/Imaging/EdgeDetection/SobelEdgeFilter.cs

@ -1,26 +1,51 @@
namespace ImageProcessor.Imaging.EdgeDetection
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="SobelEdgeFilter.cs" company="James South">
// Copyright (c) James South.
// Licensed under the Apache License, Version 2.0.
// </copyright>
// <summary>
// The Sobel operator filter.
// <see href="http://en.wikipedia.org/wiki/Sobel_operator" />
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace ImageProcessor.Imaging.EdgeDetection
{
/// <summary>
/// The Sobel operator filter.
/// <see href="http://en.wikipedia.org/wiki/Sobel_operator"/>
/// </summary>
public class SobelEdgeFilter : IEdgeFilter
{
public double[,] HorizontalMatrix
/// <summary>
/// Gets the horizontal gradient operator.
/// </summary>
public double[,] HorizontalGradientOperator
{
get
{
return new double[,]
{ { -1, 0, 1, },
{ -2, 0, 2, },
{ -1, 0, 1, }, };
return new double[,]
{
{ -1, 0, 1 },
{ -2, 0, 2 },
{ -1, 0, 1 }
};
}
}
public double[,] VerticalMatrix
/// <summary>
/// Gets the vertical gradient operator.
/// </summary>
public double[,] VerticalGradientOperator
{
get
{
return new double[,]
{ { 1, 2, 1, },
{ 0, 0, 0, },
{ -1, -2, -1, }, };
return new double[,]
{
{ 1, 2, 1 },
{ 0, 0, 0 },
{ -1, -2, -1 }
};
}
}
}

4
src/ImageProcessor/Imaging/FastBitmap.cs

@ -156,12 +156,12 @@ namespace ImageProcessor.Imaging
/// <returns>The <see cref="System.Drawing.Color"/> at the given pixel.</returns>
public Color GetPixel(int x, int y)
{
if ((x < 0) || (x >= this.width))
if ((x < 0) || (x > this.width))
{
throw new ArgumentOutOfRangeException("x", "Value cannot be less than zero or greater than the bitmap width.");
}
if ((y < 0) || (y >= this.height))
if ((y < 0) || (y > this.height))
{
throw new ArgumentOutOfRangeException("y", "Value cannot be less than zero or greater than the bitmap height.");
}

48
src/ImageProcessor/Processors/DetectEdges.cs

@ -1,16 +1,25 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="DetectEdges.cs" company="James South">
// Copyright (c) James South.
// Licensed under the Apache License, Version 2.0.
// </copyright>
// <summary>
// Produces an image with the detected edges highlighted.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace ImageProcessor.Processors
{
using System;
using System.Collections.Generic;
using System.Drawing;
using ImageProcessor.Common.Exceptions;
using ImageProcessor.Imaging.EdgeDetection;
/// <summary>
/// Produces an image with the detected edges highlighted.
/// </summary>
public class DetectEdges : IGraphicsProcessor
{
/// <summary>
@ -53,24 +62,27 @@ namespace ImageProcessor.Processors
{
Bitmap newImage = null;
Image image = factory.Image;
IEdgeFilter filter = this.DynamicParameter;
try
{
ConvolutionFilter convolutionFilter = new ConvolutionFilter(filter);
Tuple<IEdgeFilter, bool> parameters = this.DynamicParameter;
IEdgeFilter filter = parameters.Item1;
bool greyscale = parameters.Item2;
//try
//{
ConvolutionFilter convolutionFilter = new ConvolutionFilter(filter, greyscale);
newImage = convolutionFilter.ProcessFilter((Bitmap)image);
image.Dispose();
image = newImage;
}
catch (Exception ex)
{
if (newImage != null)
{
newImage.Dispose();
}
//}
//catch (Exception ex)
//{
// if (newImage != null)
// {
// newImage.Dispose();
// }
throw new ImageProcessingException("Error processing image with " + this.GetType().Name, ex);
}
// throw new ImageProcessingException("Error processing image with " + this.GetType().Name, ex);
//}
return image;
}

2
src/ImageProcessor/Settings.StyleCop

@ -8,6 +8,8 @@
<Value>gps</Value>
<Value>mmmm</Value>
<Value>orig</Value>
<Value>Scharr</Value>
<Value>Sobel</Value>
<Value>specifier</Value>
<Value>ss</Value>
<Value>subfile</Value>

4
src/ImageProcessorConsole/Program.cs

@ -46,7 +46,7 @@ namespace ImageProcessorConsole
di.Create();
}
IEnumerable<FileInfo> files = GetFilesByExtensions(di, ".jpg");
IEnumerable<FileInfo> files = GetFilesByExtensions(di, ".png");
//IEnumerable<FileInfo> files = GetFilesByExtensions(di, ".gif", ".webp", ".bmp", ".jpg", ".png", ".tif");
foreach (FileInfo fileInfo in files)
@ -77,7 +77,7 @@ namespace ImageProcessorConsole
//.Constrain(size)
//.ReplaceColor(Color.FromArgb(255, 1, 107, 165), Color.FromArgb(255, 1, 165, 13), 80)
.Resize(layer)
.DetectEdges(new SobelEdgeFilter())
.DetectEdges(new CostellaEdgeFilter(), false)
//.Filter(MatrixFilters.Comic)
//.Filter(MatrixFilters.HiSatch)
//.Pixelate(8)

1
src/ImageProcessorConsole/images/input/Bikesgray.png.REMOVED.git-id

@ -0,0 +1 @@
93b93eade2c7697a0a8fe9363d493a8a59de245a

1
src/ImageProcessorConsole/images/input/Valve_original_(1).PNG.REMOVED.git-id

@ -0,0 +1 @@
bdff6764fd5c4e3054ba7d8c43cc8c29be0e6f5e

3
src/ImageProcessorConsole/images/input/circle2.png

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:2dd59c277b646f15b0223c028ddfb0fa7d5edcb2609882e2c6841e5b2714cd67
size 3182

3
src/ImageProcessorConsole/images/output/Bikesgray.png

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:7eb6df312d356346d0d7f5d55c657a4a3a08f11d293c93f56447137a49190d0f
size 17319

3
src/ImageProcessorConsole/images/output/Valve_original_(1).PNG

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:8d74259c087adb38c335a3162c56f1c3ae344e098f2471d79d702d80a95907a3
size 4066

3
src/ImageProcessorConsole/images/output/circle.png

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:343794bc824674c81cd8ba90acd3bb690d43c84d363e3375e8ee42207867f977
size 7011

3
src/ImageProcessorConsole/images/output/circle2.png

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:662cd66659e03b0ca18e62d2e9bdc69e62e082fad9a0316348db031f67092497
size 4407

1
src/ImageProcessorConsole/images/output/monster.png.REMOVED.git-id

@ -0,0 +1 @@
ef1fdff21802713450cf2f81321c0605962ec6f5

1
src/ImageProcessorConsole/images/output/night-bridge.png.REMOVED.git-id

@ -0,0 +1 @@
fad7e5225f13c9d35d9e877c93e2bb44da7404c0
Loading…
Cancel
Save