Browse Source

Make all images implement IDisposable

af/merge-core
James Jackson-South 9 years ago
parent
commit
1339ad3075
  1. 4
      src/ImageSharp.Processing/Processors/Convolution/Convolution2DProcessor.cs
  2. 21
      src/ImageSharp.Processing/Processors/Convolution/Convolution2PassProcessor.cs
  3. 4
      src/ImageSharp.Processing/Processors/Effects/OilPaintingProcessor.cs
  4. 4
      src/ImageSharp.Processing/Processors/Effects/PixelateProcessor.cs
  5. 159
      src/ImageSharp.Processing/Processors/Transforms/CompandingResizeProcessor.cs
  6. 4
      src/ImageSharp.Processing/Processors/Transforms/CropProcessor.cs
  7. 8
      src/ImageSharp.Processing/Processors/Transforms/FlipProcessor.cs
  8. 159
      src/ImageSharp.Processing/Processors/Transforms/ResizeProcessor.cs
  9. 16
      src/ImageSharp.Processing/Processors/Transforms/RotateProcessor.cs
  10. 4
      src/ImageSharp.Processing/Processors/Transforms/SkewProcessor.cs
  11. 4
      src/ImageSharp/Image/IImageBase{TColor}.cs
  12. 111
      src/ImageSharp/Image/ImageBase{TColor}.cs
  13. 16
      src/ImageSharp/Image/Image{TColor}.cs
  14. 4
      src/ImageSharp/Image/PixelAccessor{TColor}.cs
  15. 50
      src/ImageSharp/Image/PixelPool{TColor}.cs
  16. 18
      tests/ImageSharp.Benchmarks/Drawing/DrawBeziers.cs
  17. 24
      tests/ImageSharp.Benchmarks/Drawing/DrawLines.cs
  18. 24
      tests/ImageSharp.Benchmarks/Drawing/DrawPolygon.cs
  19. 23
      tests/ImageSharp.Benchmarks/Drawing/FillPolygon.cs
  20. 29
      tests/ImageSharp.Benchmarks/Drawing/FillRectangle.cs
  21. 12
      tests/ImageSharp.Benchmarks/Drawing/FillWithPattern.cs
  22. 34
      tests/ImageSharp.Benchmarks/Image/CopyPixels.cs
  23. 6
      tests/ImageSharp.Benchmarks/Image/DecodeBmp.cs
  24. 17
      tests/ImageSharp.Benchmarks/Image/DecodeFilteredPng.cs
  25. 6
      tests/ImageSharp.Benchmarks/Image/DecodeGif.cs
  26. 6
      tests/ImageSharp.Benchmarks/Image/DecodeJpeg.cs
  27. 6
      tests/ImageSharp.Benchmarks/Image/DecodePng.cs
  28. 8
      tests/ImageSharp.Benchmarks/Image/EncodeBmp.cs
  29. 4
      tests/ImageSharp.Benchmarks/Image/EncodeBmpMultiple.cs
  30. 8
      tests/ImageSharp.Benchmarks/Image/EncodeGif.cs
  31. 8
      tests/ImageSharp.Benchmarks/Image/EncodeJpeg.cs
  32. 8
      tests/ImageSharp.Benchmarks/Image/EncodePng.cs
  33. 10
      tests/ImageSharp.Benchmarks/Image/GetSetPixel.cs
  34. 8
      tests/ImageSharp.Benchmarks/Samplers/Crop.cs
  35. 6
      tests/ImageSharp.Benchmarks/Samplers/DetectEdges.cs
  36. 16
      tests/ImageSharp.Benchmarks/Samplers/Resize.cs
  37. 137
      tests/ImageSharp.Tests/Drawing/BeziersTests.cs
  38. 21
      tests/ImageSharp.Tests/Drawing/DrawImageTest.cs
  39. 101
      tests/ImageSharp.Tests/Drawing/DrawPathTests.cs
  40. 71
      tests/ImageSharp.Tests/Drawing/FillPatternTests.cs
  41. 100
      tests/ImageSharp.Tests/Drawing/FillSolidBrushTests.cs
  42. 226
      tests/ImageSharp.Tests/Drawing/LineComplexPolygonTests.cs
  43. 155
      tests/ImageSharp.Tests/Drawing/LineTests.cs
  44. 112
      tests/ImageSharp.Tests/Drawing/PolygonTests.cs
  45. 32
      tests/ImageSharp.Tests/Drawing/RecolorImageTest.cs
  46. 102
      tests/ImageSharp.Tests/Drawing/SolidBezierTests.cs
  47. 138
      tests/ImageSharp.Tests/Drawing/SolidComplexPolygonTests.cs
  48. 156
      tests/ImageSharp.Tests/Drawing/SolidPolygonTests.cs
  49. 15
      tests/ImageSharp.Tests/Formats/Bmp/BitmapTests.cs
  50. 101
      tests/ImageSharp.Tests/Formats/GeneralFormatTests.cs
  51. 16
      tests/ImageSharp.Tests/Formats/Jpg/BadEofJpegTests.cs
  52. 61
      tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs
  53. 44
      tests/ImageSharp.Tests/Formats/Jpg/JpegEncoderTests.cs
  54. 85
      tests/ImageSharp.Tests/Formats/Jpg/JpegUtilsTests.cs
  55. 4
      tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementationsTests.cs
  56. 20
      tests/ImageSharp.Tests/Formats/Png/PngTests.cs
  57. 9
      tests/ImageSharp.Tests/Image/ImageTests.cs
  58. 118
      tests/ImageSharp.Tests/Image/PixelAccessorTests.cs
  59. 20
      tests/ImageSharp.Tests/Processors/Filters/AlphaTest.cs
  60. 19
      tests/ImageSharp.Tests/Processors/Filters/AutoOrientTests.cs
  61. 8
      tests/ImageSharp.Tests/Processors/Filters/BackgroundColorTest.cs
  62. 10
      tests/ImageSharp.Tests/Processors/Filters/BinaryThreshold.cs
  63. 8
      tests/ImageSharp.Tests/Processors/Filters/BlackWhiteTest.cs
  64. 10
      tests/ImageSharp.Tests/Processors/Filters/BoxBlurTest.cs
  65. 10
      tests/ImageSharp.Tests/Processors/Filters/BrightnessTest.cs
  66. 10
      tests/ImageSharp.Tests/Processors/Filters/ColorBlindnessTest.cs
  67. 10
      tests/ImageSharp.Tests/Processors/Filters/ContrastTest.cs
  68. 8
      tests/ImageSharp.Tests/Processors/Filters/CropTest.cs
  69. 15
      tests/ImageSharp.Tests/Processors/Filters/DetectEdgesTest.cs
  70. 10
      tests/ImageSharp.Tests/Processors/Filters/EntropyCropTest.cs
  71. 10
      tests/ImageSharp.Tests/Processors/Filters/FlipTests.cs
  72. 10
      tests/ImageSharp.Tests/Processors/Filters/GaussianBlurTest.cs
  73. 10
      tests/ImageSharp.Tests/Processors/Filters/GaussianSharpenTest.cs
  74. 31
      tests/ImageSharp.Tests/Processors/Filters/GlowTest.cs
  75. 10
      tests/ImageSharp.Tests/Processors/Filters/GrayscaleTest.cs
  76. 10
      tests/ImageSharp.Tests/Processors/Filters/HueTest.cs
  77. 16
      tests/ImageSharp.Tests/Processors/Filters/InvertTest.cs
  78. 8
      tests/ImageSharp.Tests/Processors/Filters/KodachromeTest.cs
  79. 15
      tests/ImageSharp.Tests/Processors/Filters/LomographTest.cs
  80. 21
      tests/ImageSharp.Tests/Processors/Filters/OilPaintTest.cs
  81. 8
      tests/ImageSharp.Tests/Processors/Filters/PadTest.cs
  82. 8
      tests/ImageSharp.Tests/Processors/Filters/PixelateTest.cs
  83. 8
      tests/ImageSharp.Tests/Processors/Filters/PolaroidTest.cs
  84. 76
      tests/ImageSharp.Tests/Processors/Filters/ResizeTests.cs
  85. 10
      tests/ImageSharp.Tests/Processors/Filters/RotateFlipTest.cs
  86. 20
      tests/ImageSharp.Tests/Processors/Filters/RotateTest.cs
  87. 8
      tests/ImageSharp.Tests/Processors/Filters/SaturationTest.cs
  88. 6
      tests/ImageSharp.Tests/Processors/Filters/SepiaTest.cs
  89. 12
      tests/ImageSharp.Tests/Processors/Filters/SkewTest.cs
  90. 31
      tests/ImageSharp.Tests/Processors/Filters/VignetteTest.cs
  91. 3
      tests/ImageSharp.Tests/Profiles/Exif/ExifProfileTests.cs
  92. 2
      tests/ImageSharp.Tests/Profiles/Exif/ExifTagDescriptionAttributeTests.cs
  93. 7
      tests/ImageSharp.Tests/Profiles/Exif/ExifValueTests.cs

4
src/ImageSharp.Processing/Processors/Convolution/Convolution2DProcessor.cs

@ -54,9 +54,9 @@ namespace ImageSharp.Processing.Processors
int maxY = endY - 1;
int maxX = endX - 1;
TColor[] target = new TColor[source.Width * source.Height];
TColor[] target = PixelPool<TColor>.RentPixels(source.Width * source.Height);
using (PixelAccessor<TColor> sourcePixels = source.Lock())
using (PixelAccessor<TColor> targetPixels = target.Lock<TColor>(source.Width, source.Height))
using (PixelAccessor<TColor> targetPixels = target.Lock(source.Width, source.Height))
{
Parallel.For(
startY,

21
src/ImageSharp.Processing/Processors/Convolution/Convolution2PassProcessor.cs

@ -45,13 +45,20 @@ namespace ImageSharp.Processing.Processors
int width = source.Width;
int height = source.Height;
TColor[] target = new TColor[width * height];
TColor[] firstPass = new TColor[width * height];
TColor[] target = PixelPool<TColor>.RentPixels(width * height);
TColor[] firstPass = PixelPool<TColor>.RentPixels(width * height);
this.ApplyConvolution(width, height, firstPass, source.Pixels, sourceRectangle, kernelX);
this.ApplyConvolution(width, height, target, firstPass, sourceRectangle, kernelY);
try
{
this.ApplyConvolution(width, height, firstPass, source.Pixels, sourceRectangle, kernelX);
this.ApplyConvolution(width, height, target, firstPass, sourceRectangle, kernelY);
source.SetPixels(width, height, target);
source.SetPixels(width, height, target);
}
finally
{
PixelPool<TColor>.ReturnPixels(firstPass);
}
}
/// <summary>
@ -80,8 +87,8 @@ namespace ImageSharp.Processing.Processors
int maxY = endY - 1;
int maxX = endX - 1;
using (PixelAccessor<TColor> sourcePixels = source.Lock<TColor>(width, height))
using (PixelAccessor<TColor> targetPixels = target.Lock<TColor>(width, height))
using (PixelAccessor<TColor> sourcePixels = source.Lock(width, height))
using (PixelAccessor<TColor> targetPixels = target.Lock(width, height))
{
Parallel.For(
startY,

4
src/ImageSharp.Processing/Processors/Effects/OilPaintingProcessor.cs

@ -67,9 +67,9 @@ namespace ImageSharp.Processing.Processors
startX = 0;
}
TColor[] target = new TColor[source.Width * source.Height];
TColor[] target = PixelPool<TColor>.RentPixels(source.Width * source.Height);
using (PixelAccessor<TColor> sourcePixels = source.Lock())
using (PixelAccessor<TColor> targetPixels = target.Lock<TColor>(source.Width, source.Height))
using (PixelAccessor<TColor> targetPixels = target.Lock(source.Width, source.Height))
{
Parallel.For(
minY,

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

@ -63,10 +63,10 @@ namespace ImageSharp.Processing.Processors
// Get the range on the y-plane to choose from.
IEnumerable<int> range = EnumerableExtensions.SteppedRange(minY, i => i < maxY, size);
TColor[] target = new TColor[source.Width * source.Height];
TColor[] target = PixelPool<TColor>.RentPixels(source.Width * source.Height);
using (PixelAccessor<TColor> sourcePixels = source.Lock())
using (PixelAccessor<TColor> targetPixels = target.Lock<TColor>(source.Width, source.Height))
using (PixelAccessor<TColor> targetPixels = target.Lock(source.Width, source.Height))
{
Parallel.ForEach(
range,

159
src/ImageSharp.Processing/Processors/Transforms/CompandingResizeProcessor.cs

@ -66,103 +66,112 @@ namespace ImageSharp.Processing.Processors
int minY = Math.Max(0, startY);
int maxY = Math.Min(height, endY);
TColor[] target = new TColor[width * height];
TColor[] firstPass = null;
if (this.Sampler is NearestNeighborResampler)
try
{
// Scaling factors
float widthFactor = sourceRectangle.Width / (float)this.ResizeRectangle.Width;
float heightFactor = sourceRectangle.Height / (float)this.ResizeRectangle.Height;
TColor[] target = PixelPool<TColor>.RentPixels(width * height);
if (this.Sampler is NearestNeighborResampler)
{
// Scaling factors
float widthFactor = sourceRectangle.Width / (float)this.ResizeRectangle.Width;
float heightFactor = sourceRectangle.Height / (float)this.ResizeRectangle.Height;
using (PixelAccessor<TColor> sourcePixels = source.Lock())
using (PixelAccessor<TColor> targetPixels = target.Lock(width, height))
{
Parallel.For(
minY,
maxY,
this.ParallelOptions,
y =>
{
// Y coordinates of source points
int originY = (int)((y - startY) * heightFactor);
for (int x = minX; x < maxX; x++)
{
// X coordinates of source points
targetPixels[x, y] = sourcePixels[(int)((x - startX) * widthFactor), originY];
}
});
}
// Break out now.
source.SetPixels(width, height, target);
return;
}
// Interpolate the image using the calculated weights.
// A 2-pass 1D algorithm appears to be faster than splitting a 1-pass 2D algorithm
// First process the columns. Since we are not using multiple threads startY and endY
// are the upper and lower bounds of the source rectangle.
firstPass = PixelPool<TColor>.RentPixels(width * source.Height);
using (PixelAccessor<TColor> sourcePixels = source.Lock())
using (PixelAccessor<TColor> targetPixels = target.Lock<TColor>(width, height))
using (PixelAccessor<TColor> firstPassPixels = firstPass.Lock(width, source.Height))
using (PixelAccessor<TColor> targetPixels = target.Lock(width, height))
{
Parallel.For(
minY,
maxY,
0,
sourceRectangle.Height,
this.ParallelOptions,
y =>
{
// Y coordinates of source points
int originY = (int)((y - startY) * heightFactor);
for (int x = minX; x < maxX; x++)
{
// X coordinates of source points
targetPixels[x, y] = sourcePixels[(int)((x - startX) * widthFactor), originY];
}
});
}
// Ensure offsets are normalised for cropping and padding.
Weight[] horizontalValues = this.HorizontalWeights[x - startX].Values;
// Break out now.
source.SetPixels(width, height, target);
return;
}
// Destination color components
Vector4 destination = Vector4.Zero;
// Interpolate the image using the calculated weights.
// A 2-pass 1D algorithm appears to be faster than splitting a 1-pass 2D algorithm
// First process the columns. Since we are not using multiple threads startY and endY
// are the upper and lower bounds of the source rectangle.
TColor[] firstPass = new TColor[width * source.Height];
using (PixelAccessor<TColor> sourcePixels = source.Lock())
using (PixelAccessor<TColor> firstPassPixels = firstPass.Lock<TColor>(width, source.Height))
using (PixelAccessor<TColor> targetPixels = target.Lock<TColor>(width, height))
{
Parallel.For(
0,
sourceRectangle.Height,
this.ParallelOptions,
y =>
{
for (int x = minX; x < maxX; x++)
{
// Ensure offsets are normalised for cropping and padding.
Weight[] horizontalValues = this.HorizontalWeights[x - startX].Values;
for (int i = 0; i < horizontalValues.Length; i++)
{
Weight xw = horizontalValues[i];
destination += sourcePixels[xw.Index, y].ToVector4().Expand() * xw.Value;
}
// Destination color components
Vector4 destination = Vector4.Zero;
for (int i = 0; i < horizontalValues.Length; i++)
{
Weight xw = horizontalValues[i];
destination += sourcePixels[xw.Index, y].ToVector4().Expand() * xw.Value;
TColor d = default(TColor);
d.PackFromVector4(destination.Compress());
firstPassPixels[x, y] = d;
}
});
TColor d = default(TColor);
d.PackFromVector4(destination.Compress());
firstPassPixels[x, y] = d;
}
});
// Now process the rows.
Parallel.For(
minY,
maxY,
this.ParallelOptions,
y =>
{
// Ensure offsets are normalised for cropping and padding.
Weight[] verticalValues = this.VerticalWeights[y - startY].Values;
for (int x = 0; x < width; x++)
// Now process the rows.
Parallel.For(
minY,
maxY,
this.ParallelOptions,
y =>
{
// Destination color components
Vector4 destination = Vector4.Zero;
// Ensure offsets are normalised for cropping and padding.
Weight[] verticalValues = this.VerticalWeights[y - startY].Values;
for (int i = 0; i < verticalValues.Length; i++)
for (int x = 0; x < width; x++)
{
Weight yw = verticalValues[i];
destination += firstPassPixels[x, yw.Index].ToVector4().Expand() * yw.Value;
// Destination color components
Vector4 destination = Vector4.Zero;
for (int i = 0; i < verticalValues.Length; i++)
{
Weight yw = verticalValues[i];
destination += firstPassPixels[x, yw.Index].ToVector4().Expand() * yw.Value;
}
TColor d = default(TColor);
d.PackFromVector4(destination.Compress());
targetPixels[x, y] = d;
}
});
}
TColor d = default(TColor);
d.PackFromVector4(destination.Compress());
targetPixels[x, y] = d;
}
});
source.SetPixels(width, height, target);
}
finally
{
// We don't return target or source pixels as they are handled in the image itself.
PixelPool<TColor>.ReturnPixels(firstPass);
}
source.SetPixels(width, height, target);
}
}
}

4
src/ImageSharp.Processing/Processors/Transforms/CropProcessor.cs

@ -42,10 +42,10 @@ namespace ImageSharp.Processing.Processors
int minX = Math.Max(this.CropRectangle.X, sourceRectangle.X);
int maxX = Math.Min(this.CropRectangle.Right, sourceRectangle.Right);
TColor[] target = new TColor[this.CropRectangle.Width * this.CropRectangle.Height];
TColor[] target = PixelPool<TColor>.RentPixels(this.CropRectangle.Width * this.CropRectangle.Height);
using (PixelAccessor<TColor> sourcePixels = source.Lock())
using (PixelAccessor<TColor> targetPixels = target.Lock<TColor>(this.CropRectangle.Width, this.CropRectangle.Height))
using (PixelAccessor<TColor> targetPixels = target.Lock(this.CropRectangle.Width, this.CropRectangle.Height))
{
Parallel.For(
minY,

8
src/ImageSharp.Processing/Processors/Transforms/FlipProcessor.cs

@ -55,10 +55,10 @@ namespace ImageSharp.Processing.Processors
int height = source.Height;
int halfHeight = (int)Math.Ceiling(source.Height * .5F);
TColor[] target = new TColor[width * height];
TColor[] target = PixelPool<TColor>.RentPixels(width * height);
using (PixelAccessor<TColor> sourcePixels = source.Lock())
using (PixelAccessor<TColor> targetPixels = target.Lock<TColor>(width, height))
using (PixelAccessor<TColor> targetPixels = target.Lock(width, height))
{
Parallel.For(
0,
@ -89,10 +89,10 @@ namespace ImageSharp.Processing.Processors
int height = source.Height;
int halfWidth = (int)Math.Ceiling(width * .5F);
TColor[] target = new TColor[width * height];
TColor[] target = PixelPool<TColor>.RentPixels(width * height);
using (PixelAccessor<TColor> sourcePixels = source.Lock())
using (PixelAccessor<TColor> targetPixels = target.Lock<TColor>(width, height))
using (PixelAccessor<TColor> targetPixels = target.Lock(width, height))
{
Parallel.For(
0,

159
src/ImageSharp.Processing/Processors/Transforms/ResizeProcessor.cs

@ -65,103 +65,112 @@ namespace ImageSharp.Processing.Processors
int minY = Math.Max(0, startY);
int maxY = Math.Min(height, endY);
TColor[] target = new TColor[width * height];
TColor[] firstPass = null;
if (this.Sampler is NearestNeighborResampler)
try
{
// Scaling factors
float widthFactor = sourceRectangle.Width / (float)this.ResizeRectangle.Width;
float heightFactor = sourceRectangle.Height / (float)this.ResizeRectangle.Height;
TColor[] target = PixelPool<TColor>.RentPixels(width * height);
if (this.Sampler is NearestNeighborResampler)
{
// Scaling factors
float widthFactor = sourceRectangle.Width / (float)this.ResizeRectangle.Width;
float heightFactor = sourceRectangle.Height / (float)this.ResizeRectangle.Height;
using (PixelAccessor<TColor> sourcePixels = source.Lock())
using (PixelAccessor<TColor> targetPixels = target.Lock(width, height))
{
Parallel.For(
minY,
maxY,
this.ParallelOptions,
y =>
{
// Y coordinates of source points
int originY = (int)((y - startY) * heightFactor);
for (int x = minX; x < maxX; x++)
{
// X coordinates of source points
targetPixels[x, y] = sourcePixels[(int)((x - startX) * widthFactor), originY];
}
});
}
// Break out now.
source.SetPixels(width, height, target);
return;
}
// Interpolate the image using the calculated weights.
// A 2-pass 1D algorithm appears to be faster than splitting a 1-pass 2D algorithm
// First process the columns. Since we are not using multiple threads startY and endY
// are the upper and lower bounds of the source rectangle.
firstPass = PixelPool<TColor>.RentPixels(width * source.Height);
using (PixelAccessor<TColor> sourcePixels = source.Lock())
using (PixelAccessor<TColor> targetPixels = target.Lock<TColor>(width, height))
using (PixelAccessor<TColor> firstPassPixels = firstPass.Lock(width, source.Height))
using (PixelAccessor<TColor> targetPixels = target.Lock(width, height))
{
Parallel.For(
minY,
maxY,
0,
sourceRectangle.Height,
this.ParallelOptions,
y =>
{
// Y coordinates of source points
int originY = (int)((y - startY) * heightFactor);
for (int x = minX; x < maxX; x++)
{
// X coordinates of source points
targetPixels[x, y] = sourcePixels[(int)((x - startX) * widthFactor), originY];
}
});
}
// Ensure offsets are normalised for cropping and padding.
Weight[] horizontalValues = this.HorizontalWeights[x - startX].Values;
// Break out now.
source.SetPixels(width, height, target);
return;
}
// Destination color components
Vector4 destination = Vector4.Zero;
// Interpolate the image using the calculated weights.
// A 2-pass 1D algorithm appears to be faster than splitting a 1-pass 2D algorithm
// First process the columns. Since we are not using multiple threads startY and endY
// are the upper and lower bounds of the source rectangle.
TColor[] firstPass = new TColor[width * source.Height];
using (PixelAccessor<TColor> sourcePixels = source.Lock())
using (PixelAccessor<TColor> firstPassPixels = firstPass.Lock<TColor>(width, source.Height))
using (PixelAccessor<TColor> targetPixels = target.Lock<TColor>(width, height))
{
Parallel.For(
0,
sourceRectangle.Height,
this.ParallelOptions,
y =>
{
for (int x = minX; x < maxX; x++)
{
// Ensure offsets are normalised for cropping and padding.
Weight[] horizontalValues = this.HorizontalWeights[x - startX].Values;
for (int i = 0; i < horizontalValues.Length; i++)
{
Weight xw = horizontalValues[i];
destination += sourcePixels[xw.Index, y].ToVector4() * xw.Value;
}
// Destination color components
Vector4 destination = Vector4.Zero;
for (int i = 0; i < horizontalValues.Length; i++)
{
Weight xw = horizontalValues[i];
destination += sourcePixels[xw.Index, y].ToVector4() * xw.Value;
TColor d = default(TColor);
d.PackFromVector4(destination);
firstPassPixels[x, y] = d;
}
});
TColor d = default(TColor);
d.PackFromVector4(destination);
firstPassPixels[x, y] = d;
}
});
// Now process the rows.
Parallel.For(
minY,
maxY,
this.ParallelOptions,
y =>
{
// Ensure offsets are normalised for cropping and padding.
Weight[] verticalValues = this.VerticalWeights[y - startY].Values;
for (int x = 0; x < width; x++)
// Now process the rows.
Parallel.For(
minY,
maxY,
this.ParallelOptions,
y =>
{
// Destination color components
Vector4 destination = Vector4.Zero;
// Ensure offsets are normalised for cropping and padding.
Weight[] verticalValues = this.VerticalWeights[y - startY].Values;
for (int i = 0; i < verticalValues.Length; i++)
for (int x = 0; x < width; x++)
{
Weight yw = verticalValues[i];
destination += firstPassPixels[x, yw.Index].ToVector4() * yw.Value;
// Destination color components
Vector4 destination = Vector4.Zero;
for (int i = 0; i < verticalValues.Length; i++)
{
Weight yw = verticalValues[i];
destination += firstPassPixels[x, yw.Index].ToVector4() * yw.Value;
}
TColor d = default(TColor);
d.PackFromVector4(destination);
targetPixels[x, y] = d;
}
});
}
TColor d = default(TColor);
d.PackFromVector4(destination);
targetPixels[x, y] = d;
}
});
source.SetPixels(width, height, target);
}
finally
{
// We don't return target or source pixels as they are handled in the image itself.
PixelPool<TColor>.ReturnPixels(firstPass);
}
source.SetPixels(width, height, target);
}
}
}

16
src/ImageSharp.Processing/Processors/Transforms/RotateProcessor.cs

@ -42,10 +42,10 @@ namespace ImageSharp.Processing.Processors
int height = this.CanvasRectangle.Height;
int width = this.CanvasRectangle.Width;
Matrix3x2 matrix = this.GetCenteredMatrix(source, this.processMatrix);
TColor[] target = new TColor[width * height];
TColor[] target = PixelPool<TColor>.RentPixels(width * height);
using (PixelAccessor<TColor> sourcePixels = source.Lock())
using (PixelAccessor<TColor> targetPixels = target.Lock<TColor>(width, height))
using (PixelAccessor<TColor> targetPixels = target.Lock(width, height))
{
Parallel.For(
0,
@ -124,10 +124,10 @@ namespace ImageSharp.Processing.Processors
{
int width = source.Width;
int height = source.Height;
TColor[] target = new TColor[width * height];
TColor[] target = PixelPool<TColor>.RentPixels(width * height);
using (PixelAccessor<TColor> sourcePixels = source.Lock())
using (PixelAccessor<TColor> targetPixels = target.Lock<TColor>(height, width))
using (PixelAccessor<TColor> targetPixels = target.Lock(height, width))
{
Parallel.For(
0,
@ -156,10 +156,10 @@ namespace ImageSharp.Processing.Processors
{
int width = source.Width;
int height = source.Height;
TColor[] target = new TColor[width * height];
TColor[] target = PixelPool<TColor>.RentPixels(width * height);
using (PixelAccessor<TColor> sourcePixels = source.Lock())
using (PixelAccessor<TColor> targetPixels = target.Lock<TColor>(width, height))
using (PixelAccessor<TColor> targetPixels = target.Lock(width, height))
{
Parallel.For(
0,
@ -187,10 +187,10 @@ namespace ImageSharp.Processing.Processors
{
int width = source.Width;
int height = source.Height;
TColor[] target = new TColor[width * height];
TColor[] target = PixelPool<TColor>.RentPixels(width * height);
using (PixelAccessor<TColor> sourcePixels = source.Lock())
using (PixelAccessor<TColor> targetPixels = target.Lock<TColor>(height, width))
using (PixelAccessor<TColor> targetPixels = target.Lock(height, width))
{
Parallel.For(
0,

4
src/ImageSharp.Processing/Processors/Transforms/SkewProcessor.cs

@ -42,10 +42,10 @@ namespace ImageSharp.Processing.Processors
int height = this.CanvasRectangle.Height;
int width = this.CanvasRectangle.Width;
Matrix3x2 matrix = this.GetCenteredMatrix(source, this.processMatrix);
TColor[] target = new TColor[width * height];
TColor[] target = PixelPool<TColor>.RentPixels(width * height);
using (PixelAccessor<TColor> sourcePixels = source.Lock())
using (PixelAccessor<TColor> targetPixels = target.Lock<TColor>(width, height))
using (PixelAccessor<TColor> targetPixels = target.Lock(width, height))
{
Parallel.For(
0,

4
src/ImageSharp/Image/IImageBase{TColor}.cs

@ -11,11 +11,13 @@ namespace ImageSharp
/// Encapsulates the basic properties and methods required to manipulate images in varying formats.
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
public interface IImageBase<TColor> : IImageBase
public interface IImageBase<TColor> : IImageBase, IDisposable
where TColor : struct, IPackedPixel, IEquatable<TColor>
{
/// <summary>
/// Gets the pixels as an array of the given packed pixel format.
/// Important. Due to the nature in the way this is constructed do not rely on the length
/// of the array for calculations. Use Width * Height.
/// </summary>
TColor[] Pixels { get; }

111
src/ImageSharp/Image/ImageBase{TColor}.cs

@ -6,6 +6,7 @@
namespace ImageSharp
{
using System;
using System.Buffers;
using System.Diagnostics;
/// <summary>
@ -14,14 +15,30 @@ namespace ImageSharp
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
[DebuggerDisplay("Image: {Width}x{Height}")]
public abstract class ImageBase<TColor> : IImageBase<TColor>
public abstract class ImageBase<TColor> : IImageBase<TColor> // IImageBase implements IDisposable
where TColor : struct, IPackedPixel, IEquatable<TColor>
{
/// <summary>
/// The <see cref="ArrayPool{TColor}"/> used to pool data. TODO: Choose sensible default size and count
/// </summary>
private static readonly ArrayPool<TColor> ArrayPool = ArrayPool<TColor>.Create(int.MaxValue, 50);
/// <summary>
/// The image pixels
/// </summary>
private TColor[] pixelBuffer;
/// <summary>
/// A value indicating whether this instance of the given entity has been disposed.
/// </summary>
/// <value><see langword="true"/> if this instance has been disposed; otherwise, <see langword="false"/>.</value>
/// <remarks>
/// If the entity is disposed, it must not be disposed a second time. The isDisposed field is set the first time the entity
/// is disposed. If the isDisposed field is true, then the Dispose() method will not dispose again. This help not to prolong the entity's
/// life in the Garbage Collector.
/// </remarks>
private bool isDisposed;
/// <summary>
/// Initializes a new instance of the <see cref="ImageBase{TColor}"/> class.
/// </summary>
@ -41,7 +58,7 @@ namespace ImageSharp
/// <param name="configuration">
/// The configuration providing initialization code which allows extending the library.
/// </param>
/// <exception cref="System.ArgumentOutOfRangeException">
/// <exception cref="ArgumentOutOfRangeException">
/// Thrown if either <paramref name="width"/> or <paramref name="height"/> are less than or equal to 0.
/// </exception>
protected ImageBase(int width, int height, Configuration configuration = null)
@ -67,15 +84,24 @@ namespace ImageSharp
this.Height = other.Height;
this.CopyProperties(other);
// Copy the pixels. Unsafe.CopyBlock gives us a nice speed boost here.
this.pixelBuffer = new TColor[this.Width * this.Height];
// Rent then copy the pixels. Unsafe.CopyBlock gives us a nice speed boost here.
this.RentPixels();
using (PixelAccessor<TColor> sourcePixels = other.Lock())
using (PixelAccessor<TColor> target = this.Lock())
{
// Check we can do this without crashing
sourcePixels.CopyTo(target);
}
}
/// <summary>
/// Finalizes an instance of the <see cref="ImageBase{TColor}"/> class.
/// </summary>
~ImageBase()
{
this.Dispose(false);
}
/// <inheritdoc/>
public int MaxWidth { get; set; } = int.MaxValue;
@ -108,6 +134,19 @@ namespace ImageSharp
/// </summary>
public Configuration Configuration { get; private set; }
/// <inheritdoc />
public void Dispose()
{
this.Dispose(true);
// This object will be cleaned up by the Dispose method.
// Therefore, you should call GC.SuppressFinalize to
// take this object off the finalization queue
// and prevent finalization code for this object
// from executing a second time.
GC.SuppressFinalize(this);
}
/// <inheritdoc/>
public void InitPixels(int width, int height)
{
@ -116,7 +155,7 @@ namespace ImageSharp
this.Width = width;
this.Height = height;
this.pixelBuffer = new TColor[width * height];
this.RentPixels();
}
/// <inheritdoc/>
@ -126,13 +165,15 @@ namespace ImageSharp
Guard.MustBeGreaterThan(height, 0, nameof(height));
Guard.NotNull(pixels, nameof(pixels));
if (pixels.Length != width * height)
if (!(pixels.Length >= width * height))
{
throw new ArgumentException("Pixel array must have the length of Width * Height.");
throw new ArgumentException($"Pixel array must have the length of at least {width * height}.");
}
this.Width = width;
this.Height = height;
this.ReturnPixels();
this.pixelBuffer = pixels;
}
@ -143,17 +184,18 @@ namespace ImageSharp
Guard.MustBeGreaterThan(height, 0, nameof(height));
Guard.NotNull(pixels, nameof(pixels));
if (pixels.Length != width * height)
if (!(pixels.Length >= width * height))
{
throw new ArgumentException("Pixel array must have the length of Width * Height.");
throw new ArgumentException($"Pixel array must have the length of at least {width * height}.");
}
this.Width = width;
this.Height = height;
// Copy the pixels. TODO: use Unsafe.Copy.
this.pixelBuffer = new TColor[pixels.Length];
Array.Copy(pixels, this.pixelBuffer, pixels.Length);
this.ReturnPixels();
this.RentPixels();
Array.Copy(pixels, this.pixelBuffer, width * height);
}
/// <inheritdoc/>
@ -174,5 +216,52 @@ namespace ImageSharp
this.Quality = other.Quality;
this.FrameDelay = other.FrameDelay;
}
/// <summary>
/// Releases any unmanaged resources from the inheriting class.
/// </summary>
protected virtual void ReleaseUnmanagedResources()
{
// TODO release unmanaged resources here
}
/// <summary>
/// Disposes the object and frees resources for the Garbage Collector.
/// </summary>
/// <param name="disposing">If true, the object gets disposed.</param>
protected virtual void Dispose(bool disposing)
{
if (this.isDisposed)
{
return;
}
this.ReleaseUnmanagedResources();
if (disposing)
{
this.ReturnPixels();
}
// Note disposing is done.
this.isDisposed = true;
}
/// <summary>
/// Rents the pixel array from the pool.
/// </summary>
private void RentPixels()
{
this.pixelBuffer = PixelPool<TColor>.RentPixels(this.Width * this.Height);
}
/// <summary>
/// Returns the rented pixel array back to the pool.
/// </summary>
private void ReturnPixels()
{
PixelPool<TColor>.ReturnPixels(this.pixelBuffer);
this.pixelBuffer = null;
}
}
}

16
src/ImageSharp/Image/Image{TColor}.cs

@ -334,9 +334,9 @@ namespace ImageSharp
target.ExifProfile = new ExifProfile(this.ExifProfile);
}
foreach (ImageFrame<TColor> frame in this.Frames)
for (int i = 0; i < this.Frames.Count; i++)
{
target.Frames.Add(frame.To<TColor2>());
target.Frames.Add(this.Frames[i].To<TColor2>());
}
return target;
@ -372,6 +372,18 @@ namespace ImageSharp
return new ImageFrame<TColor>(this);
}
/// <inheritdoc />
protected override void Dispose(bool disposing)
{
// ReSharper disable once ForCanBeConvertedToForeach
for (int i = 0; i < this.Frames.Count; i++)
{
this.Frames[i].Dispose();
}
base.Dispose(disposing);
}
/// <summary>
/// Loads the image from the given stream.
/// </summary>

4
src/ImageSharp/Image/PixelAccessor{TColor}.cs

@ -76,9 +76,9 @@ namespace ImageSharp
Guard.MustBeGreaterThan(width, 0, nameof(width));
Guard.MustBeGreaterThan(height, 0, nameof(height));
if (pixels.Length != width * height)
if (!(pixels.Length >= width * height))
{
throw new ArgumentException("Pixel array must have the length of Width * Height.");
throw new ArgumentException($"Pixel array must have the length of at least {width * height}.");
}
this.Width = width;

50
src/ImageSharp/Image/PixelPool{TColor}.cs

@ -0,0 +1,50 @@
// <copyright file="PixelPool{TColor}.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageSharp
{
using System;
using System.Buffers;
/// <summary>
/// Provides a resource pool that enables reusing instances of type <see cref="T:TColor[]"/>.
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
public static class PixelPool<TColor>
where TColor : struct, IPackedPixel, IEquatable<TColor>
{
/// <summary>
/// The <see cref="ArrayPool{T}"/> used to pool data. TODO: Choose sensible default size and count
/// </summary>
private static readonly ArrayPool<TColor> ArrayPool = ArrayPool<TColor>.Create(int.MaxValue, 50);
/// <summary>
/// Rents the pixel array from the pool.
/// </summary>
/// <param name="minimumLength">The minimum length of the array to return.</param>
/// <returns>The <see cref="T:TColor[]"/></returns>
public static TColor[] RentPixels(int minimumLength)
{
return ArrayPool.Rent(minimumLength);
}
/// <summary>
/// Returns the rented pixel array back to the pool.
/// </summary>
/// <param name="array">The array to return to the buffer pool.</param>
public static void ReturnPixels(TColor[] array)
{
try
{
ArrayPool.Return(array, true);
}
catch
{
// Do nothing.
// Hacky but it allows us to attempt to return non-pooled arrays and arrays that have already been returned
}
}
}
}

18
tests/ImageSharp.Benchmarks/Drawing/DrawBeziers.cs

@ -47,18 +47,22 @@ namespace ImageSharp.Benchmarks
[Benchmark(Description = "ImageSharp Draw Beziers")]
public void DrawLinesCore()
{
CoreImage image = new CoreImage(800, 800);
image.DrawBeziers(CoreColor.HotPink, 10, new[] {
using (CoreImage image = new CoreImage(800, 800))
{
image.DrawBeziers(
CoreColor.HotPink,
10,
new[] {
new Vector2(10, 500),
new Vector2(30, 10),
new Vector2(240, 30),
new Vector2(300, 500)
});
});
using (MemoryStream ms = new MemoryStream())
{
image.SaveAsBmp(ms);
using (MemoryStream ms = new MemoryStream())
{
image.SaveAsBmp(ms);
}
}
}
}

24
tests/ImageSharp.Benchmarks/Drawing/DrawLines.cs

@ -46,17 +46,21 @@ namespace ImageSharp.Benchmarks
[Benchmark(Description = "ImageSharp Draw Lines")]
public void DrawLinesCore()
{
CoreImage image = new CoreImage(800, 800);
image.DrawLines(CoreColor.HotPink, 10, new[] {
new Vector2(10, 10),
new Vector2(550, 50),
new Vector2(200, 400)
});
using (MemoryStream ms = new MemoryStream())
using (CoreImage image = new CoreImage(800, 800))
{
image.SaveAsBmp(ms);
image.DrawLines(
CoreColor.HotPink,
10,
new[] {
new Vector2(10, 10),
new Vector2(550, 50),
new Vector2(200, 400)
});
using (MemoryStream ms = new MemoryStream())
{
image.SaveAsBmp(ms);
}
}
}
}

24
tests/ImageSharp.Benchmarks/Drawing/DrawPolygon.cs

@ -45,17 +45,21 @@ namespace ImageSharp.Benchmarks
[Benchmark(Description = "ImageSharp Draw Polygon")]
public void DrawPolygonCore()
{
CoreImage image = new CoreImage(800, 800);
image.DrawPolygon(CoreColor.HotPink, 10, new[] {
new Vector2(10, 10),
new Vector2(550, 50),
new Vector2(200, 400)
});
using (MemoryStream ms = new MemoryStream())
using (CoreImage image = new CoreImage(800, 800))
{
image.SaveAsBmp(ms);
image.DrawPolygon(
CoreColor.HotPink,
10,
new[] {
new Vector2(10, 10),
new Vector2(550, 50),
new Vector2(200, 400)
});
using (MemoryStream ms = new MemoryStream())
{
image.SaveAsBmp(ms);
}
}
}
}

23
tests/ImageSharp.Benchmarks/Drawing/FillPolygon.cs

@ -44,17 +44,20 @@ namespace ImageSharp.Benchmarks
[Benchmark(Description = "ImageSharp Fill Polygon")]
public void DrawSolidPolygonCore()
{
CoreImage image = new CoreImage(800, 800);
image.FillPolygon(CoreColor.HotPink,
new[] {
new Vector2(10, 10),
new Vector2(550, 50),
new Vector2(200, 400)
});
using (MemoryStream ms = new MemoryStream())
using (CoreImage image = new CoreImage(800, 800))
{
image.SaveAsBmp(ms);
image.FillPolygon(
CoreColor.HotPink,
new[] {
new Vector2(10, 10),
new Vector2(550, 50),
new Vector2(200, 400)
});
using (MemoryStream ms = new MemoryStream())
{
image.SaveAsBmp(ms);
}
}
}
}

29
tests/ImageSharp.Benchmarks/Drawing/FillRectangle.cs

@ -28,7 +28,6 @@ namespace ImageSharp.Benchmarks
{
graphics.InterpolationMode = InterpolationMode.Default;
graphics.SmoothingMode = SmoothingMode.AntiAlias;
var pen = new Pen(Color.HotPink, 10);
graphics.FillRectangle(Brushes.HotPink, new Rectangle(10, 10, 190, 140));
}
return destination.Size;
@ -38,25 +37,29 @@ namespace ImageSharp.Benchmarks
[Benchmark(Description = "ImageSharp Fill Rectangle")]
public CoreSize FillRactangleCore()
{
CoreImage image = new CoreImage(800, 800);
image.Fill(CoreColor.HotPink, new ImageSharp.Drawing.Shapes.RectangularPolygon(new CoreRectangle(10, 10, 190, 140)));
using (CoreImage image = new CoreImage(800, 800))
{
image.Fill(CoreColor.HotPink, new ImageSharp.Drawing.Shapes.RectangularPolygon(new CoreRectangle(10, 10, 190, 140)));
return new CoreSize(image.Width, image.Height);
return new CoreSize(image.Width, image.Height);
}
}
[Benchmark(Description = "ImageSharp Fill Rectangle - As Polygon")]
public CoreSize FillPolygonCore()
{
CoreImage image = new CoreImage(800, 800);
image.FillPolygon(CoreColor.HotPink, new[] {
new Vector2(10, 10),
new Vector2(200, 10),
new Vector2(200, 150),
new Vector2(10, 150) });
using (CoreImage image = new CoreImage(800, 800))
{
image.FillPolygon(
CoreColor.HotPink,
new[] {
new Vector2(10, 10),
new Vector2(200, 10),
new Vector2(200, 150),
new Vector2(10, 150) });
return new CoreSize(image.Width, image.Height);
return new CoreSize(image.Width, image.Height);
}
}
}
}

12
tests/ImageSharp.Benchmarks/Drawing/FillWithPattern.cs

@ -38,12 +38,14 @@ namespace ImageSharp.Benchmarks
[Benchmark(Description = "ImageSharp Fill with Pattern")]
public void DrawPatternPolygon3Core()
{
CoreImage image = new CoreImage(800, 800);
image.Fill(CoreBrushes.BackwardDiagonal(CoreColor.HotPink));
using (MemoryStream ms = new MemoryStream())
using (CoreImage image = new CoreImage(800, 800))
{
image.SaveAsBmp(ms);
image.Fill(CoreBrushes.BackwardDiagonal(CoreColor.HotPink));
using (MemoryStream ms = new MemoryStream())
{
image.SaveAsBmp(ms);
}
}
}
}

34
tests/ImageSharp.Benchmarks/Image/CopyPixels.cs

@ -17,24 +17,26 @@ namespace ImageSharp.Benchmarks.Image
[Benchmark(Description = "Copy by Pixel")]
public CoreColor CopyByPixel()
{
CoreImage source = new CoreImage(1024, 768);
CoreImage target = new CoreImage(1024, 768);
using (PixelAccessor<CoreColor> sourcePixels = source.Lock())
using (PixelAccessor<CoreColor> targetPixels = target.Lock())
using (CoreImage source = new CoreImage(1024, 768))
using (CoreImage target = new CoreImage(1024, 768))
{
Parallel.For(
0,
source.Height,
Configuration.Default.ParallelOptions,
y =>
{
for (int x = 0; x < source.Width; x++)
{
targetPixels[x, y] = sourcePixels[x, y];
}
});
using (PixelAccessor<CoreColor> sourcePixels = source.Lock())
using (PixelAccessor<CoreColor> targetPixels = target.Lock())
{
Parallel.For(
0,
source.Height,
Configuration.Default.ParallelOptions,
y =>
{
for (int x = 0; x < source.Width; x++)
{
targetPixels[x, y] = sourcePixels[x, y];
}
});
return targetPixels[0, 0];
return targetPixels[0, 0];
}
}
}
}

6
tests/ImageSharp.Benchmarks/Image/DecodeBmp.cs

@ -43,8 +43,10 @@ namespace ImageSharp.Benchmarks.Image
{
using (MemoryStream memoryStream = new MemoryStream(this.bmpBytes))
{
CoreImage image = new CoreImage(memoryStream);
return new CoreSize(image.Width, image.Height);
using (CoreImage image = new CoreImage(memoryStream))
{
return new CoreSize(image.Width, image.Height);
}
}
}
}

17
tests/ImageSharp.Benchmarks/Image/DecodeFilteredPng.cs

@ -29,37 +29,40 @@ namespace ImageSharp.Benchmarks.Image
this.filter4 = new MemoryStream(File.ReadAllBytes("../ImageSharp.Tests/TestImages/Formats/Png/filter4.png"));
}
private Image LoadPng(MemoryStream stream)
private Size LoadPng(MemoryStream stream)
{
return new Image(stream);
using (Image image = new Image(stream))
{
return new Size(image.Width, image.Height);
}
}
[Benchmark(Baseline = true, Description = "None-filtered PNG file")]
public Image PngFilter0()
public Size PngFilter0()
{
return LoadPng(filter0);
}
[Benchmark(Description = "Sub-filtered PNG file")]
public Image PngFilter1()
public Size PngFilter1()
{
return LoadPng(filter1);
}
[Benchmark(Description = "Up-filtered PNG file")]
public Image PngFilter2()
public Size PngFilter2()
{
return LoadPng(filter2);
}
[Benchmark(Description = "Average-filtered PNG file")]
public Image PngFilter3()
public Size PngFilter3()
{
return LoadPng(filter3);
}
[Benchmark(Description = "Paeth-filtered PNG file")]
public Image PngFilter4()
public Size PngFilter4()
{
return LoadPng(filter4);
}

6
tests/ImageSharp.Benchmarks/Image/DecodeGif.cs

@ -43,8 +43,10 @@ namespace ImageSharp.Benchmarks.Image
{
using (MemoryStream memoryStream = new MemoryStream(this.gifBytes))
{
CoreImage image = new CoreImage(memoryStream);
return new CoreSize(image.Width, image.Height);
using (CoreImage image = new CoreImage(memoryStream))
{
return new CoreSize(image.Width, image.Height);
}
}
}
}

6
tests/ImageSharp.Benchmarks/Image/DecodeJpeg.cs

@ -43,8 +43,10 @@ namespace ImageSharp.Benchmarks.Image
{
using (MemoryStream memoryStream = new MemoryStream(this.jpegBytes))
{
CoreImage image = new CoreImage(memoryStream);
return new CoreSize(image.Width, image.Height);
using (CoreImage image = new CoreImage(memoryStream))
{
return new CoreSize(image.Width, image.Height);
}
}
}
}

6
tests/ImageSharp.Benchmarks/Image/DecodePng.cs

@ -43,8 +43,10 @@ namespace ImageSharp.Benchmarks.Image
{
using (MemoryStream memoryStream = new MemoryStream(this.pngBytes))
{
CoreImage image = new CoreImage(memoryStream);
return new CoreSize(image.Width, image.Height);
using (CoreImage image = new CoreImage(memoryStream))
{
return new CoreSize(image.Width, image.Height);
}
}
}
}

8
tests/ImageSharp.Benchmarks/Image/EncodeBmp.cs

@ -31,6 +31,14 @@ namespace ImageSharp.Benchmarks.Image
}
}
[Cleanup]
public void Cleanup()
{
this.bmpStream.Dispose();
this.bmpCore.Dispose();
this.bmpDrawing.Dispose();
}
[Benchmark(Baseline = true, Description = "System.Drawing Bmp")]
public void BmpSystemDrawing()
{

4
tests/ImageSharp.Benchmarks/Image/EncodeBmpMultiple.cs

@ -18,7 +18,7 @@ namespace ImageSharp.Benchmarks.Image
protected override IEnumerable<string> InputImageSubfoldersOrFiles => new[] { "Bmp/", "Jpg/baseline" };
[Benchmark(Description = "EncodeBmpMultiple - ImageSharp")]
public void EncodeGifImageSharp()
public void EncodeBmpImageSharp()
{
this.ForEachImageSharpImage(
(img, ms) =>
@ -29,7 +29,7 @@ namespace ImageSharp.Benchmarks.Image
}
[Benchmark(Baseline = true, Description = "EncodeBmpMultiple - System.Drawing")]
public void EncodeGifSystemDrawing()
public void EncodeBmpSystemDrawing()
{
this.ForEachSystemDrawingImage(
(img, ms) =>

8
tests/ImageSharp.Benchmarks/Image/EncodeGif.cs

@ -31,6 +31,14 @@ namespace ImageSharp.Benchmarks.Image
}
}
[Cleanup]
public void Cleanup()
{
this.bmpStream.Dispose();
this.bmpCore.Dispose();
this.bmpDrawing.Dispose();
}
[Benchmark(Baseline = true, Description = "System.Drawing Gif")]
public void GifSystemDrawing()
{

8
tests/ImageSharp.Benchmarks/Image/EncodeJpeg.cs

@ -31,6 +31,14 @@ namespace ImageSharp.Benchmarks.Image
}
}
[Cleanup]
public void Cleanup()
{
this.bmpStream.Dispose();
this.bmpCore.Dispose();
this.bmpDrawing.Dispose();
}
[Benchmark(Baseline = true, Description = "System.Drawing Jpeg")]
public void JpegSystemDrawing()
{

8
tests/ImageSharp.Benchmarks/Image/EncodePng.cs

@ -31,6 +31,14 @@ namespace ImageSharp.Benchmarks.Image
}
}
[Cleanup]
public void Cleanup()
{
this.bmpStream.Dispose();
this.bmpCore.Dispose();
this.bmpDrawing.Dispose();
}
[Benchmark(Baseline = true, Description = "System.Drawing Png")]
public void PngSystemDrawing()
{

10
tests/ImageSharp.Benchmarks/Image/GetSetPixel.cs

@ -28,11 +28,13 @@ namespace ImageSharp.Benchmarks.Image
[Benchmark(Description = "ImageSharp GetSet pixel")]
public CoreColor ResizeCore()
{
CoreImage image = new CoreImage(400, 400);
using (PixelAccessor<CoreColor> imagePixels = image.Lock())
using (CoreImage image = new CoreImage(400, 400))
{
imagePixels[200, 200] = CoreColor.White;
return imagePixels[200, 200];
using (PixelAccessor<CoreColor> imagePixels = image.Lock())
{
imagePixels[200, 200] = CoreColor.White;
return imagePixels[200, 200];
}
}
}
}

8
tests/ImageSharp.Benchmarks/Samplers/Crop.cs

@ -38,9 +38,11 @@ namespace ImageSharp.Benchmarks
[Benchmark(Description = "ImageSharp Crop")]
public CoreSize CropResizeCore()
{
CoreImage image = new CoreImage(800, 800);
image.Crop(100, 100);
return new CoreSize(image.Width, image.Height);
using (CoreImage image = new CoreImage(800, 800))
{
image.Crop(100, 100);
return new CoreSize(image.Width, image.Height);
}
}
}
}

6
tests/ImageSharp.Benchmarks/Samplers/DetectEdges.cs

@ -28,6 +28,12 @@ namespace ImageSharp.Benchmarks
}
}
[Cleanup]
public void Cleanup()
{
this.image.Dispose();
}
[Benchmark(Description = "ImageSharp DetectEdges")]
public void ImageProcessorCoreDetectEdges()
{

16
tests/ImageSharp.Benchmarks/Samplers/Resize.cs

@ -37,17 +37,21 @@ namespace ImageSharp.Benchmarks
[Benchmark(Description = "ImageSharp Resize")]
public CoreSize ResizeCore()
{
CoreImage image = new CoreImage(2000, 2000);
image.Resize(400, 400);
return new CoreSize(image.Width, image.Height);
using (CoreImage image = new CoreImage(2000, 2000))
{
image.Resize(400, 400);
return new CoreSize(image.Width, image.Height);
}
}
[Benchmark(Description = "ImageSharp Compand Resize")]
public CoreSize ResizeCoreCompand()
{
CoreImage image = new CoreImage(2000, 2000);
image.Resize(400, 400, true);
return new CoreSize(image.Width, image.Height);
using (CoreImage image = new CoreImage(2000, 2000))
{
image.Resize(400, 400, true);
return new CoreSize(image.Width, image.Height);
}
}
}
}

137
tests/ImageSharp.Tests/Drawing/BeziersTests.cs

@ -15,89 +15,88 @@ namespace ImageSharp.Tests.Drawing
public class Beziers : FileTestBase
{
[Fact]
public void ImageShouldBeOverlayedByBezierLine()
{
string path = CreateOutputDirectory("Drawing","BezierLine");
var image = new Image(500, 500);
using (FileStream output = File.OpenWrite($"{path}/Simple.png"))
{
image
.BackgroundColor(Color.Blue)
.DrawBeziers(Color.HotPink, 5, new[] {
new Vector2(10, 400),
new Vector2(30, 10),
new Vector2(240, 30),
new Vector2(300, 400)
})
.Save(output);
}
using (var sourcePixels = image.Lock())
string path = this.CreateOutputDirectory("Drawing", "BezierLine");
using (Image image = new Image(500, 500))
{
//top of curve
Assert.Equal(Color.HotPink, sourcePixels[138,115]);
//start points
Assert.Equal(Color.HotPink, sourcePixels[10, 400]);
Assert.Equal(Color.HotPink, sourcePixels[300, 400]);
//curve points should not be never be set
Assert.Equal(Color.Blue, sourcePixels[30, 10]);
Assert.Equal(Color.Blue, sourcePixels[240, 30]);
// inside shape should be empty
Assert.Equal(Color.Blue, sourcePixels[200, 250]);
using (FileStream output = File.OpenWrite($"{path}/Simple.png"))
{
image.BackgroundColor(Color.Blue)
.DrawBeziers(Color.HotPink, 5,
new[] {
new Vector2(10, 400),
new Vector2(30, 10),
new Vector2(240, 30),
new Vector2(300, 400)
})
.Save(output);
}
using (PixelAccessor<Color> sourcePixels = image.Lock())
{
//top of curve
Assert.Equal(Color.HotPink, sourcePixels[138, 115]);
//start points
Assert.Equal(Color.HotPink, sourcePixels[10, 400]);
Assert.Equal(Color.HotPink, sourcePixels[300, 400]);
//curve points should not be never be set
Assert.Equal(Color.Blue, sourcePixels[30, 10]);
Assert.Equal(Color.Blue, sourcePixels[240, 30]);
// inside shape should be empty
Assert.Equal(Color.Blue, sourcePixels[200, 250]);
}
}
}
[Fact]
public void ImageShouldBeOverlayedBezierLineWithOpacity()
{
string path = CreateOutputDirectory("Drawing", "BezierLine");
string path = this.CreateOutputDirectory("Drawing", "BezierLine");
var color = new Color(Color.HotPink.R, Color.HotPink.G, Color.HotPink.B, 150);
Color color = new Color(Color.HotPink.R, Color.HotPink.G, Color.HotPink.B, 150);
var image = new Image(500, 500);
using (FileStream output = File.OpenWrite($"{path}/Opacity.png"))
using (Image image = new Image(500, 500))
{
image
.BackgroundColor(Color.Blue)
.DrawBeziers(color, 10, new[] {
new Vector2(10, 400),
new Vector2(30, 10),
new Vector2(240, 30),
new Vector2(300, 400)
})
.Save(output);
using (FileStream output = File.OpenWrite($"{path}/Opacity.png"))
{
image.BackgroundColor(Color.Blue)
.DrawBeziers(color,
10,
new[] {
new Vector2(10, 400),
new Vector2(30, 10),
new Vector2(240, 30),
new Vector2(300, 400)
})
.Save(output);
}
//shift background color towards forground color by the opacity amount
Color mergedColor = new Color(Vector4.Lerp(Color.Blue.ToVector4(), Color.HotPink.ToVector4(), 150f / 255f));
using (PixelAccessor<Color> sourcePixels = image.Lock())
{
//top of curve
Assert.Equal(mergedColor, sourcePixels[138, 115]);
//start points
Assert.Equal(mergedColor, sourcePixels[10, 400]);
Assert.Equal(mergedColor, sourcePixels[300, 400]);
//curve points should not be never be set
Assert.Equal(Color.Blue, sourcePixels[30, 10]);
Assert.Equal(Color.Blue, sourcePixels[240, 30]);
// inside shape should be empty
Assert.Equal(Color.Blue, sourcePixels[200, 250]);
}
}
//shift background color towards forground color by the opacity amount
var mergedColor = new Color(Vector4.Lerp(Color.Blue.ToVector4(), Color.HotPink.ToVector4(), 150f/255f));
using (var sourcePixels = image.Lock())
{
//top of curve
Assert.Equal(mergedColor, sourcePixels[138, 115]);
//start points
Assert.Equal(mergedColor, sourcePixels[10, 400]);
Assert.Equal(mergedColor, sourcePixels[300, 400]);
//curve points should not be never be set
Assert.Equal(Color.Blue, sourcePixels[30, 10]);
Assert.Equal(Color.Blue, sourcePixels[240, 30]);
// inside shape should be empty
Assert.Equal(Color.Blue, sourcePixels[200, 250]);
}
}
}
}
}

21
tests/ImageSharp.Tests/Drawing/DrawImageTest.cs

@ -6,7 +6,6 @@
namespace ImageSharp.Tests
{
using System.IO;
using System.Linq;
using Xunit;
@ -15,18 +14,20 @@ namespace ImageSharp.Tests
[Fact]
public void ImageShouldApplyDrawImageFilter()
{
string path = CreateOutputDirectory("Drawing", "DrawImage");
string path = this.CreateOutputDirectory("Drawing", "DrawImage");
Image blend = TestFile.Create(TestImages.Bmp.Car).CreateImage();
foreach (TestFile file in Files)
using (Image blend = TestFile.Create(TestImages.Bmp.Car).CreateImage())
{
Image image = file.CreateImage();
using (FileStream output = File.OpenWrite($"{path}/{file.FileName}"))
foreach (TestFile file in Files)
{
image.DrawImage(blend, 75, new Size(image.Width / 2, image.Height / 2), new Point(image.Width / 4, image.Height / 4))
.Save(output);
using (Image image = file.CreateImage())
{
using (FileStream output = File.OpenWrite($"{path}/{file.FileName}"))
{
image.DrawImage(blend, 75, new Size(image.Width / 2, image.Height / 2), new Point(image.Width / 4, image.Height / 4))
.Save(output);
}
}
}
}
}

101
tests/ImageSharp.Tests/Drawing/DrawPathTests.cs

@ -20,81 +20,82 @@ namespace ImageSharp.Tests.Drawing
[Fact]
public void ImageShouldBeOverlayedByPath()
{
string path = CreateOutputDirectory("Drawing", "Path");
var image = new Image(500, 500);
var linerSegemnt = new LinearLineSegment(
new Vector2(10, 10),
new Vector2(200, 150),
new Vector2(50, 300));
var bazierSegment = new BezierLineSegment(new Vector2(50, 300),
new Vector2(500, 500),
new Vector2(60, 10),
new Vector2(10, 400));
var p = new CorePath(linerSegemnt, bazierSegment);
using (FileStream output = File.OpenWrite($"{path}/Simple.png"))
{
image
.BackgroundColor(Color.Blue)
.DrawPath(Color.HotPink, 5, p)
.Save(output);
}
using (var sourcePixels = image.Lock())
string path = this.CreateOutputDirectory("Drawing", "Path");
using (Image image = new Image(500, 500))
{
Assert.Equal(Color.HotPink, sourcePixels[9, 9]);
Assert.Equal(Color.HotPink, sourcePixels[199, 149]);
Assert.Equal(Color.Blue, sourcePixels[50, 50]);
LinearLineSegment linerSegemnt = new LinearLineSegment(
new Vector2(10, 10),
new Vector2(200, 150),
new Vector2(50, 300));
BezierLineSegment bazierSegment = new BezierLineSegment(new Vector2(50, 300),
new Vector2(500, 500),
new Vector2(60, 10),
new Vector2(10, 400));
CorePath p = new CorePath(linerSegemnt, bazierSegment);
using (FileStream output = File.OpenWrite($"{path}/Simple.png"))
{
image
.BackgroundColor(Color.Blue)
.DrawPath(Color.HotPink, 5, p)
.Save(output);
}
using (PixelAccessor<Color> sourcePixels = image.Lock())
{
Assert.Equal(Color.HotPink, sourcePixels[9, 9]);
Assert.Equal(Color.HotPink, sourcePixels[199, 149]);
Assert.Equal(Color.Blue, sourcePixels[50, 50]);
}
}
}
[Fact]
public void ImageShouldBeOverlayedPathWithOpacity()
{
string path = CreateOutputDirectory("Drawing", "Path");
string path = this.CreateOutputDirectory("Drawing", "Path");
var color = new Color(Color.HotPink.R, Color.HotPink.G, Color.HotPink.B, 150);
Color color = new Color(Color.HotPink.R, Color.HotPink.G, Color.HotPink.B, 150);
var linerSegemnt = new LinearLineSegment(
LinearLineSegment linerSegemnt = new LinearLineSegment(
new Vector2(10, 10),
new Vector2(200, 150),
new Vector2(50, 300)
);
var bazierSegment = new BezierLineSegment(new Vector2(50, 300),
BezierLineSegment bazierSegment = new BezierLineSegment(new Vector2(50, 300),
new Vector2(500, 500),
new Vector2(60, 10),
new Vector2(10, 400));
var p = new CorePath(linerSegemnt, bazierSegment);
CorePath p = new CorePath(linerSegemnt, bazierSegment);
var image = new Image(500, 500);
using (FileStream output = File.OpenWrite($"{path}/Opacity.png"))
using (Image image = new Image(500, 500))
{
image
.BackgroundColor(Color.Blue)
.DrawPath(color, 10, p)
.Save(output);
}
using (FileStream output = File.OpenWrite($"{path}/Opacity.png"))
{
image
.BackgroundColor(Color.Blue)
.DrawPath(color, 10, p)
.Save(output);
}
//shift background color towards forground color by the opacity amount
var mergedColor = new Color(Vector4.Lerp(Color.Blue.ToVector4(), Color.HotPink.ToVector4(), 150f / 255f));
//shift background color towards forground color by the opacity amount
Color mergedColor = new Color(Vector4.Lerp(Color.Blue.ToVector4(), Color.HotPink.ToVector4(), 150f / 255f));
using (var sourcePixels = image.Lock())
{
Assert.Equal(mergedColor, sourcePixels[9, 9]);
using (PixelAccessor<Color> sourcePixels = image.Lock())
{
Assert.Equal(mergedColor, sourcePixels[9, 9]);
Assert.Equal(mergedColor, sourcePixels[199, 149]);
Assert.Equal(mergedColor, sourcePixels[199, 149]);
Assert.Equal(Color.Blue, sourcePixels[50, 50]);
Assert.Equal(Color.Blue, sourcePixels[50, 50]);
}
}
}

71
tests/ImageSharp.Tests/Drawing/FillPatternTests.cs

@ -15,55 +15,56 @@ namespace ImageSharp.Tests.Drawing
public class FillPatternBrushTests : FileTestBase
{
private Image Test(string name, Color background, IBrush<Color> brush, Color[,] expectedPattern)
private void Test(string name, Color background, IBrush<Color> brush, Color[,] expectedPattern)
{
string path = CreateOutputDirectory("Fill", "PatternBrush");
Image image = new Image(20, 20);
image
.Fill(background)
.Fill(brush);
using (FileStream output = File.OpenWrite($"{path}/{name}.png"))
{
image.Save(output);
}
using (var sourcePixels = image.Lock())
string path = this.CreateOutputDirectory("Fill", "PatternBrush");
using (Image image = new Image(20, 20))
{
// lets pick random spots to start checking
var r = new Random();
var xStride = expectedPattern.GetLength(1);
var yStride = expectedPattern.GetLength(0);
var offsetX = r.Next(image.Width / xStride) * xStride;
var offsetY = r.Next(image.Height / yStride) * yStride;
for (var x = 0; x < xStride; x++)
image
.Fill(background)
.Fill(brush);
using (FileStream output = File.OpenWrite($"{path}/{name}.png"))
{
for (var y = 0; y < yStride; y++)
image.Save(output);
}
using (PixelAccessor<Color> sourcePixels = image.Lock())
{
// lets pick random spots to start checking
Random r = new Random();
int xStride = expectedPattern.GetLength(1);
int yStride = expectedPattern.GetLength(0);
int offsetX = r.Next(image.Width / xStride) * xStride;
int offsetY = r.Next(image.Height / yStride) * yStride;
for (int x = 0; x < xStride; x++)
{
var actualX = x + offsetX;
var actualY = y + offsetY;
var expected = expectedPattern[y, x]; // inverted pattern
var actual = sourcePixels[actualX, actualY];
if (expected != actual)
for (int y = 0; y < yStride; y++)
{
Assert.True(false, $"Expected {expected} but found {actual} at ({actualX},{actualY})");
int actualX = x + offsetX;
int actualY = y + offsetY;
Color expected = expectedPattern[y, x]; // inverted pattern
Color actual = sourcePixels[actualX, actualY];
if (expected != actual)
{
Assert.True(false, $"Expected {expected} but found {actual} at ({actualX},{actualY})");
}
}
}
}
using (FileStream output = File.OpenWrite($"{path}/{name}x4.png"))
{
image.Resize(80, 80).Save(output);
}
}
using (FileStream output = File.OpenWrite($"{path}/{name}x4.png"))
{
image.Resize(80, 80).Save(output);
}
return image;
}
[Fact]
public void ImageShouldBeFloodFilledWithPercent10()
{
Test("Percent10", Color.Blue, Brushes.Percent10(Color.HotPink, Color.LimeGreen), new Color[,] {
this.Test("Percent10", Color.Blue, Brushes.Percent10(Color.HotPink, Color.LimeGreen),
new[,]
{
{ Color.HotPink , Color.LimeGreen, Color.LimeGreen, Color.LimeGreen},
{ Color.LimeGreen, Color.LimeGreen, Color.LimeGreen, Color.LimeGreen},
{ Color.LimeGreen, Color.LimeGreen, Color.HotPink , Color.LimeGreen},

100
tests/ImageSharp.Tests/Drawing/FillSolidBrushTests.cs

@ -18,71 +18,73 @@ namespace ImageSharp.Tests.Drawing
[Fact]
public void ImageShouldBeFloodFilledWithColorOnDefaultBackground()
{
string path = CreateOutputDirectory("Fill", "SolidBrush");
var image = new Image(500, 500);
using (FileStream output = File.OpenWrite($"{path}/DefaultBack.png"))
string path = this.CreateOutputDirectory("Fill", "SolidBrush");
using (Image image = new Image(500, 500))
{
image
.Fill(Color.HotPink)
.Save(output);
}
using (var sourcePixels = image.Lock())
{
Assert.Equal(Color.HotPink, sourcePixels[9, 9]);
Assert.Equal(Color.HotPink, sourcePixels[199, 149]);
using (FileStream output = File.OpenWrite($"{path}/DefaultBack.png"))
{
image
.Fill(Color.HotPink)
.Save(output);
}
using (PixelAccessor<Color> sourcePixels = image.Lock())
{
Assert.Equal(Color.HotPink, sourcePixels[9, 9]);
Assert.Equal(Color.HotPink, sourcePixels[199, 149]);
}
}
}
[Fact]
public void ImageShouldBeFloodFilledWithColor()
{
string path = CreateOutputDirectory("Fill", "SolidBrush");
var image = new Image(500, 500);
using (FileStream output = File.OpenWrite($"{path}/Simple.png"))
string path = this.CreateOutputDirectory("Fill", "SolidBrush");
using (Image image = new Image(500, 500))
{
image
.BackgroundColor(Color.Blue)
.Fill(Color.HotPink)
.Save(output);
}
using (var sourcePixels = image.Lock())
{
Assert.Equal(Color.HotPink, sourcePixels[9, 9]);
Assert.Equal(Color.HotPink, sourcePixels[199, 149]);
using (FileStream output = File.OpenWrite($"{path}/Simple.png"))
{
image
.BackgroundColor(Color.Blue)
.Fill(Color.HotPink)
.Save(output);
}
using (PixelAccessor<Color> sourcePixels = image.Lock())
{
Assert.Equal(Color.HotPink, sourcePixels[9, 9]);
Assert.Equal(Color.HotPink, sourcePixels[199, 149]);
}
}
}
[Fact]
public void ImageShouldBeFloodFilledWithColorOpacity()
{
string path = CreateOutputDirectory("Fill", "SolidBrush");
var image = new Image(500, 500);
var color = new Color(Color.HotPink.R, Color.HotPink.G, Color.HotPink.B, 150);
using (FileStream output = File.OpenWrite($"{path}/Opacity.png"))
{
image
.BackgroundColor(Color.Blue)
.Fill(color)
.Save(output);
}
//shift background color towards forground color by the opacity amount
var mergedColor = new Color(Vector4.Lerp(Color.Blue.ToVector4(), Color.HotPink.ToVector4(), 150f / 255f));
using (var sourcePixels = image.Lock())
string path = this.CreateOutputDirectory("Fill", "SolidBrush");
using (Image image = new Image(500, 500))
{
Assert.Equal(mergedColor, sourcePixels[9, 9]);
Assert.Equal(mergedColor, sourcePixels[199, 149]);
Color color = new Color(Color.HotPink.R, Color.HotPink.G, Color.HotPink.B, 150);
using (FileStream output = File.OpenWrite($"{path}/Opacity.png"))
{
image
.BackgroundColor(Color.Blue)
.Fill(color)
.Save(output);
}
//shift background color towards forground color by the opacity amount
Color mergedColor = new Color(Vector4.Lerp(Color.Blue.ToVector4(), Color.HotPink.ToVector4(), 150f / 255f));
using (PixelAccessor<Color> sourcePixels = image.Lock())
{
Assert.Equal(mergedColor, sourcePixels[9, 9]);
Assert.Equal(mergedColor, sourcePixels[199, 149]);
}
}
}
}

226
tests/ImageSharp.Tests/Drawing/LineComplexPolygonTests.cs

@ -5,12 +5,9 @@
namespace ImageSharp.Tests.Drawing
{
using System;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using Xunit;
using Drawing;
using ImageSharp.Drawing;
using System.Numerics;
using ImageSharp.Drawing.Shapes;
using ImageSharp.Drawing.Pens;
@ -20,98 +17,100 @@ namespace ImageSharp.Tests.Drawing
[Fact]
public void ImageShouldBeOverlayedByPolygonOutline()
{
string path = CreateOutputDirectory("Drawing", "LineComplexPolygon");
var simplePath = new LinearPolygon(
string path = this.CreateOutputDirectory("Drawing", "LineComplexPolygon");
LinearPolygon simplePath = new LinearPolygon(
new Vector2(10, 10),
new Vector2(200, 150),
new Vector2(50, 300));
var hole1 = new LinearPolygon(
LinearPolygon hole1 = new LinearPolygon(
new Vector2(37, 85),
new Vector2(93, 85),
new Vector2(65, 137));
var image = new Image(500, 500);
using (FileStream output = File.OpenWrite($"{path}/Simple.png"))
using (Image image = new Image(500, 500))
{
image
.BackgroundColor(Color.Blue)
.DrawPolygon(Color.HotPink, 5, new ComplexPolygon(simplePath, hole1))
.Save(output);
}
using (FileStream output = File.OpenWrite($"{path}/Simple.png"))
{
image
.BackgroundColor(Color.Blue)
.DrawPolygon(Color.HotPink, 5, new ComplexPolygon(simplePath, hole1))
.Save(output);
}
using (var sourcePixels = image.Lock())
{
Assert.Equal(Color.HotPink, sourcePixels[10, 10]);
using (PixelAccessor<Color> sourcePixels = image.Lock())
{
Assert.Equal(Color.HotPink, sourcePixels[10, 10]);
Assert.Equal(Color.HotPink, sourcePixels[200, 150]);
Assert.Equal(Color.HotPink, sourcePixels[200, 150]);
Assert.Equal(Color.HotPink, sourcePixels[50, 300]);
Assert.Equal(Color.HotPink, sourcePixels[50, 300]);
Assert.Equal(Color.HotPink, sourcePixels[37, 85]);
Assert.Equal(Color.HotPink, sourcePixels[37, 85]);
Assert.Equal(Color.HotPink, sourcePixels[93, 85]);
Assert.Equal(Color.HotPink, sourcePixels[93, 85]);
Assert.Equal(Color.HotPink, sourcePixels[65, 137]);
Assert.Equal(Color.HotPink, sourcePixels[65, 137]);
Assert.Equal(Color.Blue, sourcePixels[2, 2]);
Assert.Equal(Color.Blue, sourcePixels[2, 2]);
//inside hole
Assert.Equal(Color.Blue, sourcePixels[57, 99]);
//inside hole
Assert.Equal(Color.Blue, sourcePixels[57, 99]);
//inside shape
Assert.Equal(Color.Blue, sourcePixels[100, 192]);
//inside shape
Assert.Equal(Color.Blue, sourcePixels[100, 192]);
}
}
}
[Fact]
public void ImageShouldBeOverlayedByPolygonOutlineNoOverlapping()
{
string path = CreateOutputDirectory("Drawing", "LineComplexPolygon");
var simplePath = new LinearPolygon(
string path = this.CreateOutputDirectory("Drawing", "LineComplexPolygon");
LinearPolygon simplePath = new LinearPolygon(
new Vector2(10, 10),
new Vector2(200, 150),
new Vector2(50, 300));
var hole1 = new LinearPolygon(
LinearPolygon hole1 = new LinearPolygon(
new Vector2(207, 25),
new Vector2(263, 25),
new Vector2(235, 57));
var image = new Image(500, 500);
using (FileStream output = File.OpenWrite($"{path}/SimpleVanishHole.png"))
using (Image image = new Image(500, 500))
{
image
.BackgroundColor(Color.Blue)
.DrawPolygon(Color.HotPink, 5, new ComplexPolygon(simplePath, hole1))
.Save(output);
}
using (FileStream output = File.OpenWrite($"{path}/SimpleVanishHole.png"))
{
image
.BackgroundColor(Color.Blue)
.DrawPolygon(Color.HotPink, 5, new ComplexPolygon(simplePath, hole1))
.Save(output);
}
using (var sourcePixels = image.Lock())
{
Assert.Equal(Color.HotPink, sourcePixels[10, 10]);
using (PixelAccessor<Color> sourcePixels = image.Lock())
{
Assert.Equal(Color.HotPink, sourcePixels[10, 10]);
Assert.Equal(Color.HotPink, sourcePixels[200, 150]);
Assert.Equal(Color.HotPink, sourcePixels[200, 150]);
Assert.Equal(Color.HotPink, sourcePixels[50, 300]);
Assert.Equal(Color.HotPink, sourcePixels[50, 300]);
//Assert.Equal(Color.HotPink, sourcePixels[37, 85]);
//Assert.Equal(Color.HotPink, sourcePixels[37, 85]);
//Assert.Equal(Color.HotPink, sourcePixels[93, 85]);
//Assert.Equal(Color.HotPink, sourcePixels[93, 85]);
//Assert.Equal(Color.HotPink, sourcePixels[65, 137]);
//Assert.Equal(Color.HotPink, sourcePixels[65, 137]);
Assert.Equal(Color.Blue, sourcePixels[2, 2]);
Assert.Equal(Color.Blue, sourcePixels[2, 2]);
//inside hole
Assert.Equal(Color.Blue, sourcePixels[57, 99]);
//inside hole
Assert.Equal(Color.Blue, sourcePixels[57, 99]);
//inside shape
Assert.Equal(Color.Blue, sourcePixels[100, 192]);
//inside shape
Assert.Equal(Color.Blue, sourcePixels[100, 192]);
}
}
}
@ -119,44 +118,45 @@ namespace ImageSharp.Tests.Drawing
[Fact]
public void ImageShouldBeOverlayedByPolygonOutlineOverlapping()
{
string path = CreateOutputDirectory("Drawing", "LineComplexPolygon");
var simplePath = new LinearPolygon(
string path = this.CreateOutputDirectory("Drawing", "LineComplexPolygon");
LinearPolygon simplePath = new LinearPolygon(
new Vector2(10, 10),
new Vector2(200, 150),
new Vector2(50, 300));
var hole1 = new LinearPolygon(
LinearPolygon hole1 = new LinearPolygon(
new Vector2(37, 85),
new Vector2(130, 40),
new Vector2(65, 137));
var image = new Image(500, 500);
using (FileStream output = File.OpenWrite($"{path}/SimpleOverlapping.png"))
using (Image image = new Image(500, 500))
{
image
.BackgroundColor(Color.Blue)
.DrawPolygon(Color.HotPink, 5, new ComplexPolygon(simplePath, hole1))
.Save(output);
}
using (FileStream output = File.OpenWrite($"{path}/SimpleOverlapping.png"))
{
image
.BackgroundColor(Color.Blue)
.DrawPolygon(Color.HotPink, 5, new ComplexPolygon(simplePath, hole1))
.Save(output);
}
using (var sourcePixels = image.Lock())
{
Assert.Equal(Color.HotPink, sourcePixels[10, 10]);
using (PixelAccessor<Color> sourcePixels = image.Lock())
{
Assert.Equal(Color.HotPink, sourcePixels[10, 10]);
Assert.Equal(Color.HotPink, sourcePixels[200, 150]);
Assert.Equal(Color.HotPink, sourcePixels[200, 150]);
Assert.Equal(Color.HotPink, sourcePixels[50, 300]);
Assert.Equal(Color.HotPink, sourcePixels[50, 300]);
Assert.Equal(Color.Blue, sourcePixels[130, 41]);
Assert.Equal(Color.Blue, sourcePixels[2, 2]);
Assert.Equal(Color.Blue, sourcePixels[130, 41]);
//inside hole
Assert.Equal(Color.Blue, sourcePixels[57, 99]);
Assert.Equal(Color.Blue, sourcePixels[2, 2]);
//inside shape
Assert.Equal(Color.Blue, sourcePixels[100, 192]);
//inside hole
Assert.Equal(Color.Blue, sourcePixels[57, 99]);
//inside shape
Assert.Equal(Color.Blue, sourcePixels[100, 192]);
}
}
}
@ -164,25 +164,26 @@ namespace ImageSharp.Tests.Drawing
[Fact]
public void ImageShouldBeOverlayedByPolygonOutlineDashed()
{
string path = CreateOutputDirectory("Drawing", "LineComplexPolygon");
var simplePath = new LinearPolygon(
string path = this.CreateOutputDirectory("Drawing", "LineComplexPolygon");
LinearPolygon simplePath = new LinearPolygon(
new Vector2(10, 10),
new Vector2(200, 150),
new Vector2(50, 300));
var hole1 = new LinearPolygon(
LinearPolygon hole1 = new LinearPolygon(
new Vector2(37, 85),
new Vector2(93, 85),
new Vector2(65, 137));
var image = new Image(500, 500);
using (FileStream output = File.OpenWrite($"{path}/Dashed.png"))
using (Image image = new Image(500, 500))
{
image
.BackgroundColor(Color.Blue)
.DrawPolygon(Pens.Dash(Color.HotPink, 5), new ComplexPolygon(simplePath, hole1))
.Save(output);
using (FileStream output = File.OpenWrite($"{path}/Dashed.png"))
{
image
.BackgroundColor(Color.Blue)
.DrawPolygon(Pens.Dash(Color.HotPink, 5), new ComplexPolygon(simplePath, hole1))
.Save(output);
}
}
}
@ -190,54 +191,55 @@ namespace ImageSharp.Tests.Drawing
[Fact]
public void ImageShouldBeOverlayedPolygonOutlineWithOpacity()
{
string path = CreateOutputDirectory("Drawing", "LineComplexPolygon");
var simplePath = new LinearPolygon(
string path = this.CreateOutputDirectory("Drawing", "LineComplexPolygon");
LinearPolygon simplePath = new LinearPolygon(
new Vector2(10, 10),
new Vector2(200, 150),
new Vector2(50, 300));
var hole1 = new LinearPolygon(
LinearPolygon hole1 = new LinearPolygon(
new Vector2(37, 85),
new Vector2(93, 85),
new Vector2(65, 137));
var color = new Color(Color.HotPink.R, Color.HotPink.G, Color.HotPink.B, 150);
Color color = new Color(Color.HotPink.R, Color.HotPink.G, Color.HotPink.B, 150);
var image = new Image(500, 500);
using (FileStream output = File.OpenWrite($"{path}/Opacity.png"))
using (Image image = new Image(500, 500))
{
image
.BackgroundColor(Color.Blue)
.DrawPolygon(color, 5, new ComplexPolygon(simplePath, hole1))
.Save(output);
}
using (FileStream output = File.OpenWrite($"{path}/Opacity.png"))
{
image
.BackgroundColor(Color.Blue)
.DrawPolygon(color, 5, new ComplexPolygon(simplePath, hole1))
.Save(output);
}
//shift background color towards forground color by the opacity amount
var mergedColor = new Color(Vector4.Lerp(Color.Blue.ToVector4(), Color.HotPink.ToVector4(), 150f / 255f));
//shift background color towards forground color by the opacity amount
Color mergedColor = new Color(Vector4.Lerp(Color.Blue.ToVector4(), Color.HotPink.ToVector4(), 150f / 255f));
using (var sourcePixels = image.Lock())
{
Assert.Equal(mergedColor, sourcePixels[10, 10]);
using (PixelAccessor<Color> sourcePixels = image.Lock())
{
Assert.Equal(mergedColor, sourcePixels[10, 10]);
Assert.Equal(mergedColor, sourcePixels[200, 150]);
Assert.Equal(mergedColor, sourcePixels[200, 150]);
Assert.Equal(mergedColor, sourcePixels[50, 300]);
Assert.Equal(mergedColor, sourcePixels[50, 300]);
Assert.Equal(mergedColor, sourcePixels[37, 85]);
Assert.Equal(mergedColor, sourcePixels[37, 85]);
Assert.Equal(mergedColor, sourcePixels[93, 85]);
Assert.Equal(mergedColor, sourcePixels[93, 85]);
Assert.Equal(mergedColor, sourcePixels[65, 137]);
Assert.Equal(mergedColor, sourcePixels[65, 137]);
Assert.Equal(Color.Blue, sourcePixels[2, 2]);
Assert.Equal(Color.Blue, sourcePixels[2, 2]);
//inside hole
Assert.Equal(Color.Blue, sourcePixels[57, 99]);
//inside hole
Assert.Equal(Color.Blue, sourcePixels[57, 99]);
//inside shape
Assert.Equal(Color.Blue, sourcePixels[100, 192]);
//inside shape
Assert.Equal(Color.Blue, sourcePixels[100, 192]);
}
}
}
}

155
tests/ImageSharp.Tests/Drawing/LineTests.cs

@ -5,11 +5,9 @@
namespace ImageSharp.Tests.Drawing
{
using Drawing;
using ImageSharp.Drawing;
using ImageSharp.Drawing.Pens;
using System;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Numerics;
using Xunit;
@ -19,123 +17,132 @@ namespace ImageSharp.Tests.Drawing
[Fact]
public void ImageShouldBeOverlayedByPath()
{
string path = CreateOutputDirectory("Drawing", "Lines");
var image = new Image(500, 500);
using (FileStream output = File.OpenWrite($"{path}/Simple.png"))
string path = this.CreateOutputDirectory("Drawing", "Lines");
using (Image image = new Image(500, 500))
{
image
.BackgroundColor(Color.Blue)
.DrawLines(Color.HotPink, 5, new[] {
using (FileStream output = File.OpenWrite($"{path}/Simple.png"))
{
image
.BackgroundColor(Color.Blue)
.DrawLines(Color.HotPink, 5,
new[] {
new Vector2(10, 10),
new Vector2(200, 150),
new Vector2(50, 300)
})
.Save(output);
}
})
.Save(output);
}
using (var sourcePixels = image.Lock())
{
Assert.Equal(Color.HotPink, sourcePixels[9, 9]);
using (PixelAccessor<Color> sourcePixels = image.Lock())
{
Assert.Equal(Color.HotPink, sourcePixels[9, 9]);
Assert.Equal(Color.HotPink, sourcePixels[199, 149]);
Assert.Equal(Color.HotPink, sourcePixels[199, 149]);
Assert.Equal(Color.Blue, sourcePixels[50, 50]);
Assert.Equal(Color.Blue, sourcePixels[50, 50]);
}
}
}
[Fact]
public void ImageShouldBeOverlayedByPath_NoAntialias()
{
string path = CreateOutputDirectory("Drawing", "Lines");
var image = new Image(500, 500);
using (FileStream output = File.OpenWrite($"{path}/Simple_noantialias.png"))
string path = this.CreateOutputDirectory("Drawing", "Lines");
using (Image image = new Image(500, 500))
{
image
.BackgroundColor(Color.Blue)
.DrawLines(Color.HotPink, 5, new[] {
using (FileStream output = File.OpenWrite($"{path}/Simple_noantialias.png"))
{
image
.BackgroundColor(Color.Blue)
.DrawLines(Color.HotPink, 5,
new[] {
new Vector2(10, 10),
new Vector2(200, 150),
new Vector2(50, 300)
}, new GraphicsOptions(false))
.Save(output);
}
},
new GraphicsOptions(false))
.Save(output);
}
using (var sourcePixels = image.Lock())
{
Assert.Equal(Color.HotPink, sourcePixels[9, 9]);
using (PixelAccessor<Color> sourcePixels = image.Lock())
{
Assert.Equal(Color.HotPink, sourcePixels[9, 9]);
Assert.Equal(Color.HotPink, sourcePixels[199, 149]);
Assert.Equal(Color.HotPink, sourcePixels[199, 149]);
Assert.Equal(Color.Blue, sourcePixels[50, 50]);
Assert.Equal(Color.Blue, sourcePixels[50, 50]);
}
}
}
[Fact]
public void ImageShouldBeOverlayedByPathDashed()
{
string path = CreateOutputDirectory("Drawing", "Lines");
var image = new Image(500, 500);
using (FileStream output = File.OpenWrite($"{path}/Dashed.png"))
string path = this.CreateOutputDirectory("Drawing", "Lines");
using (Image image = new Image(500, 500))
{
image
.BackgroundColor(Color.Blue)
.DrawLines(Pens.Dash(Color.HotPink, 5), new[] {
using (FileStream output = File.OpenWrite($"{path}/Dashed.png"))
{
image
.BackgroundColor(Color.Blue)
.DrawLines(Pens.Dash(Color.HotPink, 5),
new[] {
new Vector2(10, 10),
new Vector2(200, 150),
new Vector2(50, 300)
})
.Save(output);
})
.Save(output);
}
}
}
[Fact]
public void ImageShouldBeOverlayedByPathDotted()
{
string path = CreateOutputDirectory("Drawing", "Lines");
var image = new Image(500, 500);
using (FileStream output = File.OpenWrite($"{path}/Dot.png"))
string path = this.CreateOutputDirectory("Drawing", "Lines");
using (Image image = new Image(500, 500))
{
image
.BackgroundColor(Color.Blue)
.DrawLines(Pens.Dot(Color.HotPink, 5), new[] {
using (FileStream output = File.OpenWrite($"{path}/Dot.png"))
{
image
.BackgroundColor(Color.Blue)
.DrawLines(Pens.Dot(Color.HotPink, 5),
new[] {
new Vector2(10, 10),
new Vector2(200, 150),
new Vector2(50, 300)
})
.Save(output);
})
.Save(output);
}
}
}
[Fact]
public void ImageShouldBeOverlayedByPathDashDot()
{
string path = CreateOutputDirectory("Drawing", "Lines");
var image = new Image(500, 500);
using (FileStream output = File.OpenWrite($"{path}/DashDot.png"))
string path = this.CreateOutputDirectory("Drawing", "Lines");
using (Image image = new Image(500, 500))
{
image
.BackgroundColor(Color.Blue)
.DrawLines(Pens.DashDot(Color.HotPink, 5), new[] {
using (FileStream output = File.OpenWrite($"{path}/DashDot.png"))
{
image
.BackgroundColor(Color.Blue)
.DrawLines(Pens.DashDot(Color.HotPink, 5),
new[] {
new Vector2(10, 10),
new Vector2(200, 150),
new Vector2(50, 300)
})
.Save(output);
})
.Save(output);
}
}
}
[Fact]
public void ImageShouldBeOverlayedByPathDashDotDot()
{
string path = CreateOutputDirectory("Drawing", "Lines");
var image = new Image(500, 500);
string path = this.CreateOutputDirectory("Drawing", "Lines");
Image image = new Image(500, 500);
using (FileStream output = File.OpenWrite($"{path}/DashDotDot.png"))
{
@ -153,12 +160,12 @@ namespace ImageSharp.Tests.Drawing
[Fact]
public void ImageShouldBeOverlayedPathWithOpacity()
{
string path = CreateOutputDirectory("Drawing", "Lines");
string path = this.CreateOutputDirectory("Drawing", "Lines");
var color = new Color(Color.HotPink.R, Color.HotPink.G, Color.HotPink.B, 150);
Color color = new Color(Color.HotPink.R, Color.HotPink.G, Color.HotPink.B, 150);
Image image = new Image(500, 500);
var image = new Image(500, 500);
using (FileStream output = File.OpenWrite($"{path}/Opacity.png"))
{
@ -173,9 +180,9 @@ namespace ImageSharp.Tests.Drawing
}
//shift background color towards forground color by the opacity amount
var mergedColor = new Color(Vector4.Lerp(Color.Blue.ToVector4(), Color.HotPink.ToVector4(), 150f/255f));
Color mergedColor = new Color(Vector4.Lerp(Color.Blue.ToVector4(), Color.HotPink.ToVector4(), 150f/255f));
using (var sourcePixels = image.Lock())
using (PixelAccessor<Color> sourcePixels = image.Lock())
{
Assert.Equal(mergedColor, sourcePixels[9, 9]);
@ -188,9 +195,9 @@ namespace ImageSharp.Tests.Drawing
[Fact]
public void ImageShouldBeOverlayedByPathOutline()
{
string path = CreateOutputDirectory("Drawing", "Lines");
string path = this.CreateOutputDirectory("Drawing", "Lines");
var image = new Image(500, 500);
Image image = new Image(500, 500);
using (FileStream output = File.OpenWrite($"{path}/Rectangle.png"))
{
@ -205,7 +212,7 @@ namespace ImageSharp.Tests.Drawing
.Save(output);
}
using (var sourcePixels = image.Lock())
using (PixelAccessor<Color> sourcePixels = image.Lock())
{
Assert.Equal(Color.HotPink, sourcePixels[8, 8]);
@ -216,6 +223,6 @@ namespace ImageSharp.Tests.Drawing
Assert.Equal(Color.Blue, sourcePixels[50, 50]);
}
}
}
}

112
tests/ImageSharp.Tests/Drawing/PolygonTests.cs

@ -18,97 +18,101 @@ namespace ImageSharp.Tests.Drawing
[Fact]
public void ImageShouldBeOverlayedByPolygonOutline()
{
string path = CreateOutputDirectory("Drawing", "Polygons");
string path = this.CreateOutputDirectory("Drawing", "Polygons");
var image = new Image(500, 500);
using (FileStream output = File.OpenWrite($"{path}/Simple.png"))
using (Image image = new Image(500, 500))
{
image
.BackgroundColor(Color.Blue)
.DrawPolygon(Color.HotPink, 5, new[] {
new Vector2(10, 10),
new Vector2(200, 150),
new Vector2(50, 300)
})
.Save(output);
}
using (FileStream output = File.OpenWrite($"{path}/Simple.png"))
{
image
.BackgroundColor(Color.Blue)
.DrawPolygon(Color.HotPink, 5,
new[] {
new Vector2(10, 10),
new Vector2(200, 150),
new Vector2(50, 300)
})
.Save(output);
}
using (var sourcePixels = image.Lock())
{
Assert.Equal(Color.HotPink, sourcePixels[9, 9]);
using (PixelAccessor<Color> sourcePixels = image.Lock())
{
Assert.Equal(Color.HotPink, sourcePixels[9, 9]);
Assert.Equal(Color.HotPink, sourcePixels[199, 149]);
Assert.Equal(Color.HotPink, sourcePixels[199, 149]);
Assert.Equal(Color.Blue, sourcePixels[50, 50]);
Assert.Equal(Color.Blue, sourcePixels[50, 50]);
Assert.Equal(Color.Blue, sourcePixels[2, 2]);
Assert.Equal(Color.Blue, sourcePixels[2, 2]);
}
}
}
[Fact]
public void ImageShouldBeOverlayedPolygonOutlineWithOpacity()
{
string path = CreateOutputDirectory("Drawing", "Polygons");
var simplePath = new[] {
string path = this.CreateOutputDirectory("Drawing", "Polygons");
Vector2[] simplePath = new[] {
new Vector2(10, 10),
new Vector2(200, 150),
new Vector2(50, 300)
};
var color = new Color(Color.HotPink.R, Color.HotPink.G, Color.HotPink.B, 150);
Color color = new Color(Color.HotPink.R, Color.HotPink.G, Color.HotPink.B, 150);
var image = new Image(500, 500);
using (FileStream output = File.OpenWrite($"{path}/Opacity.png"))
using (Image image = new Image(500, 500))
{
image
.BackgroundColor(Color.Blue)
.DrawPolygon(color, 10, simplePath)
.Save(output);
}
using (FileStream output = File.OpenWrite($"{path}/Opacity.png"))
{
image
.BackgroundColor(Color.Blue)
.DrawPolygon(color, 10, simplePath)
.Save(output);
}
//shift background color towards forground color by the opacity amount
var mergedColor = new Color(Vector4.Lerp(Color.Blue.ToVector4(), Color.HotPink.ToVector4(), 150f / 255f));
//shift background color towards forground color by the opacity amount
Color mergedColor = new Color(Vector4.Lerp(Color.Blue.ToVector4(), Color.HotPink.ToVector4(), 150f / 255f));
using (var sourcePixels = image.Lock())
{
Assert.Equal(mergedColor, sourcePixels[9, 9]);
using (PixelAccessor<Color> sourcePixels = image.Lock())
{
Assert.Equal(mergedColor, sourcePixels[9, 9]);
Assert.Equal(mergedColor, sourcePixels[199, 149]);
Assert.Equal(mergedColor, sourcePixels[199, 149]);
Assert.Equal(Color.Blue, sourcePixels[50, 50]);
Assert.Equal(Color.Blue, sourcePixels[50, 50]);
Assert.Equal(Color.Blue, sourcePixels[2, 2]);
Assert.Equal(Color.Blue, sourcePixels[2, 2]);
}
}
}
[Fact]
public void ImageShouldBeOverlayedByRectangleOutline()
{
string path = CreateOutputDirectory("Drawing", "Polygons");
string path = this.CreateOutputDirectory("Drawing", "Polygons");
var image = new Image(500, 500);
using (FileStream output = File.OpenWrite($"{path}/Rectangle.png"))
using (Image image = new Image(500, 500))
{
image
.BackgroundColor(Color.Blue)
.DrawPolygon(Color.HotPink, 10, new Rectangle(10, 10, 190, 140))
.Save(output);
}
using (FileStream output = File.OpenWrite($"{path}/Rectangle.png"))
{
image
.BackgroundColor(Color.Blue)
.DrawPolygon(Color.HotPink, 10, new Rectangle(10, 10, 190, 140))
.Save(output);
}
using (var sourcePixels = image.Lock())
{
Assert.Equal(Color.HotPink, sourcePixels[8, 8]);
using (PixelAccessor<Color> sourcePixels = image.Lock())
{
Assert.Equal(Color.HotPink, sourcePixels[8, 8]);
Assert.Equal(Color.HotPink, sourcePixels[198, 10]);
Assert.Equal(Color.HotPink, sourcePixels[198, 10]);
Assert.Equal(Color.HotPink, sourcePixels[10, 50]);
Assert.Equal(Color.HotPink, sourcePixels[10, 50]);
Assert.Equal(Color.Blue, sourcePixels[50, 50]);
Assert.Equal(Color.Blue, sourcePixels[50, 50]);
Assert.Equal(Color.Blue, sourcePixels[2, 2]);
Assert.Equal(Color.Blue, sourcePixels[2, 2]);
}
}
}
}

32
tests/ImageSharp.Tests/Drawing/RecolorImageTest.cs

@ -16,18 +16,19 @@ namespace ImageSharp.Tests
[Fact]
public void ImageShouldRecolorYellowToHotPink()
{
string path = CreateOutputDirectory("Drawing", "RecolorImage");
string path = this.CreateOutputDirectory("Drawing", "RecolorImage");
var brush = new RecolorBrush(Color.Yellow, Color.HotPink, 0.2f);
RecolorBrush brush = new RecolorBrush(Color.Yellow, Color.HotPink, 0.2f);
foreach (TestFile file in Files)
{
Image image = file.CreateImage();
using (FileStream output = File.OpenWrite($"{path}/{file.FileName}"))
using (Image image = file.CreateImage())
{
image.Fill(brush)
.Save(output);
using (FileStream output = File.OpenWrite($"{path}/{file.FileName}"))
{
image.Fill(brush)
.Save(output);
}
}
}
}
@ -35,19 +36,20 @@ namespace ImageSharp.Tests
[Fact]
public void ImageShouldRecolorYellowToHotPinkInARectangle()
{
string path = CreateOutputDirectory("Drawing", "RecolorImage");
string path = this.CreateOutputDirectory("Drawing", "RecolorImage");
var brush = new RecolorBrush(Color.Yellow, Color.HotPink, 0.2f);
RecolorBrush brush = new RecolorBrush(Color.Yellow, Color.HotPink, 0.2f);
foreach (TestFile file in Files)
{
Image image = file.CreateImage();
using (FileStream output = File.OpenWrite($"{path}/Shaped_{file.FileName}"))
using (Image image = file.CreateImage())
{
var imageHeight = image.Height;
image.Fill(brush, new Rectangle(0, imageHeight/2 - imageHeight/4, image.Width, imageHeight/2))
.Save(output);
using (FileStream output = File.OpenWrite($"{path}/Shaped_{file.FileName}"))
{
int imageHeight = image.Height;
image.Fill(brush, new Rectangle(0, imageHeight/2 - imageHeight/4, image.Width, imageHeight/2))
.Save(output);
}
}
}
}

102
tests/ImageSharp.Tests/Drawing/SolidBezierTests.cs

@ -5,11 +5,8 @@
namespace ImageSharp.Tests.Drawing
{
using Drawing;
using ImageSharp.Drawing;
using ImageSharp.Drawing.Shapes;
using System;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Numerics;
using Xunit;
@ -19,83 +16,84 @@ namespace ImageSharp.Tests.Drawing
[Fact]
public void ImageShouldBeOverlayedByFilledPolygon()
{
string path = CreateOutputDirectory("Drawing", "FilledBezier");
var simplePath = new[] {
string path = this.CreateOutputDirectory("Drawing", "FilledBezier");
Vector2[] simplePath = new[] {
new Vector2(10, 400),
new Vector2(30, 10),
new Vector2(240, 30),
new Vector2(300, 400)
};
var image = new Image(500, 500);
using (FileStream output = File.OpenWrite($"{path}/Simple.png"))
using (Image image = new Image(500, 500))
{
image
.BackgroundColor(Color.Blue)
.Fill(Color.HotPink,new BezierPolygon(simplePath))
.Save(output);
}
using (FileStream output = File.OpenWrite($"{path}/Simple.png"))
{
image
.BackgroundColor(Color.Blue)
.Fill(Color.HotPink,new BezierPolygon(simplePath))
.Save(output);
}
using (var sourcePixels = image.Lock())
{
//top of curve
Assert.Equal(Color.HotPink, sourcePixels[138, 116]);
using (PixelAccessor<Color> sourcePixels = image.Lock())
{
//top of curve
Assert.Equal(Color.HotPink, sourcePixels[138, 116]);
//start points
Assert.Equal(Color.HotPink, sourcePixels[10, 400]);
Assert.Equal(Color.HotPink, sourcePixels[300, 400]);
//start points
Assert.Equal(Color.HotPink, sourcePixels[10, 400]);
Assert.Equal(Color.HotPink, sourcePixels[300, 400]);
//curve points should not be never be set
Assert.Equal(Color.Blue, sourcePixels[30, 10]);
Assert.Equal(Color.Blue, sourcePixels[240, 30]);
//curve points should not be never be set
Assert.Equal(Color.Blue, sourcePixels[30, 10]);
Assert.Equal(Color.Blue, sourcePixels[240, 30]);
// inside shape should not be empty
Assert.Equal(Color.HotPink, sourcePixels[200, 250]);
// inside shape should not be empty
Assert.Equal(Color.HotPink, sourcePixels[200, 250]);
}
}
}
[Fact]
public void ImageShouldBeOverlayedByFilledPolygonOpacity()
{
string path = CreateOutputDirectory("Drawing", "FilledBezier");
var simplePath = new[] {
string path = this.CreateOutputDirectory("Drawing", "FilledBezier");
Vector2[] simplePath = new[] {
new Vector2(10, 400),
new Vector2(30, 10),
new Vector2(240, 30),
new Vector2(300, 400)
};
var color = new Color(Color.HotPink.R, Color.HotPink.G, Color.HotPink.B, 150);
Color color = new Color(Color.HotPink.R, Color.HotPink.G, Color.HotPink.B, 150);
var image = new Image(500, 500);
using (FileStream output = File.OpenWrite($"{path}/Opacity.png"))
using (Image image = new Image(500, 500))
{
image
.BackgroundColor(Color.Blue)
.Fill(color, new BezierPolygon(simplePath))
.Save(output);
}
using (FileStream output = File.OpenWrite($"{path}/Opacity.png"))
{
image
.BackgroundColor(Color.Blue)
.Fill(color, new BezierPolygon(simplePath))
.Save(output);
}
//shift background color towards forground color by the opacity amount
var mergedColor = new Color(Vector4.Lerp(Color.Blue.ToVector4(), Color.HotPink.ToVector4(), 150f / 255f));
//shift background color towards forground color by the opacity amount
Color mergedColor = new Color(Vector4.Lerp(Color.Blue.ToVector4(), Color.HotPink.ToVector4(), 150f / 255f));
using (var sourcePixels = image.Lock())
{
//top of curve
Assert.Equal(mergedColor, sourcePixels[138, 116]);
using (PixelAccessor<Color> sourcePixels = image.Lock())
{
//top of curve
Assert.Equal(mergedColor, sourcePixels[138, 116]);
//start points
Assert.Equal(mergedColor, sourcePixels[10, 400]);
Assert.Equal(mergedColor, sourcePixels[300, 400]);
//start points
Assert.Equal(mergedColor, sourcePixels[10, 400]);
Assert.Equal(mergedColor, sourcePixels[300, 400]);
//curve points should not be never be set
Assert.Equal(Color.Blue, sourcePixels[30, 10]);
Assert.Equal(Color.Blue, sourcePixels[240, 30]);
//curve points should not be never be set
Assert.Equal(Color.Blue, sourcePixels[30, 10]);
Assert.Equal(Color.Blue, sourcePixels[240, 30]);
// inside shape should not be empty
Assert.Equal(mergedColor, sourcePixels[200, 250]);
// inside shape should not be empty
Assert.Equal(mergedColor, sourcePixels[200, 250]);
}
}
}
}
}

138
tests/ImageSharp.Tests/Drawing/SolidComplexPolygonTests.cs

@ -5,12 +5,9 @@
namespace ImageSharp.Tests.Drawing
{
using System;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using Xunit;
using Drawing;
using ImageSharp.Drawing;
using System.Numerics;
using ImageSharp.Drawing.Shapes;
@ -19,41 +16,42 @@ namespace ImageSharp.Tests.Drawing
[Fact]
public void ImageShouldBeOverlayedByPolygonOutline()
{
string path = CreateOutputDirectory("Drawing", "ComplexPolygon");
var simplePath = new LinearPolygon(
string path = this.CreateOutputDirectory("Drawing", "ComplexPolygon");
LinearPolygon simplePath = new LinearPolygon(
new Vector2(10, 10),
new Vector2(200, 150),
new Vector2(50, 300));
var hole1 = new LinearPolygon(
LinearPolygon hole1 = new LinearPolygon(
new Vector2(37, 85),
new Vector2(93, 85),
new Vector2(65, 137));
var image = new Image(500, 500);
using (FileStream output = File.OpenWrite($"{path}/Simple.png"))
using (Image image = new Image(500, 500))
{
image
.BackgroundColor(Color.Blue)
.Fill(Color.HotPink, new ComplexPolygon(simplePath, hole1))
.Save(output);
}
using (FileStream output = File.OpenWrite($"{path}/Simple.png"))
{
image
.BackgroundColor(Color.Blue)
.Fill(Color.HotPink, new ComplexPolygon(simplePath, hole1))
.Save(output);
}
using (var sourcePixels = image.Lock())
{
Assert.Equal(Color.HotPink, sourcePixels[11, 11]);
using (PixelAccessor<Color> sourcePixels = image.Lock())
{
Assert.Equal(Color.HotPink, sourcePixels[11, 11]);
Assert.Equal(Color.HotPink, sourcePixels[200, 150]);
Assert.Equal(Color.HotPink, sourcePixels[200, 150]);
Assert.Equal(Color.HotPink, sourcePixels[50, 50]);
Assert.Equal(Color.HotPink, sourcePixels[50, 50]);
Assert.Equal(Color.HotPink, sourcePixels[35, 100]);
Assert.Equal(Color.HotPink, sourcePixels[35, 100]);
Assert.Equal(Color.Blue, sourcePixels[2, 2]);
Assert.Equal(Color.Blue, sourcePixels[2, 2]);
//inside hole
Assert.Equal(Color.Blue, sourcePixels[57, 99]);
//inside hole
Assert.Equal(Color.Blue, sourcePixels[57, 99]);
}
}
}
@ -61,87 +59,89 @@ namespace ImageSharp.Tests.Drawing
[Fact]
public void ImageShouldBeOverlayedPolygonOutlineWithOverlap()
{
string path = CreateOutputDirectory("Drawing", "ComplexPolygon");
var simplePath = new LinearPolygon(
string path = this.CreateOutputDirectory("Drawing", "ComplexPolygon");
LinearPolygon simplePath = new LinearPolygon(
new Vector2(10, 10),
new Vector2(200, 150),
new Vector2(50, 300));
var hole1 = new LinearPolygon(
LinearPolygon hole1 = new LinearPolygon(
new Vector2(37, 85),
new Vector2(130, 40),
new Vector2(65, 137));
var image = new Image(500, 500);
using (FileStream output = File.OpenWrite($"{path}/SimpleOverlapping.png"))
using (Image image = new Image(500, 500))
{
image
.BackgroundColor(Color.Blue)
.Fill(Color.HotPink, new ComplexPolygon(simplePath, hole1))
.Save(output);
}
using (var sourcePixels = image.Lock())
{
Assert.Equal(Color.HotPink, sourcePixels[11, 11]);
using (FileStream output = File.OpenWrite($"{path}/SimpleOverlapping.png"))
{
image
.BackgroundColor(Color.Blue)
.Fill(Color.HotPink, new ComplexPolygon(simplePath, hole1))
.Save(output);
}
using (PixelAccessor<Color> sourcePixels = image.Lock())
{
Assert.Equal(Color.HotPink, sourcePixels[11, 11]);
Assert.Equal(Color.HotPink, sourcePixels[200, 150]);
Assert.Equal(Color.HotPink, sourcePixels[200, 150]);
Assert.Equal(Color.HotPink, sourcePixels[50, 50]);
Assert.Equal(Color.HotPink, sourcePixels[50, 50]);
Assert.Equal(Color.HotPink, sourcePixels[35, 100]);
Assert.Equal(Color.HotPink, sourcePixels[35, 100]);
Assert.Equal(Color.Blue, sourcePixels[2, 2]);
Assert.Equal(Color.Blue, sourcePixels[2, 2]);
//inside hole
Assert.Equal(Color.Blue, sourcePixels[57, 99]);
//inside hole
Assert.Equal(Color.Blue, sourcePixels[57, 99]);
}
}
}
[Fact]
public void ImageShouldBeOverlayedPolygonOutlineWithOpacity()
{
string path = CreateOutputDirectory("Drawing", "ComplexPolygon");
var simplePath = new LinearPolygon(
string path = this.CreateOutputDirectory("Drawing", "ComplexPolygon");
LinearPolygon simplePath = new LinearPolygon(
new Vector2(10, 10),
new Vector2(200, 150),
new Vector2(50, 300));
var hole1 = new LinearPolygon(
LinearPolygon hole1 = new LinearPolygon(
new Vector2(37, 85),
new Vector2(93, 85),
new Vector2(65, 137));
var color = new Color(Color.HotPink.R, Color.HotPink.G, Color.HotPink.B, 150);
var image = new Image(500, 500);
Color color = new Color(Color.HotPink.R, Color.HotPink.G, Color.HotPink.B, 150);
using (FileStream output = File.OpenWrite($"{path}/Opacity.png"))
using (Image image = new Image(500, 500))
{
image
.BackgroundColor(Color.Blue)
.Fill(color, new ComplexPolygon(simplePath, hole1))
.Save(output);
}
using (FileStream output = File.OpenWrite($"{path}/Opacity.png"))
{
image
.BackgroundColor(Color.Blue)
.Fill(color, new ComplexPolygon(simplePath, hole1))
.Save(output);
}
//shift background color towards forground color by the opacity amount
var mergedColor = new Color(Vector4.Lerp(Color.Blue.ToVector4(), Color.HotPink.ToVector4(), 150f / 255f));
//shift background color towards forground color by the opacity amount
Color mergedColor = new Color(Vector4.Lerp(Color.Blue.ToVector4(), Color.HotPink.ToVector4(), 150f / 255f));
using (var sourcePixels = image.Lock())
{
Assert.Equal(mergedColor, sourcePixels[11, 11]);
using (PixelAccessor<Color> sourcePixels = image.Lock())
{
Assert.Equal(mergedColor, sourcePixels[11, 11]);
Assert.Equal(mergedColor, sourcePixels[200, 150]);
Assert.Equal(mergedColor, sourcePixels[200, 150]);
Assert.Equal(mergedColor, sourcePixels[50, 50]);
Assert.Equal(mergedColor, sourcePixels[50, 50]);
Assert.Equal(mergedColor, sourcePixels[35, 100]);
Assert.Equal(mergedColor, sourcePixels[35, 100]);
Assert.Equal(Color.Blue, sourcePixels[2, 2]);
Assert.Equal(Color.Blue, sourcePixels[2, 2]);
//inside hole
Assert.Equal(Color.Blue, sourcePixels[57, 99]);
//inside hole
Assert.Equal(Color.Blue, sourcePixels[57, 99]);
}
}
}
}
}
}

156
tests/ImageSharp.Tests/Drawing/SolidPolygonTests.cs

@ -5,10 +5,8 @@
namespace ImageSharp.Tests.Drawing
{
using Drawing;
using ImageSharp.Drawing;
using System;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Numerics;
using Xunit;
@ -19,155 +17,153 @@ namespace ImageSharp.Tests.Drawing
[Fact]
public void ImageShouldBeOverlayedByFilledPolygon()
{
string path = CreateOutputDirectory("Drawing", "FilledPolygons");
var simplePath = new[] {
string path = this.CreateOutputDirectory("Drawing", "FilledPolygons");
Vector2[] simplePath = new[] {
new Vector2(10, 10),
new Vector2(200, 150),
new Vector2(50, 300)
};
var image = new Image(500, 500);
using (FileStream output = File.OpenWrite($"{path}/Simple.png"))
using (Image image = new Image(500, 500))
{
image
.BackgroundColor(Color.Blue)
.FillPolygon(Color.HotPink, simplePath, new GraphicsOptions(true))
.Save(output);
}
using (FileStream output = File.OpenWrite($"{path}/Simple.png"))
{
image
.BackgroundColor(Color.Blue)
.FillPolygon(Color.HotPink, simplePath, new GraphicsOptions(true))
.Save(output);
}
using (var sourcePixels = image.Lock())
{
Assert.Equal(Color.HotPink, sourcePixels[11, 11]);
using (PixelAccessor<Color> sourcePixels = image.Lock())
{
Assert.Equal(Color.HotPink, sourcePixels[11, 11]);
Assert.Equal(Color.HotPink, sourcePixels[200, 150]);
Assert.Equal(Color.HotPink, sourcePixels[200, 150]);
Assert.Equal(Color.HotPink, sourcePixels[50, 50]);
Assert.Equal(Color.HotPink, sourcePixels[50, 50]);
Assert.Equal(Color.Blue, sourcePixels[2, 2]);
Assert.Equal(Color.Blue, sourcePixels[2, 2]);
}
}
}
[Fact]
public void ImageShouldBeOverlayedByFilledPolygon_NoAntialias()
public void ImageShouldBeOverlayedByFilledPolygonNoAntialias()
{
string path = CreateOutputDirectory("Drawing", "FilledPolygons");
var simplePath = new[] {
string path = this.CreateOutputDirectory("Drawing", "FilledPolygons");
Vector2[] simplePath = new[] {
new Vector2(10, 10),
new Vector2(200, 150),
new Vector2(50, 300)
};
var image = new Image(500, 500);
using (Image image = new Image(500, 500))
using (FileStream output = File.OpenWrite($"{path}/Simple_NoAntialias.png"))
{
image
.BackgroundColor(Color.Blue)
.FillPolygon(Color.HotPink, simplePath, new GraphicsOptions(false))
.Save(output);
}
using (var sourcePixels = image.Lock())
{
Assert.Equal(Color.HotPink, sourcePixels[11, 11]);
using (PixelAccessor<Color> sourcePixels = image.Lock())
{
Assert.Equal(Color.HotPink, sourcePixels[11, 11]);
Assert.Equal(Color.HotPink, sourcePixels[200, 150]);
Assert.Equal(Color.HotPink, sourcePixels[200, 150]);
Assert.Equal(Color.HotPink, sourcePixels[50, 50]);
Assert.Equal(Color.HotPink, sourcePixels[50, 50]);
Assert.Equal(Color.Blue, sourcePixels[2, 2]);
Assert.Equal(Color.Blue, sourcePixels[2, 2]);
}
}
}
[Fact]
public void ImageShouldBeOverlayedByFilledPolygon_Image()
public void ImageShouldBeOverlayedByFilledPolygonImage()
{
string path = CreateOutputDirectory("Drawing", "FilledPolygons");
var simplePath = new[] {
string path = this.CreateOutputDirectory("Drawing", "FilledPolygons");
Vector2[] simplePath = new[] {
new Vector2(10, 10),
new Vector2(200, 150),
new Vector2(50, 300)
};
var brush = new ImageBrush(TestFile.Create(TestImages.Bmp.Car).CreateImage());
var image = new Image(500, 500);
using (Image brushImage = TestFile.Create(TestImages.Bmp.Car).CreateImage())
using (Image image = new Image(500, 500))
using (FileStream output = File.OpenWrite($"{path}/Image.png"))
{
ImageBrush brush = new ImageBrush(brushImage);
image
.BackgroundColor(Color.Blue)
.FillPolygon(brush, simplePath)
.Save(output);
.BackgroundColor(Color.Blue)
.FillPolygon(brush, simplePath)
.Save(output);
}
}
[Fact]
public void ImageShouldBeOverlayedByFilledPolygonOpacity()
{
string path = CreateOutputDirectory("Drawing", "FilledPolygons");
var simplePath = new[] {
string path = this.CreateOutputDirectory("Drawing", "FilledPolygons");
Vector2[] simplePath = new[] {
new Vector2(10, 10),
new Vector2(200, 150),
new Vector2(50, 300)
};
var color = new Color(Color.HotPink.R, Color.HotPink.G, Color.HotPink.B, 150);
var image = new Image(500, 500);
Color color = new Color(Color.HotPink.R, Color.HotPink.G, Color.HotPink.B, 150);
using (FileStream output = File.OpenWrite($"{path}/Opacity.png"))
using (Image image = new Image(500, 500))
{
image
.BackgroundColor(Color.Blue)
.FillPolygon(color, simplePath)
.Save(output);
}
using (FileStream output = File.OpenWrite($"{path}/Opacity.png"))
{
image
.BackgroundColor(Color.Blue)
.FillPolygon(color, simplePath)
.Save(output);
}
//shift background color towards forground color by the opacity amount
var mergedColor = new Color(Vector4.Lerp(Color.Blue.ToVector4(), Color.HotPink.ToVector4(), 150f / 255f));
//shift background color towards forground color by the opacity amount
Color mergedColor = new Color(Vector4.Lerp(Color.Blue.ToVector4(), Color.HotPink.ToVector4(), 150f / 255f));
using (var sourcePixels = image.Lock())
{
Assert.Equal(mergedColor, sourcePixels[11, 11]);
using (PixelAccessor<Color> sourcePixels = image.Lock())
{
Assert.Equal(mergedColor, sourcePixels[11, 11]);
Assert.Equal(mergedColor, sourcePixels[200, 150]);
Assert.Equal(mergedColor, sourcePixels[200, 150]);
Assert.Equal(mergedColor, sourcePixels[50, 50]);
Assert.Equal(mergedColor, sourcePixels[50, 50]);
Assert.Equal(Color.Blue, sourcePixels[2, 2]);
Assert.Equal(Color.Blue, sourcePixels[2, 2]);
}
}
}
[Fact]
public void ImageShouldBeOverlayedByFilledRectangle()
{
string path = CreateOutputDirectory("Drawing", "FilledPolygons");
var simplePath = new[] {
new Vector2(10, 10),
new Vector2(200, 10),
new Vector2(200, 150),
new Vector2(10, 150)
};
var image = new Image(500, 500);
using (FileStream output = File.OpenWrite($"{path}/Rectangle.png"))
string path = this.CreateOutputDirectory("Drawing", "FilledPolygons");
using (Image image = new Image(500, 500))
{
image
.BackgroundColor(Color.Blue)
.Fill(Color.HotPink, new ImageSharp.Drawing.Shapes.RectangularPolygon(new Rectangle(10,10, 190, 140)))
.Save(output);
}
using (FileStream output = File.OpenWrite($"{path}/Rectangle.png"))
{
image
.BackgroundColor(Color.Blue)
.Fill(Color.HotPink, new ImageSharp.Drawing.Shapes.RectangularPolygon(new Rectangle(10, 10, 190, 140)))
.Save(output);
}
using (var sourcePixels = image.Lock())
{
Assert.Equal(Color.HotPink, sourcePixels[11, 11]);
using (PixelAccessor<Color> sourcePixels = image.Lock())
{
Assert.Equal(Color.HotPink, sourcePixels[11, 11]);
Assert.Equal(Color.HotPink, sourcePixels[198, 10]);
Assert.Equal(Color.HotPink, sourcePixels[198, 10]);
Assert.Equal(Color.HotPink, sourcePixels[10, 50]);
Assert.Equal(Color.HotPink, sourcePixels[10, 50]);
Assert.Equal(Color.HotPink, sourcePixels[50, 50]);
Assert.Equal(Color.HotPink, sourcePixels[50, 50]);
Assert.Equal(Color.Blue, sourcePixels[2, 2]);
Assert.Equal(Color.Blue, sourcePixels[2, 2]);
}
}
}
}

15
tests/ImageSharp.Tests/Formats/Bmp/BitmapTests.cs

@ -9,8 +9,6 @@ namespace ImageSharp.Tests
{
using System.IO;
using Formats;
using Xunit;
public class BitmapTests : FileTestBase
@ -23,19 +21,20 @@ namespace ImageSharp.Tests
};
[Theory]
[MemberData("BitsPerPixel")]
[MemberData(nameof(BitsPerPixel))]
public void BitmapCanEncodeDifferentBitRates(BmpBitsPerPixel bitsPerPixel)
{
string path = CreateOutputDirectory("Bmp");
string path = this.CreateOutputDirectory("Bmp");
foreach (TestFile file in Files)
{
string filename = file.GetFileNameWithoutExtension(bitsPerPixel);
Image image = file.CreateImage();
using (FileStream output = File.OpenWrite($"{path}/{filename}.bmp"))
using (Image image = file.CreateImage())
{
image.Save(output, new BmpEncoder { BitsPerPixel = bitsPerPixel });
using (FileStream output = File.OpenWrite($"{path}/{filename}.bmp"))
{
image.Save(output, new BmpEncoder { BitsPerPixel = bitsPerPixel });
}
}
}
}

101
tests/ImageSharp.Tests/Formats/GeneralFormatTests.cs

@ -16,17 +16,18 @@ namespace ImageSharp.Tests
[Fact]
public void ResolutionShouldChange()
{
string path = CreateOutputDirectory("Resolution");
string path = this.CreateOutputDirectory("Resolution");
foreach (TestFile file in Files)
{
Image image = file.CreateImage();
using (FileStream output = File.OpenWrite($"{path}/{file.FileName}"))
using (Image image = file.CreateImage())
{
image.VerticalResolution = 150;
image.HorizontalResolution = 150;
image.Save(output);
using (FileStream output = File.OpenWrite($"{path}/{file.FileName}"))
{
image.VerticalResolution = 150;
image.HorizontalResolution = 150;
image.Save(output);
}
}
}
}
@ -34,45 +35,31 @@ namespace ImageSharp.Tests
[Fact]
public void ImageCanEncodeToString()
{
string path = CreateOutputDirectory("ToString");
string path = this.CreateOutputDirectory("ToString");
foreach (TestFile file in Files)
{
Image image = file.CreateImage();
string filename = path + "/" + file.FileNameWithoutExtension + ".txt";
File.WriteAllText(filename, image.ToBase64String());
using (Image image = file.CreateImage())
{
string filename = path + "/" + file.FileNameWithoutExtension + ".txt";
File.WriteAllText(filename, image.ToBase64String());
}
}
}
[Fact]
public void DecodeThenEncodeImageFromStreamShouldSucceed()
{
string path = CreateOutputDirectory("Encode");
string path = this.CreateOutputDirectory("Encode");
foreach (TestFile file in Files)
{
Image image = file.CreateImage();
//Image<Bgr565> image = file.CreateImage().To<Bgr565>();
//Image<Bgra4444> image = file.CreateImage().To<Bgra4444>();
//Image<Bgra5551> image = file.CreateImage().To<Bgra5551>();
//Image<Byte4> image = file.CreateImage().To<Byte4>();
//Image<HalfSingle> image = file.CreateImage().To<HalfSingle>();
//Image<HalfVector2> image = file.CreateImage().To<HalfVector2>();
//Image<HalfVector4> image = file.CreateImage().To<HalfVector4>();
//Image<Rg32> image = file.CreateImage().To<Rg32>();
//Image<Rgba1010102> image = file.CreateImage().To<Rgba1010102>();
//Image<Rgba64> image = file.CreateImage().To<Rgba64>();
//Image<NormalizedByte2> image = file.CreateImage().To<NormalizedByte2>();
//Image<NormalizedByte4> image = file.CreateImage().To<NormalizedByte4>();
//Image<NormalizedShort2> image = file.CreateImage().To<NormalizedShort2>();
//Image<NormalizedShort4> image = file.CreateImage().To<NormalizedShort4>();
//Image<Short2> image = file.CreateImage().To<Short2>();
//Image<Short4> image = file.CreateImage().To<Short4>();
using (FileStream output = File.OpenWrite($"{path}/{file.FileName}"))
using (Image image = file.CreateImage())
{
image.Save(output);
using (FileStream output = File.OpenWrite($"{path}/{file.FileName}"))
{
image.Save(output);
}
}
}
}
@ -80,35 +67,35 @@ namespace ImageSharp.Tests
[Fact]
public void QuantizeImageShouldPreserveMaximumColorPrecision()
{
string path = CreateOutputDirectory("Quantize");
string path = this.CreateOutputDirectory("Quantize");
foreach (TestFile file in Files)
{
Image image = file.CreateImage();
// Copy the original pixels to save decoding time.
Color[] pixels = new Color[image.Width * image.Height];
Array.Copy(image.Pixels, pixels, image.Pixels.Length);
using (FileStream output = File.OpenWrite($"{path}/Octree-{file.FileName}"))
using (Image image = file.CreateImage())
{
image.Quantize(Quantization.Octree)
.Save(output, image.CurrentImageFormat);
Color[] pixels = new Color[image.Width * image.Height];
Array.Copy(image.Pixels, pixels, image.Width * image.Height);
}
using (FileStream output = File.OpenWrite($"{path}/Octree-{file.FileName}"))
{
image.Quantize(Quantization.Octree)
.Save(output, image.CurrentImageFormat);
image.SetPixels(image.Width, image.Height, pixels);
using (FileStream output = File.OpenWrite($"{path}/Wu-{file.FileName}"))
{
image.Quantize(Quantization.Wu)
.Save(output, image.CurrentImageFormat);
}
}
image.SetPixels(image.Width, image.Height, pixels);
using (FileStream output = File.OpenWrite($"{path}/Palette-{file.FileName}"))
{
image.Quantize(Quantization.Palette)
.Save(output, image.CurrentImageFormat);
image.SetPixels(image.Width, image.Height, pixels);
using (FileStream output = File.OpenWrite($"{path}/Wu-{file.FileName}"))
{
image.Quantize(Quantization.Wu)
.Save(output, image.CurrentImageFormat);
}
image.SetPixels(image.Width, image.Height, pixels);
using (FileStream output = File.OpenWrite($"{path}/Palette-{file.FileName}"))
{
image.Quantize(Quantization.Palette)
.Save(output, image.CurrentImageFormat);
}
}
}
}
@ -116,7 +103,7 @@ namespace ImageSharp.Tests
[Fact]
public void ImageCanConvertFormat()
{
string path = CreateOutputDirectory("Format");
string path = this.CreateOutputDirectory("Format");
foreach (TestFile file in Files)
{
@ -147,7 +134,7 @@ namespace ImageSharp.Tests
[Fact]
public void ImageShouldPreservePixelByteOrderWhenSerialized()
{
string path = CreateOutputDirectory("Serialized");
string path = this.CreateOutputDirectory("Serialized");
foreach (TestFile file in Files)
{

16
tests/ImageSharp.Tests/Formats/Jpg/BadEofJpegTests.cs

@ -31,9 +31,11 @@ namespace ImageSharp.Tests
public void LoadBaselineImage<TColor>(TestImageProvider<TColor> provider)
where TColor : struct, IPackedPixel, IEquatable<TColor>
{
var image = provider.GetImage();
Assert.NotNull(image);
provider.Utility.SaveTestOutputFile(image, "bmp");
using (Image<TColor> image = provider.GetImage())
{
Assert.NotNull(image);
provider.Utility.SaveTestOutputFile(image, "bmp");
}
}
[Theory] // TODO: #18
@ -41,9 +43,11 @@ namespace ImageSharp.Tests
public void LoadProgressiveImage<TColor>(TestImageProvider<TColor> provider)
where TColor : struct, IPackedPixel, IEquatable<TColor>
{
var image = provider.GetImage();
Assert.NotNull(image);
provider.Utility.SaveTestOutputFile(image, "bmp");
using (Image<TColor> image = provider.GetImage())
{
Assert.NotNull(image);
provider.Utility.SaveTestOutputFile(image, "bmp");
}
}
}
}

61
tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs

@ -29,19 +29,21 @@ namespace ImageSharp.Tests
public void OpenBaselineJpeg_SaveBmp<TColor>(TestImageProvider<TColor> provider)
where TColor : struct, IPackedPixel, IEquatable<TColor>
{
Image<TColor> image = provider.GetImage();
provider.Utility.SaveTestOutputFile(image, "bmp");
using (Image<TColor> image = provider.GetImage())
{
provider.Utility.SaveTestOutputFile(image, "bmp");
}
}
[Theory]
[WithFileCollection(nameof(ProgressiveTestJpegs), PixelTypes.Color | PixelTypes.StandardImageClass | PixelTypes.Argb)]
public void OpenProgressiveJpeg_SaveBmp<TColor>(TestImageProvider<TColor> provider)
where TColor : struct, IPackedPixel, IEquatable<TColor>
{
Image<TColor> image = provider.GetImage();
provider.Utility.SaveTestOutputFile(image, "bmp");
using (Image<TColor> image = provider.GetImage())
{
provider.Utility.SaveTestOutputFile(image, "bmp");
}
}
[Theory]
@ -53,17 +55,19 @@ namespace ImageSharp.Tests
public void DecodeGenerated_SaveBmp<TColor>(
TestImageProvider<TColor> provider,
JpegSubsample subsample,
int quality)
int quality)
where TColor : struct, IPackedPixel, IEquatable<TColor>
{
Image<TColor> image = provider.GetImage();
JpegEncoder encoder = new JpegEncoder() { Subsample = subsample, Quality = quality };
byte[] data = new byte[65536];
using (MemoryStream ms = new MemoryStream(data))
byte[] data;
using (Image<TColor> image = provider.GetImage())
{
image.Save(ms, encoder);
JpegEncoder encoder = new JpegEncoder() { Subsample = subsample, Quality = quality };
data = new byte[65536];
using (MemoryStream ms = new MemoryStream(data))
{
image.Save(ms, encoder);
}
}
// TODO: Automatic image comparers could help here a lot :P
@ -75,23 +79,24 @@ namespace ImageSharp.Tests
[Theory]
[WithSolidFilledImages(42, 88, 255, 0, 0, PixelTypes.StandardImageClass)]
public void DecodeGenerated_MetadataOnly<TColor>(
TestImageProvider<TColor> provider)
TestImageProvider<TColor> provider)
where TColor : struct, IPackedPixel, IEquatable<TColor>
{
Image<TColor> image = provider.GetImage();
using (MemoryStream ms = new MemoryStream())
using (Image<TColor> image = provider.GetImage())
{
image.Save(ms, new JpegEncoder());
ms.Seek(0, SeekOrigin.Begin);
Image<TColor> mirror = provider.Factory.CreateImage(1, 1);
using (JpegDecoderCore decoder = new JpegDecoderCore())
using (MemoryStream ms = new MemoryStream())
{
decoder.Decode(mirror, ms, true);
Assert.Equal(decoder.ImageWidth, image.Width);
Assert.Equal(decoder.ImageHeight, image.Height);
image.Save(ms, new JpegEncoder());
ms.Seek(0, SeekOrigin.Begin);
Image<TColor> mirror = provider.Factory.CreateImage(1, 1);
using (JpegDecoderCore decoder = new JpegDecoderCore())
{
decoder.Decode(mirror, ms, true);
Assert.Equal(decoder.ImageWidth, image.Width);
Assert.Equal(decoder.ImageHeight, image.Height);
}
}
}
}

44
tests/ImageSharp.Tests/Formats/Jpg/JpegEncoderTests.cs

@ -34,19 +34,16 @@ namespace ImageSharp.Tests
public void LoadResizeSave<TColor>(TestImageProvider<TColor> provider, int quality, JpegSubsample subsample)
where TColor : struct, IPackedPixel, IEquatable<TColor>
{
Image<TColor> image = provider.GetImage()
.Resize(new ResizeOptions
{
Size = new Size(150, 100),
Mode = ResizeMode.Max
});
image.Quality = quality;
image.ExifProfile = null; // Reduce the size of the file
JpegEncoder encoder = new JpegEncoder { Subsample = subsample, Quality = quality };
using (Image<TColor> image = provider.GetImage().Resize(new ResizeOptions { Size = new Size(150, 100), Mode = ResizeMode.Max }))
{
image.Quality = quality;
image.ExifProfile = null; // Reduce the size of the file
JpegEncoder encoder = new JpegEncoder { Subsample = subsample, Quality = quality };
provider.Utility.TestName += $"{subsample}_Q{quality}";
provider.Utility.SaveTestOutputFile(image, "png");
provider.Utility.SaveTestOutputFile(image, "jpg", encoder);
provider.Utility.TestName += $"{subsample}_Q{quality}";
provider.Utility.SaveTestOutputFile(image, "png");
provider.Utility.SaveTestOutputFile(image, "jpg", encoder);
}
}
[Theory]
@ -55,20 +52,21 @@ namespace ImageSharp.Tests
public void OpenBmp_SaveJpeg<TColor>(TestImageProvider<TColor> provider, JpegSubsample subSample, int quality)
where TColor : struct, IPackedPixel, IEquatable<TColor>
{
Image<TColor> image = provider.GetImage();
ImagingTestCaseUtility utility = provider.Utility;
utility.TestName += "_" + subSample + "_Q" + quality;
using (var outputStream = File.OpenWrite(utility.GetTestOutputFileName("jpg")))
using (Image<TColor> image = provider.GetImage())
{
var encoder = new JpegEncoder()
ImagingTestCaseUtility utility = provider.Utility;
utility.TestName += "_" + subSample + "_Q" + quality;
using (FileStream outputStream = File.OpenWrite(utility.GetTestOutputFileName("jpg")))
{
Subsample = subSample,
Quality = quality
};
JpegEncoder encoder = new JpegEncoder()
{
Subsample = subSample,
Quality = quality
};
image.Save(outputStream, encoder);
image.Save(outputStream, encoder);
}
}
}
}

85
tests/ImageSharp.Tests/Formats/Jpg/JpegUtilsTests.cs

@ -19,7 +19,6 @@ namespace ImageSharp.Tests
where TColor : struct, IPackedPixel, IEquatable<TColor>
{
Image<TColor> image = factory.CreateImage(10, 10);
using (PixelAccessor<TColor> pixels = image.Lock())
{
for (int i = 0; i < 10; i++)
@ -35,6 +34,7 @@ namespace ImageSharp.Tests
}
}
}
return image;
}
@ -43,24 +43,21 @@ namespace ImageSharp.Tests
public void CopyStretchedRGBTo_FromOrigo<TColor>(TestImageProvider<TColor> provider)
where TColor : struct, IPackedPixel, IEquatable<TColor>
{
Image<TColor> src = provider.GetImage();
PixelArea<TColor> area = new PixelArea<TColor>(8, 8, ComponentOrder.Xyz);
Image<TColor> dest = provider.Factory.CreateImage(8, 8);
using (var s = src.Lock())
using (Image<TColor> src = provider.GetImage())
using (Image<TColor> dest = provider.Factory.CreateImage(8, 8))
using (PixelArea<TColor> area = new PixelArea<TColor>(8, 8, ComponentOrder.Xyz))
using (PixelAccessor<TColor> s = src.Lock())
using (PixelAccessor<TColor> d = dest.Lock())
{
using (var d = dest.Lock())
{
s.CopyRGBBytesStretchedTo(area, 0, 0);
d.CopyFrom(area, 0, 0);
s.CopyRGBBytesStretchedTo(area, 0, 0);
d.CopyFrom(area, 0, 0);
Assert.Equal(s[0, 0], d[0, 0]);
Assert.Equal(s[7, 0], d[7, 0]);
Assert.Equal(s[0, 7], d[0, 7]);
Assert.Equal(s[7, 7], d[7, 7]);
}
Assert.Equal(s[0, 0], d[0, 0]);
Assert.Equal(s[7, 0], d[7, 0]);
Assert.Equal(s[0, 7], d[0, 7]);
Assert.Equal(s[7, 7], d[7, 7]);
}
}
[Theory]
@ -68,45 +65,41 @@ namespace ImageSharp.Tests
public void CopyStretchedRGBTo_WithOffset<TColor>(TestImageProvider<TColor> provider)
where TColor : struct, IPackedPixel, IEquatable<TColor>
{
Image<TColor> src = provider.GetImage();
PixelArea<TColor> area = new PixelArea<TColor>(8, 8, ComponentOrder.Xyz);
Image<TColor> dest = provider.Factory.CreateImage(8, 8);
using (Image<TColor> src = provider.GetImage())
using (PixelArea<TColor> area = new PixelArea<TColor>(8, 8, ComponentOrder.Xyz))
using (Image<TColor> dest = provider.Factory.CreateImage(8, 8))
using (PixelAccessor<TColor> s = src.Lock())
using (PixelAccessor<TColor> d = dest.Lock())
{
using (var d = dest.Lock())
{
s.CopyRGBBytesStretchedTo(area, 7, 6);
d.CopyFrom(area, 0, 0);
s.CopyRGBBytesStretchedTo(area, 7, 6);
d.CopyFrom(area, 0, 0);
Assert.Equal(s[6, 7], d[0, 0]);
Assert.Equal(s[6, 8], d[0, 1]);
Assert.Equal(s[7, 8], d[1, 1]);
Assert.Equal(s[6, 7], d[0, 0]);
Assert.Equal(s[6, 8], d[0, 1]);
Assert.Equal(s[7, 8], d[1, 1]);
Assert.Equal(s[6, 9], d[0, 2]);
Assert.Equal(s[6, 9], d[0, 3]);
Assert.Equal(s[6, 9], d[0, 7]);
Assert.Equal(s[6, 9], d[0, 2]);
Assert.Equal(s[6, 9], d[0, 3]);
Assert.Equal(s[6, 9], d[0, 7]);
Assert.Equal(s[7, 9], d[1, 2]);
Assert.Equal(s[7, 9], d[1, 3]);
Assert.Equal(s[7, 9], d[1, 7]);
Assert.Equal(s[7, 9], d[1, 2]);
Assert.Equal(s[7, 9], d[1, 3]);
Assert.Equal(s[7, 9], d[1, 7]);
Assert.Equal(s[9, 9], d[3, 2]);
Assert.Equal(s[9, 9], d[3, 3]);
Assert.Equal(s[9, 9], d[3, 7]);
Assert.Equal(s[9, 9], d[3, 2]);
Assert.Equal(s[9, 9], d[3, 3]);
Assert.Equal(s[9, 9], d[3, 7]);
Assert.Equal(s[9, 7], d[3, 0]);
Assert.Equal(s[9, 7], d[4, 0]);
Assert.Equal(s[9, 7], d[7, 0]);
Assert.Equal(s[9, 7], d[3, 0]);
Assert.Equal(s[9, 7], d[4, 0]);
Assert.Equal(s[9, 7], d[7, 0]);
Assert.Equal(s[9, 9], d[3, 2]);
Assert.Equal(s[9, 9], d[4, 2]);
Assert.Equal(s[9, 9], d[7, 2]);
Assert.Equal(s[9, 9], d[3, 2]);
Assert.Equal(s[9, 9], d[4, 2]);
Assert.Equal(s[9, 9], d[7, 2]);
Assert.Equal(s[9, 9], d[4, 3]);
Assert.Equal(s[9, 9], d[7, 7]);
}
Assert.Equal(s[9, 9], d[4, 3]);
Assert.Equal(s[9, 9], d[7, 7]);
}
}
}

4
tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementationsTests.cs

@ -6,8 +6,6 @@
// ReSharper disable InconsistentNaming
namespace ImageSharp.Tests.Formats.Jpg
{
using System.Numerics;
using ImageSharp.Formats;
using ImageSharp.Formats.Jpg;
using Xunit;
@ -97,7 +95,7 @@ namespace ImageSharp.Tests.Formats.Jpg
Assert.Equal(expected, actual, new ApproximateFloatComparer(2f));
}
}
[Theory]
[InlineData(42)]
[InlineData(1)]

20
tests/ImageSharp.Tests/Formats/Png/PngTests.cs

@ -23,12 +23,13 @@ namespace ImageSharp.Tests
foreach (TestFile file in Files)
{
Image image = file.CreateImage();
using (FileStream output = File.OpenWrite($"{path}/{file.FileNameWithoutExtension}.png"))
using (Image image = file.CreateImage())
{
image.Quality = 256;
image.Save(output, new PngFormat());
using (FileStream output = File.OpenWrite($"{path}/{file.FileNameWithoutExtension}.png"))
{
image.Quality = 256;
image.Save(output, new PngFormat());
}
}
}
}
@ -42,11 +43,12 @@ namespace ImageSharp.Tests
Files,
file =>
{
Image image = file.CreateImage();
using (FileStream output = File.OpenWrite($"{path}/{file.FileNameWithoutExtension}.png"))
using (Image image = file.CreateImage())
{
image.SaveAsPng(output);
using (FileStream output = File.OpenWrite($"{path}/{file.FileNameWithoutExtension}.png"))
{
image.SaveAsPng(output);
}
}
});
}

9
tests/ImageSharp.Tests/Image/ImageTests.cs

@ -23,10 +23,11 @@ namespace ImageSharp.Tests
});
TestFile file = TestFile.Create(TestImages.Bmp.Car);
Image image = new Image(file.Bytes);
Assert.Equal(600, image.Width);
Assert.Equal(450, image.Height);
using (Image image = new Image(file.Bytes))
{
Assert.Equal(600, image.Width);
Assert.Equal(450, image.Height);
}
}
}
}

118
tests/ImageSharp.Tests/Image/PixelAccessorTests.cs

@ -19,8 +19,7 @@ namespace ImageSharp.Tests
where TColor : struct, IPackedPixel, IEquatable<TColor>
{
Image<TColor> image = factory.CreateImage(10, 10);
using (var pixels = image.Lock())
using (PixelAccessor<TColor> pixels = image.Lock())
{
for (int i = 0; i < 10; i++)
{
@ -47,31 +46,33 @@ namespace ImageSharp.Tests
public void CopyTo_Then_CopyFrom_OnFullImageRect<TColor>(TestImageProvider<TColor> provider, ComponentOrder order)
where TColor : struct, IPackedPixel, IEquatable<TColor>
{
var src = provider.GetImage();
var dest = new Image<TColor>(src.Width, src.Height);
using (PixelArea<TColor> area = new PixelArea<TColor>(src.Width, src.Height, order))
using (Image<TColor> src = provider.GetImage())
{
using (var srcPixels = src.Lock())
using (Image<TColor> dest = new Image<TColor>(src.Width, src.Height))
{
srcPixels.CopyTo(area, 0, 0);
}
using (PixelArea<TColor> area = new PixelArea<TColor>(src.Width, src.Height, order))
{
using (PixelAccessor<TColor> srcPixels = src.Lock())
{
srcPixels.CopyTo(area, 0, 0);
}
using (PixelAccessor<TColor> destPixels = dest.Lock())
{
destPixels.CopyFrom(area, 0, 0);
}
}
using (var destPixels = dest.Lock())
{
destPixels.CopyFrom(area, 0, 0);
Assert.True(src.IsEquivalentTo(dest, false));
}
}
Assert.True(src.IsEquivalentTo(dest, false));
}
// TODO: Need a processor in the library with this signature
private static void Fill<TColor>(Image<TColor> image, Rectangle region, TColor color)
where TColor : struct, IPackedPixel, IEquatable<TColor>
{
using (var pixels = image.Lock())
using (PixelAccessor<TColor> pixels = image.Lock())
{
for (int y = region.Top; y < region.Bottom; y++)
{
@ -88,87 +89,114 @@ namespace ImageSharp.Tests
[WithBlankImages(16, 16, PixelTypes.All, ComponentOrder.Zyx)]
[WithBlankImages(16, 16, PixelTypes.All, ComponentOrder.Xyzw)]
[WithBlankImages(16, 16, PixelTypes.All, ComponentOrder.Zyxw)]
public void CopyTo_Then_CopyFrom_WithOffset<TColor>(TestImageProvider<TColor> provider, ComponentOrder order)
public void CopyToThenCopyFromWithOffset<TColor>(TestImageProvider<TColor> provider, ComponentOrder order)
where TColor : struct, IPackedPixel, IEquatable<TColor>
{
var srcImage = provider.GetImage();
var color = default(TColor);
color.PackFromBytes(255, 0, 0, 255);
Fill(srcImage, new Rectangle(4, 4, 8, 8), color);
var destImage = new Image<TColor>(8, 8);
using (var srcPixels = srcImage.Lock())
using (Image<TColor> destImage = new Image<TColor>(8, 8))
{
using (var area = new PixelArea<TColor>(8, 8, order))
TColor color;
using (Image<TColor> srcImage = provider.GetImage())
{
srcPixels.CopyTo(area, 4, 4);
color = default(TColor);
color.PackFromBytes(255, 0, 0, 255);
using (var destPixels = destImage.Lock())
Fill(srcImage, new Rectangle(4, 4, 8, 8), color);
using (PixelAccessor<TColor> srcPixels = srcImage.Lock())
{
destPixels.CopyFrom(area, 0, 0);
using (PixelArea<TColor> area = new PixelArea<TColor>(8, 8, order))
{
srcPixels.CopyTo(area, 4, 4);
using (PixelAccessor<TColor> destPixels = destImage.Lock())
{
destPixels.CopyFrom(area, 0, 0);
}
}
}
}
}
provider.Utility.SourceFileOrDescription = order.ToString();
provider.Utility.SaveTestOutputFile(destImage, "bmp");
var expectedImage = new Image<TColor>(8, 8).Fill(color);
provider.Utility.SourceFileOrDescription = order.ToString();
provider.Utility.SaveTestOutputFile(destImage, "bmp");
Assert.True(destImage.IsEquivalentTo(expectedImage));
using (Image<TColor> expectedImage = new Image<TColor>(8, 8).Fill(color))
{
Assert.True(destImage.IsEquivalentTo(expectedImage));
}
}
}
[Fact]
public void CopyFromZYX()
{
CopyFromZYX(new Image(1, 1));
using (Image<Color> image = new Image<Color>(1, 1))
{
CopyFromZYX(image);
}
}
[Fact]
public void CopyFromZYXOptimized()
{
CopyFromZYX(new Image(1, 1));
using (Image image = new Image(1, 1))
{
CopyFromZYX(image);
}
}
[Fact]
public void CopyFromZYXW()
{
CopyFromZYXW(new Image(1, 1));
using (Image<Color> image = new Image<Color>(1, 1))
{
CopyFromZYXW(image);
}
}
[Fact]
public void CopyFromZYXWOptimized()
{
CopyFromZYXW(new Image(1, 1));
using (Image image = new Image(1, 1))
{
CopyFromZYXW(image);
}
}
[Fact]
public void CopyToZYX()
{
CopyToZYX(new Image(1, 1));
using (Image<Color> image = new Image<Color>(1, 1))
{
CopyToZYX(image);
}
}
[Fact]
public void CopyToZYXOptimized()
{
CopyToZYX(new Image(1, 1));
using (Image image = new Image(1, 1))
{
CopyToZYX(image);
}
}
[Fact]
public void CopyToZYXW()
{
CopyToZYXW(new Image(1, 1));
using (Image<Color> image = new Image<Color>(1, 1))
{
CopyToZYXW(image);
}
}
[Fact]
public void CopyToZYXWOptimized()
{
CopyToZYXW(new Image(1, 1));
using (Image image = new Image(1, 1))
{
CopyToZYXW(image);
}
}
private static void CopyFromZYX<TColor>(Image<TColor> image)

20
tests/ImageSharp.Tests/Processors/Filters/AlphaTest.cs

@ -19,39 +19,35 @@ namespace ImageSharp.Tests
};
[Theory]
[MemberData("AlphaValues")]
[MemberData(nameof(AlphaValues))]
public void ImageShouldApplyAlphaFilter(int value)
{
string path = CreateOutputDirectory("Alpha");
string path = this.CreateOutputDirectory("Alpha");
foreach (TestFile file in Files)
{
string filename = file.GetFileName(value);
Image image = file.CreateImage();
using (Image image = file.CreateImage())
using (FileStream output = File.OpenWrite($"{path}/{filename}"))
{
image.Alpha(value)
.Save(output);
image.Alpha(value).Save(output);
}
}
}
[Theory]
[MemberData("AlphaValues")]
[MemberData(nameof(AlphaValues))]
public void ImageShouldApplyAlphaFilterInBox(int value)
{
string path = CreateOutputDirectory("Alpha");
string path = this.CreateOutputDirectory("Alpha");
foreach (TestFile file in Files)
{
string filename = file.GetFileName(value);
Image image = file.CreateImage();
using (Image image = file.CreateImage())
using (FileStream output = File.OpenWrite($"{path}/{filename}"))
{
image.Alpha(value, new Rectangle(10, 10, image.Width / 2, image.Height / 2))
.Save(output);
image.Alpha(value, new Rectangle(10, 10, image.Width / 2, image.Height / 2)).Save(output);
}
}
}

19
tests/ImageSharp.Tests/Processors/Filters/AutoOrientTests.cs

@ -26,25 +26,22 @@ namespace ImageSharp.Tests
};
[Theory]
[MemberData("OrientationValues")]
[MemberData(nameof(OrientationValues))]
public void ImageShouldFlip(RotateType rotateType, FlipType flipType, ushort orientation)
{
string path = CreateOutputDirectory("AutoOrient");
string path = this.CreateOutputDirectory("AutoOrient");
TestFile file = TestFile.Create(TestImages.Bmp.F);
Image image = file.CreateImage();
image.ExifProfile = new ExifProfile();
image.ExifProfile.SetValue(ExifTag.Orientation, orientation);
using (FileStream before = File.OpenWrite($"{path}/before-{file.FileName}"))
using (Image image = file.CreateImage())
{
image.ExifProfile = new ExifProfile();
image.ExifProfile.SetValue(ExifTag.Orientation, orientation);
using (FileStream before = File.OpenWrite($"{path}/before-{file.FileName}"))
using (FileStream after = File.OpenWrite($"{path}/after-{file.FileName}"))
{
image.RotateFlip(rotateType, flipType)
.Save(before)
.AutoOrient()
.Save(after);
image.RotateFlip(rotateType, flipType).Save(before).AutoOrient().Save(after);
}
}
}

8
tests/ImageSharp.Tests/Processors/Filters/BackgroundColorTest.cs

@ -14,16 +14,14 @@ namespace ImageSharp.Tests
[Fact]
public void ImageShouldApplyBackgroundColorFilter()
{
string path = CreateOutputDirectory("BackgroundColor");
string path = this.CreateOutputDirectory("BackgroundColor");
foreach (TestFile file in Files)
{
Image image = file.CreateImage();
using (Image image = file.CreateImage())
using (FileStream output = File.OpenWrite($"{path}/{file.FileName}"))
{
image.BackgroundColor(Color.HotPink)
.Save(output);
image.BackgroundColor(Color.HotPink).Save(output);
}
}
}

10
tests/ImageSharp.Tests/Processors/Filters/BinaryThreshold.cs

@ -19,20 +19,18 @@ namespace ImageSharp.Tests
};
[Theory]
[MemberData("BinaryThresholdValues")]
[MemberData(nameof(BinaryThresholdValues))]
public void ImageShouldApplyBinaryThresholdFilter(float value)
{
string path = CreateOutputDirectory("BinaryThreshold");
string path = this.CreateOutputDirectory("BinaryThreshold");
foreach (TestFile file in Files)
{
string filename = file.GetFileName(value);
Image image = file.CreateImage();
using (Image image = file.CreateImage())
using (FileStream output = File.OpenWrite($"{path}/{filename}"))
{
image.BinaryThreshold(value)
.Save(output);
image.BinaryThreshold(value).Save(output);
}
}
}

8
tests/ImageSharp.Tests/Processors/Filters/BlackWhiteTest.cs

@ -14,16 +14,14 @@ namespace ImageSharp.Tests
[Fact]
public void ImageShouldApplyBlackWhiteFilter()
{
string path = CreateOutputDirectory("BlackWhite");
string path = this.CreateOutputDirectory("BlackWhite");
foreach (TestFile file in Files)
{
Image image = file.CreateImage();
using (Image image = file.CreateImage())
using (FileStream output = File.OpenWrite($"{path}/{file.FileName}"))
{
image.BlackWhite()
.Save(output);
image.BlackWhite().Save(output);
}
}
}

10
tests/ImageSharp.Tests/Processors/Filters/BoxBlurTest.cs

@ -19,20 +19,18 @@ namespace ImageSharp.Tests
};
[Theory]
[MemberData("BoxBlurValues")]
[MemberData(nameof(BoxBlurValues))]
public void ImageShouldApplyBoxBlurFilter(int value)
{
string path = CreateOutputDirectory("BoxBlur");
string path = this.CreateOutputDirectory("BoxBlur");
foreach (TestFile file in Files)
{
string filename = file.GetFileName(value);
Image image = file.CreateImage();
using (Image image = file.CreateImage())
using (FileStream output = File.OpenWrite($"{path}/{filename}"))
{
image.BoxBlur(value)
.Save(output);
image.BoxBlur(value).Save(output);
}
}
}

10
tests/ImageSharp.Tests/Processors/Filters/BrightnessTest.cs

@ -19,20 +19,18 @@ namespace ImageSharp.Tests
};
[Theory]
[MemberData("BrightnessValues")]
[MemberData(nameof(BrightnessValues))]
public void ImageShouldApplyBrightnessFilter(int value)
{
string path = CreateOutputDirectory("Brightness");
string path = this.CreateOutputDirectory("Brightness");
foreach (TestFile file in Files)
{
string filename = file.GetFileName(value);
Image image = file.CreateImage();
using (Image image = file.CreateImage())
using (FileStream output = File.OpenWrite($"{path}/{filename}"))
{
image.Brightness(value)
.Save(output);
image.Brightness(value).Save(output);
}
}
}

10
tests/ImageSharp.Tests/Processors/Filters/ColorBlindnessTest.cs

@ -26,20 +26,18 @@ namespace ImageSharp.Tests
};
[Theory]
[MemberData("ColorBlindnessFilters")]
[MemberData(nameof(ColorBlindnessFilters))]
public void ImageShouldApplyColorBlindnessFilter(ColorBlindness colorBlindness)
{
string path = CreateOutputDirectory("ColorBlindness");
string path = this.CreateOutputDirectory("ColorBlindness");
foreach (TestFile file in Files)
{
string filename = file.GetFileName(colorBlindness);
Image image = file.CreateImage();
using (Image image = file.CreateImage())
using (FileStream output = File.OpenWrite($"{path}/{filename}"))
{
image.ColorBlindness(colorBlindness)
.Save(output);
image.ColorBlindness(colorBlindness).Save(output);
}
}
}

10
tests/ImageSharp.Tests/Processors/Filters/ContrastTest.cs

@ -19,19 +19,17 @@ namespace ImageSharp.Tests
};
[Theory]
[MemberData("ContrastValues")]
[MemberData(nameof(ContrastValues))]
public void ImageShouldApplyContrastFilter(int value)
{
string path = CreateOutputDirectory("Contrast");
string path = this.CreateOutputDirectory("Contrast");
foreach (TestFile file in Files)
{
Image image = file.CreateImage();
using (Image image = file.CreateImage())
using (FileStream output = File.OpenWrite($"{path}/{file.FileName}"))
{
image.Contrast(value)
.Save(output);
image.Contrast(value).Save(output);
}
}
}

8
tests/ImageSharp.Tests/Processors/Filters/CropTest.cs

@ -14,16 +14,14 @@ namespace ImageSharp.Tests
[Fact]
public void ImageShouldApplyCropSampler()
{
string path = CreateOutputDirectory("Crop");
string path = this.CreateOutputDirectory("Crop");
foreach (TestFile file in Files)
{
Image image = file.CreateImage();
using (Image image = file.CreateImage())
using (FileStream output = File.OpenWrite($"{path}/{file.FileName}"))
{
image.Crop(image.Width / 2, image.Height / 2)
.Save(output);
image.Crop(image.Width / 2, image.Height / 2).Save(output);
}
}
}

15
tests/ImageSharp.Tests/Processors/Filters/DetectEdgesTest.cs

@ -31,32 +31,29 @@ namespace ImageSharp.Tests
[MemberData(nameof(DetectEdgesFilters))]
public void ImageShouldApplyDetectEdgesFilter(EdgeDetection detector)
{
string path = CreateOutputDirectory("DetectEdges");
string path = this.CreateOutputDirectory("DetectEdges");
foreach (TestFile file in Files)
{
string filename = file.GetFileName(detector);
Image image = file.CreateImage();
using (Image image = file.CreateImage())
using (FileStream output = File.OpenWrite($"{path}/{filename}"))
{
image.DetectEdges(detector)
.Save(output);
image.DetectEdges(detector).Save(output);
}
}
}
[Theory]
[MemberData("DetectEdgesFilters")]
[MemberData(nameof(DetectEdgesFilters))]
public void ImageShouldApplyDetectEdgesFilterInBox(EdgeDetection detector)
{
string path = CreateOutputDirectory("DetectEdges");
string path = this.CreateOutputDirectory("DetectEdges");
foreach (TestFile file in Files)
{
string filename = file.GetFileName(detector + "-InBox");
Image image = file.CreateImage();
using (Image image = file.CreateImage())
using (FileStream output = File.OpenWrite($"{path}/{filename}"))
{
image.DetectEdges(detector, new Rectangle(image.Width / 4, image.Height / 4, image.Width / 2, image.Height / 2))

10
tests/ImageSharp.Tests/Processors/Filters/EntropyCropTest.cs

@ -19,20 +19,18 @@ namespace ImageSharp.Tests
};
[Theory]
[MemberData("EntropyCropValues")]
[MemberData(nameof(EntropyCropValues))]
public void ImageShouldApplyEntropyCropSampler(float value)
{
string path = CreateOutputDirectory("EntropyCrop");
string path = this.CreateOutputDirectory("EntropyCrop");
foreach (TestFile file in Files)
{
string filename = file.GetFileName(value);
Image image = file.CreateImage();
using (Image image = file.CreateImage())
using (FileStream output = File.OpenWrite($"{path}/{filename}"))
{
image.EntropyCrop(value)
.Save(output);
image.EntropyCrop(value).Save(output);
}
}
}

10
tests/ImageSharp.Tests/Processors/Filters/FlipTests.cs

@ -20,20 +20,18 @@ namespace ImageSharp.Tests
};
[Theory]
[MemberData("FlipValues")]
[MemberData(nameof(FlipValues))]
public void ImageShouldFlip(FlipType flipType)
{
string path = CreateOutputDirectory("Flip");
string path = this.CreateOutputDirectory("Flip");
foreach (TestFile file in Files)
{
string filename = file.GetFileName(flipType);
Image image = file.CreateImage();
using (Image image = file.CreateImage())
using (FileStream output = File.OpenWrite($"{path}/{filename}"))
{
image.Flip(flipType)
.Save(output);
image.Flip(flipType).Save(output);
}
}
}

10
tests/ImageSharp.Tests/Processors/Filters/GaussianBlurTest.cs

@ -19,20 +19,18 @@ namespace ImageSharp.Tests
};
[Theory]
[MemberData("GaussianBlurValues")]
[MemberData(nameof(GaussianBlurValues))]
public void ImageShouldApplyGaussianBlurFilter(int value)
{
string path = CreateOutputDirectory("GaussianBlur");
string path = this.CreateOutputDirectory("GaussianBlur");
foreach (TestFile file in Files)
{
string filename = file.GetFileName(value);
Image image = file.CreateImage();
using (Image image = file.CreateImage())
using (FileStream output = File.OpenWrite($"{path}/{filename}"))
{
image.GaussianBlur(value)
.Save(output);
image.GaussianBlur(value).Save(output);
}
}
}

10
tests/ImageSharp.Tests/Processors/Filters/GaussianSharpenTest.cs

@ -19,20 +19,18 @@ namespace ImageSharp.Tests
};
[Theory]
[MemberData("GaussianSharpenValues")]
[MemberData(nameof(GaussianSharpenValues))]
public void ImageShouldApplyGaussianSharpenFilter(int value)
{
string path = CreateOutputDirectory("GaussianSharpen");
string path = this.CreateOutputDirectory("GaussianSharpen");
foreach (TestFile file in Files)
{
string filename = file.GetFileName(value);
Image image = file.CreateImage();
using (Image image = file.CreateImage())
using (FileStream output = File.OpenWrite($"{path}/{filename}"))
{
image.GaussianSharpen(value)
.Save(output);
image.GaussianSharpen(value).Save(output);
}
}
}

31
tests/ImageSharp.Tests/Processors/Filters/GlowTest.cs

@ -14,16 +14,14 @@ namespace ImageSharp.Tests
[Fact]
public void ImageShouldApplyGlowFilter()
{
string path = CreateOutputDirectory("Glow");
string path = this.CreateOutputDirectory("Glow");
foreach (TestFile file in Files)
{
Image image = file.CreateImage();
using (Image image = file.CreateImage())
using (FileStream output = File.OpenWrite($"{path}/{file.FileName}"))
{
image.Glow()
.Save(output);
image.Glow().Save(output);
}
}
}
@ -31,17 +29,15 @@ namespace ImageSharp.Tests
[Fact]
public void ImageShouldApplyGlowFilterColor()
{
string path = CreateOutputDirectory("Glow");
string path = this.CreateOutputDirectory("Glow");
foreach (TestFile file in Files)
{
string filename = file.GetFileName("Color");
Image image = file.CreateImage();
using (Image image = file.CreateImage())
using (FileStream output = File.OpenWrite($"{path}/{filename}"))
{
image.Glow(Color.HotPink)
.Save(output);
image.Glow(Color.HotPink).Save(output);
}
}
}
@ -49,17 +45,15 @@ namespace ImageSharp.Tests
[Fact]
public void ImageShouldApplyGlowFilterRadius()
{
string path = CreateOutputDirectory("Glow");
string path = this.CreateOutputDirectory("Glow");
foreach (TestFile file in Files)
{
string filename = file.GetFileName("Radius");
Image image = file.CreateImage();
using (Image image = file.CreateImage())
using (FileStream output = File.OpenWrite($"{path}/{filename}"))
{
image.Glow(image.Width / 4)
.Save(output);
image.Glow(image.Width / 4F).Save(output);
}
}
}
@ -67,17 +61,16 @@ namespace ImageSharp.Tests
[Fact]
public void ImageShouldApplyGlowFilterInBox()
{
string path = CreateOutputDirectory("Glow");
string path = this.CreateOutputDirectory("Glow");
foreach (TestFile file in Files)
{
string filename = file.GetFileName("InBox");
Image image = file.CreateImage();
using (Image image = file.CreateImage())
using (FileStream output = File.OpenWrite($"{path}/{filename}"))
{
image.Glow(new Rectangle(image.Width / 4, image.Height / 4, image.Width / 2, image.Height / 2))
.Save(output);
.Save(output);
}
}
}

10
tests/ImageSharp.Tests/Processors/Filters/GrayscaleTest.cs

@ -20,20 +20,18 @@ namespace ImageSharp.Tests
};
[Theory]
[MemberData("GrayscaleValues")]
[MemberData(nameof(GrayscaleValues))]
public void ImageShouldApplyGrayscaleFilter(GrayscaleMode value)
{
string path = CreateOutputDirectory("Grayscale");
string path = this.CreateOutputDirectory("Grayscale");
foreach (TestFile file in Files)
{
string filename = file.GetFileName(value);
Image image = file.CreateImage();
using (Image image = file.CreateImage())
using (FileStream output = File.OpenWrite($"{path}/{filename}"))
{
image.Grayscale(value)
.Save(output);
image.Grayscale(value).Save(output);
}
}
}

10
tests/ImageSharp.Tests/Processors/Filters/HueTest.cs

@ -19,20 +19,18 @@ namespace ImageSharp.Tests
};
[Theory]
[MemberData("HueValues")]
[MemberData(nameof(HueValues))]
public void ImageShouldApplyHueFilter(int value)
{
string path = CreateOutputDirectory("Hue");
string path = this.CreateOutputDirectory("Hue");
foreach (TestFile file in Files)
{
string filename = file.GetFileName(value);
Image image = file.CreateImage();
using (Image image = file.CreateImage())
using (FileStream output = File.OpenWrite($"{path}/{filename}"))
{
image.Hue(value)
.Save(output);
image.Hue(value).Save(output);
}
}
}

16
tests/ImageSharp.Tests/Processors/Filters/InvertTest.cs

@ -14,15 +14,13 @@ namespace ImageSharp.Tests
[Fact]
public void ImageShouldApplyInvertFilter()
{
string path = CreateOutputDirectory("Invert");
string path = this.CreateOutputDirectory("Invert");
foreach (TestFile file in Files)
{
Image image = file.CreateImage();
using (Image image = file.CreateImage())
using (FileStream output = File.OpenWrite($"{path}/{file.FileName}"))
{
image.Invert()
.Save(output);
image.Invert().Save(output);
}
}
}
@ -30,17 +28,15 @@ namespace ImageSharp.Tests
[Fact]
public void ImageShouldApplyInvertFilterInBox()
{
string path = CreateOutputDirectory("Invert");
string path = this.CreateOutputDirectory("Invert");
foreach (TestFile file in Files)
{
string filename = file.GetFileName("InBox");
Image image = file.CreateImage();
using (Image image = file.CreateImage())
using (FileStream output = File.OpenWrite($"{path}/{filename}"))
{
image.Invert(new Rectangle(10, 10, image.Width / 2, image.Height / 2))
.Save(output);
image.Invert(new Rectangle(10, 10, image.Width / 2, image.Height / 2)).Save(output);
}
}
}

8
tests/ImageSharp.Tests/Processors/Filters/KodachromeTest.cs

@ -14,16 +14,14 @@ namespace ImageSharp.Tests
[Fact]
public void ImageShouldApplyKodachromeFilter()
{
string path = CreateOutputDirectory("Kodachrome");
string path = this.CreateOutputDirectory("Kodachrome");
foreach (TestFile file in Files)
{
Image image = file.CreateImage();
using (Image image = file.CreateImage())
using (FileStream output = File.OpenWrite($"{path}/{file.FileName}"))
{
image.Kodachrome()
.Save(output);
image.Kodachrome().Save(output);
}
}
}

15
tests/ImageSharp.Tests/Processors/Filters/LomographTest.cs

@ -14,16 +14,14 @@ namespace ImageSharp.Tests
[Fact]
public void ImageShouldApplyLomographFilter()
{
string path = CreateOutputDirectory("Lomograph");
string path = this.CreateOutputDirectory("Lomograph");
foreach (TestFile file in Files)
{
Image image = file.CreateImage();
using (Image image = file.CreateImage())
using (FileStream output = File.OpenWrite($"{path}/{file.FileName}"))
{
image.Lomograph()
.Save(output);
image.Lomograph().Save(output);
}
}
}
@ -31,17 +29,16 @@ namespace ImageSharp.Tests
[Fact]
public void ImageShouldApplyLomographFilterInBox()
{
string path = CreateOutputDirectory("Lomograph");
string path = this.CreateOutputDirectory("Lomograph");
foreach (TestFile file in Files)
{
string filename = file.GetFileName("InBox");
Image image = file.CreateImage();
using (Image image = file.CreateImage())
using (FileStream output = File.OpenWrite($"{path}/{filename}"))
{
image.Lomograph(new Rectangle(image.Width / 4, image.Width / 4, image.Width / 2, image.Height / 2))
.Save(output);
.Save(output);
}
}
}

21
tests/ImageSharp.Tests/Processors/Filters/OilPaintTest.cs

@ -23,19 +23,17 @@ namespace ImageSharp.Tests
[MemberData(nameof(OilPaintValues))]
public void ImageShouldApplyOilPaintFilter(Tuple<int, int> value)
{
string path = CreateOutputDirectory("OilPaint");
string path = this.CreateOutputDirectory("OilPaint");
foreach (TestFile file in Files)
{
string filename = file.GetFileName(value);
Image image = file.CreateImage();
using (Image image = file.CreateImage())
using (FileStream output = File.OpenWrite($"{path}/{filename}"))
{
if (image.Width > value.Item2 && image.Height > value.Item2)
{
image.OilPaint(value.Item1, value.Item2)
.Save(output);
image.OilPaint(value.Item1, value.Item2).Save(output);
}
}
}
@ -45,18 +43,19 @@ namespace ImageSharp.Tests
[MemberData(nameof(OilPaintValues))]
public void ImageShouldApplyOilPaintFilterInBox(Tuple<int, int> value)
{
string path = CreateOutputDirectory("OilPaint");
string path = this.CreateOutputDirectory("OilPaint");
foreach (TestFile file in Files)
{
string filename = file.GetFileName(value + "-InBox");
Image image = file.CreateImage();
if (image.Width > value.Item2 && image.Height > value.Item2)
using (Image image = file.CreateImage())
{
using (FileStream output = File.OpenWrite($"{path}/{filename}"))
if (image.Width > value.Item2 && image.Height > value.Item2)
{
image.OilPaint(value.Item1, value.Item2, new Rectangle(image.Width / 4, image.Width / 4, image.Width / 2, image.Height / 2)).Save(output);
using (FileStream output = File.OpenWrite($"{path}/{filename}"))
{
image.OilPaint(value.Item1, value.Item2, new Rectangle(image.Width / 4, image.Width / 4, image.Width / 2, image.Height / 2)).Save(output);
}
}
}
}

8
tests/ImageSharp.Tests/Processors/Filters/PadTest.cs

@ -14,16 +14,14 @@ namespace ImageSharp.Tests
[Fact]
public void ImageShouldApplyPadSampler()
{
string path = CreateOutputDirectory("Pad");
string path = this.CreateOutputDirectory("Pad");
foreach (TestFile file in Files)
{
Image image = file.CreateImage();
using (Image image = file.CreateImage())
using (FileStream output = File.OpenWrite($"{path}/{file.FileName}"))
{
image.Pad(image.Width + 50, image.Height + 50)
.Save(output);
image.Pad(image.Width + 50, image.Height + 50).Save(output);
}
}
}

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

@ -41,17 +41,15 @@ namespace ImageSharp.Tests
[MemberData(nameof(PixelateValues))]
public void ImageShouldApplyPixelateFilterInBox(int value)
{
string path = CreateOutputDirectory("Pixelate");
string path = this.CreateOutputDirectory("Pixelate");
foreach (TestFile file in Files)
{
string filename = file.GetFileName(value + "-InBox");
Image image = file.CreateImage();
using (Image image = file.CreateImage())
using (FileStream output = File.OpenWrite($"{path}/{filename}"))
{
image.Pixelate(value, new Rectangle(10, 10, image.Width / 2, image.Height / 2))
.Save(output);
image.Pixelate(value, new Rectangle(10, 10, image.Width / 2, image.Height / 2)).Save(output);
}
}
}

8
tests/ImageSharp.Tests/Processors/Filters/PolaroidTest.cs

@ -14,16 +14,14 @@ namespace ImageSharp.Tests
[Fact]
public void ImageShouldApplyPolaroidFilter()
{
string path = CreateOutputDirectory("Polaroid");
string path = this.CreateOutputDirectory("Polaroid");
foreach (TestFile file in Files)
{
Image image = file.CreateImage();
using (Image image = file.CreateImage())
using (FileStream output = File.OpenWrite($"{path}/{file.FileName}"))
{
image.Polaroid()
.Save(output);
image.Polaroid().Save(output);
}
}
}

76
tests/ImageSharp.Tests/Processors/Filters/ResizeTests.cs

@ -42,12 +42,10 @@ namespace ImageSharp.Tests
foreach (TestFile file in Files)
{
string filename = file.GetFileName(name);
Image image = file.CreateImage();
using (Image image = file.CreateImage())
using (FileStream output = File.OpenWrite($"{path}/{filename}"))
{
image.Resize(image.Width / 2, image.Height / 2, sampler, true)
.Save(output);
image.Resize(image.Width / 2, image.Height / 2, sampler, true).Save(output);
}
}
}
@ -63,12 +61,10 @@ namespace ImageSharp.Tests
foreach (TestFile file in Files)
{
string filename = file.GetFileName(name);
Image image = file.CreateImage();
using (Image image = file.CreateImage())
using (FileStream output = File.OpenWrite($"{path}/{filename}"))
{
image.Resize(image.Width / 3, 0, sampler, false)
.Save(output);
image.Resize(image.Width / 3, 0, sampler, false).Save(output);
}
}
}
@ -84,12 +80,10 @@ namespace ImageSharp.Tests
foreach (TestFile file in Files)
{
string filename = file.GetFileName(name);
Image image = file.CreateImage();
using (Image image = file.CreateImage())
using (FileStream output = File.OpenWrite($"{path}/{filename}"))
{
image.Resize(0, image.Height / 3, sampler, false)
.Save(output);
image.Resize(0, image.Height / 3, sampler, false).Save(output);
}
}
}
@ -105,18 +99,16 @@ namespace ImageSharp.Tests
foreach (TestFile file in Files)
{
string filename = file.GetFileName(name);
Image image = file.CreateImage();
using (Image image = file.CreateImage())
using (FileStream output = File.OpenWrite($"{path}/{filename}"))
{
ResizeOptions options = new ResizeOptions()
ResizeOptions options = new ResizeOptions
{
Sampler = sampler,
Size = new Size(image.Width / 2, image.Height)
};
image.Resize(options)
.Save(output);
image.Resize(options).Save(output);
}
}
}
@ -132,18 +124,16 @@ namespace ImageSharp.Tests
foreach (TestFile file in Files)
{
string filename = file.GetFileName(name);
Image image = file.CreateImage();
using (Image image = file.CreateImage())
using (FileStream output = File.OpenWrite($"{path}/{filename}"))
{
ResizeOptions options = new ResizeOptions()
ResizeOptions options = new ResizeOptions
{
Sampler = sampler,
Size = new Size(image.Width, image.Height / 2)
};
image.Resize(options)
.Save(output);
image.Resize(options).Save(output);
}
}
}
@ -159,18 +149,16 @@ namespace ImageSharp.Tests
foreach (TestFile file in Files)
{
string filename = file.GetFileName(name);
Image image = file.CreateImage();
using (Image image = file.CreateImage())
using (FileStream output = File.OpenWrite($"{path}/{filename}"))
{
ResizeOptions options = new ResizeOptions()
ResizeOptions options = new ResizeOptions
{
Size = new Size(image.Width + 200, image.Height),
Mode = ResizeMode.Pad
};
image.Resize(options)
.Save(output);
image.Resize(options).Save(output);
}
}
}
@ -186,19 +174,17 @@ namespace ImageSharp.Tests
foreach (TestFile file in Files)
{
string filename = file.GetFileName(name);
Image image = file.CreateImage();
using (Image image = file.CreateImage())
using (FileStream output = File.OpenWrite($"{path}/{filename}"))
{
ResizeOptions options = new ResizeOptions()
ResizeOptions options = new ResizeOptions
{
Sampler = sampler,
Size = new Size(image.Width + 200, image.Height + 200),
Mode = ResizeMode.BoxPad
};
image.Resize(options)
.Save(output);
image.Resize(options).Save(output);
}
}
}
@ -214,19 +200,17 @@ namespace ImageSharp.Tests
foreach (TestFile file in Files)
{
string filename = file.GetFileName(name);
Image image = file.CreateImage();
using (Image image = file.CreateImage())
using (FileStream output = File.OpenWrite($"{path}/{filename}"))
{
ResizeOptions options = new ResizeOptions()
ResizeOptions options = new ResizeOptions
{
Sampler = sampler,
Size = new Size(300, 300),
Mode = ResizeMode.Max
};
image.Resize(options)
.Save(output);
image.Resize(options).Save(output);
}
}
}
@ -242,19 +226,17 @@ namespace ImageSharp.Tests
foreach (TestFile file in Files)
{
string filename = file.GetFileName(name);
Image image = file.CreateImage();
using (Image image = file.CreateImage())
using (FileStream output = File.OpenWrite($"{path}/{filename}"))
{
ResizeOptions options = new ResizeOptions()
ResizeOptions options = new ResizeOptions
{
Sampler = sampler,
Size = new Size((int)Math.Round(image.Width * .75F), (int)Math.Round(image.Height * 95F)),
Size = new Size((int)Math.Round(image.Width * .75F), (int)Math.Round(image.Height * .95F)),
Mode = ResizeMode.Min
};
image.Resize(options)
.Save(output);
image.Resize(options).Save(output);
}
}
}
@ -270,19 +252,17 @@ namespace ImageSharp.Tests
foreach (TestFile file in Files)
{
string filename = file.GetFileName(name);
Image image = file.CreateImage();
using (Image image = file.CreateImage())
using (FileStream output = File.OpenWrite($"{path}/{filename}"))
{
ResizeOptions options = new ResizeOptions()
ResizeOptions options = new ResizeOptions
{
Sampler = sampler,
Size = new Size(image.Width / 2, image.Height),
Mode = ResizeMode.Stretch
};
image.Resize(options)
.Save(output);
image.Resize(options).Save(output);
}
}
}

10
tests/ImageSharp.Tests/Processors/Filters/RotateFlipTest.cs

@ -22,20 +22,18 @@ namespace ImageSharp.Tests
};
[Theory]
[MemberData("RotateFlipValues")]
[MemberData(nameof(RotateFlipValues))]
public void ImageShouldRotateFlip(RotateType rotateType, FlipType flipType)
{
string path = CreateOutputDirectory("RotateFlip");
string path = this.CreateOutputDirectory("RotateFlip");
foreach (TestFile file in Files)
{
string filename = file.GetFileName(rotateType + "-" + flipType);
Image image = file.CreateImage();
using (Image image = file.CreateImage())
using (FileStream output = File.OpenWrite($"{path}/{filename}"))
{
image.RotateFlip(rotateType, flipType)
.Save(output);
image.RotateFlip(rotateType, flipType).Save(output);
}
}
}

20
tests/ImageSharp.Tests/Processors/Filters/RotateTest.cs

@ -28,39 +28,35 @@ namespace ImageSharp.Tests
};
[Theory]
[MemberData("RotateFloatValues")]
[MemberData(nameof(RotateFloatValues))]
public void ImageShouldApplyRotateSampler(float value)
{
string path = CreateOutputDirectory("Rotate");
string path = this.CreateOutputDirectory("Rotate");
foreach (TestFile file in Files)
{
string filename = file.GetFileName(value);
Image image = file.CreateImage();
using (Image image = file.CreateImage())
using (FileStream output = File.OpenWrite($"{path}/{filename}"))
{
image.Rotate(value)
.Save(output);
image.Rotate(value).Save(output);
}
}
}
[Theory]
[MemberData("RotateEnumValues")]
[MemberData(nameof(RotateEnumValues))]
public void ImageShouldApplyRotateSampler(RotateType value)
{
string path = CreateOutputDirectory("Rotate");
string path = this.CreateOutputDirectory("Rotate");
foreach (TestFile file in Files)
{
string filename = file.GetFileName(value);
Image image = file.CreateImage();
using (Image image = file.CreateImage())
using (FileStream output = File.OpenWrite($"{path}/{filename}"))
{
image.Rotate(value)
.Save(output);
image.Rotate(value).Save(output);
}
}
}

8
tests/ImageSharp.Tests/Processors/Filters/SaturationTest.cs

@ -19,7 +19,7 @@ namespace ImageSharp.Tests
};
[Theory]
[MemberData("SaturationValues")]
[MemberData(nameof(SaturationValues))]
public void ImageShouldApplySaturationFilter(int value)
{
string path = CreateOutputDirectory("Saturation");
@ -27,12 +27,10 @@ namespace ImageSharp.Tests
foreach (TestFile file in Files)
{
string filename = file.GetFileName(value);
Image image = file.CreateImage();
using (Image image = file.CreateImage())
using (FileStream output = File.OpenWrite($"{path}/{filename}"))
{
image.Saturation(value)
.Save(output);
image.Saturation(value).Save(output);
}
}
}

6
tests/ImageSharp.Tests/Processors/Filters/SepiaTest.cs

@ -18,12 +18,10 @@ namespace ImageSharp.Tests
foreach (TestFile file in Files)
{
Image image = file.CreateImage();
using (Image image = file.CreateImage())
using (FileStream output = File.OpenWrite($"{path}/{file.FileName}"))
{
image.Sepia()
.Save(output);
image.Sepia().Save(output);
}
}
}

12
tests/ImageSharp.Tests/Processors/Filters/SkewTest.cs

@ -19,22 +19,20 @@ namespace ImageSharp.Tests
};
[Theory]
[MemberData("SkewValues")]
[MemberData(nameof(SkewValues))]
public void ImageShouldApplySkewSampler(float x, float y)
{
string path = CreateOutputDirectory("Skew");
string path = this.CreateOutputDirectory("Skew");
// Matches live example
// Matches live example
// http://www.w3schools.com/css/tryit.asp?filename=trycss3_transform_skew
foreach (TestFile file in Files)
{
string filename = file.GetFileName(x + "-" + y);
Image image = file.CreateImage();
using (Image image = file.CreateImage())
using (FileStream output = File.OpenWrite($"{path}/{filename}"))
{
image.Skew(x, y)
.Save(output);
image.Skew(x, y).Save(output);
}
}
}

31
tests/ImageSharp.Tests/Processors/Filters/VignetteTest.cs

@ -14,16 +14,14 @@ namespace ImageSharp.Tests
[Fact]
public void ImageShouldApplyVignetteFilter()
{
string path = CreateOutputDirectory("Vignette");
string path = this.CreateOutputDirectory("Vignette");
foreach (TestFile file in Files)
{
Image image = file.CreateImage();
using (Image image = file.CreateImage())
using (FileStream output = File.OpenWrite($"{path}/{file.FileName}"))
{
image.Vignette()
.Save(output);
image.Vignette().Save(output);
}
}
}
@ -31,17 +29,15 @@ namespace ImageSharp.Tests
[Fact]
public void ImageShouldApplyVignetteFilterColor()
{
string path = CreateOutputDirectory("Vignette");
string path = this.CreateOutputDirectory("Vignette");
foreach (TestFile file in Files)
{
string filename = file.GetFileName("Color");
Image image = file.CreateImage();
using (Image image = file.CreateImage())
using (FileStream output = File.OpenWrite($"{path}/{filename}"))
{
image.Vignette(Color.HotPink)
.Save(output);
image.Vignette(Color.HotPink).Save(output);
}
}
}
@ -49,17 +45,15 @@ namespace ImageSharp.Tests
[Fact]
public void ImageShouldApplyVignetteFilterRadius()
{
string path = CreateOutputDirectory("Vignette");
string path = this.CreateOutputDirectory("Vignette");
foreach (TestFile file in Files)
{
string filename = file.GetFileName("Radius");
Image image = file.CreateImage();
using (Image image = file.CreateImage())
using (FileStream output = File.OpenWrite($"{path}/{filename}"))
{
image.Vignette(image.Width / 4, image.Height / 4)
.Save(output);
image.Vignette(image.Width / 4F, image.Height / 4F).Save(output);
}
}
}
@ -67,17 +61,16 @@ namespace ImageSharp.Tests
[Fact]
public void ImageShouldApplyVignetteFilterInBox()
{
string path = CreateOutputDirectory("Vignette");
string path = this.CreateOutputDirectory("Vignette");
foreach (TestFile file in Files)
{
string filename = file.GetFileName("InBox");
Image image = file.CreateImage();
using (Image image = file.CreateImage())
using (FileStream output = File.OpenWrite($"{path}/{filename}"))
{
image.Vignette(new Rectangle(image.Width / 4, image.Height / 4, image.Width / 2, image.Height / 2))
.Save(output);
.Save(output);
}
}
}

3
tests/ImageSharp.Tests/Profiles/Exif/ExifProfileTests.cs

@ -31,6 +31,8 @@ namespace ImageSharp.Tests
ExifValue value = image.ExifProfile.Values.FirstOrDefault(val => val.Tag == ExifTag.Copyright);
TestValue(value, "Dirk Lemstra");
}
[Fact]
@ -247,6 +249,7 @@ namespace ImageSharp.Tests
using (MemoryStream memStream = new MemoryStream())
{
image.SaveAsJpeg(memStream);
image.Dispose();
memStream.Position = 0;
return new Image(memStream);

2
tests/ImageSharp.Tests/Profiles/Exif/ExifTagDescriptionAttributeTests.cs

@ -10,7 +10,7 @@ namespace ImageSharp.Tests
public class ExifDescriptionAttributeTests
{
[Fact]
public void Test_ExifTag()
public void TestExifTag()
{
var exifProfile = new ExifProfile();

7
tests/ImageSharp.Tests/Profiles/Exif/ExifValueTests.cs

@ -12,9 +12,12 @@ namespace ImageSharp.Tests
{
private static ExifValue GetExifValue()
{
Image image = TestFile.Create(TestImages.Jpeg.Baseline.Floorplan).CreateImage();
ExifProfile profile;
using (Image image = TestFile.Create(TestImages.Jpeg.Baseline.Floorplan).CreateImage())
{
profile = image.ExifProfile;
}
ExifProfile profile = image.ExifProfile;
Assert.NotNull(profile);
return profile.Values.First();

Loading…
Cancel
Save