Browse Source

Replace .Lock() with .GetRootFramePixelBuffer()

af/merge-core
Anton Firszov 8 years ago
parent
commit
61e6d2d6e1
  1. 10
      src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs
  2. 4
      src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs
  3. 31
      src/ImageSharp/ImageExtensions.Internal.cs
  4. 15
      src/ImageSharp/ImageFrame{TPixel}.cs
  5. 48
      src/ImageSharp/PixelAccessorExtensions.cs
  6. 9
      src/ImageSharp/PixelAccessor{TPixel}.cs
  7. 46
      tests/ImageSharp.Benchmarks/Codecs/CopyPixels.cs
  8. 27
      tests/ImageSharp.Benchmarks/PixelBlenders/PorterDuffBulkVsPixel.cs
  9. 2
      tests/ImageSharp.Benchmarks/Samplers/Glow.cs
  10. 86
      tests/ImageSharp.Tests/Drawing/BeziersTests.cs
  11. 50
      tests/ImageSharp.Tests/Drawing/DrawPathTests.cs
  12. 41
      tests/ImageSharp.Tests/Drawing/FillPatternTests.cs
  13. 129
      tests/ImageSharp.Tests/Drawing/LineComplexPolygonTests.cs
  14. 106
      tests/ImageSharp.Tests/Drawing/LineTests.cs
  15. 69
      tests/ImageSharp.Tests/Drawing/PolygonTests.cs
  16. 47
      tests/ImageSharp.Tests/Drawing/SolidComplexPolygonTests.cs
  17. 88
      tests/ImageSharp.Tests/Drawing/SolidPolygonTests.cs
  18. 20
      tests/ImageSharp.Tests/Formats/Jpg/GenericBlock8x8Tests.cs
  19. 23
      tests/ImageSharp.Tests/TestUtilities/ImageProviders/TestPatternProvider.cs
  20. 47
      tests/ImageSharp.Tests/TestUtilities/TestUtils.cs
  21. 22
      tests/ImageSharp.Tests/TestUtilities/Tests/TestImageProviderTests.cs
  22. 19
      tests/ImageSharp.Tests/TestUtilities/Tests/TestUtilityExtensionsTests.cs

10
src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs

@ -208,7 +208,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp
/// Compresssed RLE8 stream is uncompressed by <see cref="UncompressRle8(int, Span{byte})"/>
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="pixels">The <see cref="PixelAccessor{TPixel}"/> to assign the palette to.</param>
/// <param name="pixels">The <see cref="Buffer2D{TPixel}"/> to assign the palette to.</param>
/// <param name="colors">The <see cref="T:byte[]"/> containing the colors.</param>
/// <param name="width">The width of the bitmap.</param>
/// <param name="height">The height of the bitmap.</param>
@ -319,7 +319,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp
/// Reads the color palette from the stream.
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="pixels">The <see cref="PixelAccessor{TPixel}"/> to assign the palette to.</param>
/// <param name="pixels">The <see cref="Buffer2D{TPixel}"/> to assign the palette to.</param>
/// <param name="colors">The <see cref="T:byte[]"/> containing the colors.</param>
/// <param name="width">The width of the bitmap.</param>
/// <param name="height">The height of the bitmap.</param>
@ -383,7 +383,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp
/// Reads the 16 bit color palette from the stream
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="pixels">The <see cref="PixelAccessor{TPixel}"/> to assign the palette to.</param>
/// <param name="pixels">The <see cref="Buffer2D{TPixel}"/> to assign the palette to.</param>
/// <param name="width">The width of the bitmap.</param>
/// <param name="height">The height of the bitmap.</param>
/// <param name="inverted">Whether the bitmap is inverted.</param>
@ -424,7 +424,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp
/// Reads the 24 bit color palette from the stream
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="pixels">The <see cref="PixelAccessor{TPixel}"/> to assign the palette to.</param>
/// <param name="pixels">The <see cref="Buffer2D{TPixel}"/> to assign the palette to.</param>
/// <param name="width">The width of the bitmap.</param>
/// <param name="height">The height of the bitmap.</param>
/// <param name="inverted">Whether the bitmap is inverted.</param>
@ -449,7 +449,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp
/// Reads the 32 bit color palette from the stream
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="pixels">The <see cref="PixelAccessor{TPixel}"/> to assign the palette to.</param>
/// <param name="pixels">The <see cref="Buffer2D{TPixel}"/> to assign the palette to.</param>
/// <param name="width">The width of the bitmap.</param>
/// <param name="height">The height of the bitmap.</param>
/// <param name="inverted">Whether the bitmap is inverted.</param>

4
src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs

@ -115,7 +115,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="stream">The <see cref="Stream"/> to write to.</param>
/// <param name="pixels">The <see cref="PixelAccessor{TPixel}"/> containing pixel data.</param>
/// <param name="pixels">The <see cref="Buffer2D{TPixel}"/> containing pixel data.</param>
private void Write32Bit<TPixel>(Stream stream, Buffer2D<TPixel> pixels)
where TPixel : struct, IPixel<TPixel>
{
@ -135,7 +135,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="stream">The <see cref="Stream"/> to write to.</param>
/// <param name="pixels">The <see cref="PixelAccessor{TPixel}"/> containing pixel data.</param>
/// <param name="pixels">The <see cref="Buffer2D{TPixel}"/> containing pixel data.</param>
private void Write24Bit<TPixel>(Stream stream, Buffer2D<TPixel> pixels)
where TPixel : struct, IPixel<TPixel>
{

31
src/ImageSharp/ImageExtensions.Internal.cs

@ -0,0 +1,31 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.Memory;
namespace SixLabors.ImageSharp
{
/// <content>
/// Contains internal extensions for <see cref="Image{TPixel}"/>
/// </content>
public static partial class ImageExtensions
{
/// <summary>
/// Locks the image providing access to the pixels.
/// <remarks>
/// It is imperative that the accessor is correctly disposed off after use.
/// </remarks>
/// </summary>
/// <typeparam name="TPixel">The type of the pixel.</typeparam>
/// <param name="image">The image.</param>
/// <returns>
/// The <see cref="Buffer2D{TPixel}" />
/// </returns>
internal static Buffer2D<TPixel> GetRootFramePixelBuffer<TPixel>(this Image<TPixel> image)
where TPixel : struct, IPixel<TPixel>
{
return image.Frames.RootFrame.PixelBuffer;
}
}
}

15
src/ImageSharp/ImageFrame{TPixel}.cs

@ -216,19 +216,10 @@ namespace SixLabors.ImageSharp
/// It is imperative that the accessor is correctly disposed off after use.
/// </remarks>
/// </summary>
/// <returns>The <see cref="PixelAccessor{TPixel}"/></returns>
internal PixelAccessor<TPixel> Lock()
/// <returns>The <see cref="Buffer2D{TPixel}"/></returns>
internal Buffer2D<TPixel> Lock()
{
return new PixelAccessor<TPixel>(this);
}
/// <summary>
/// Copies the pixels to a <see cref="PixelAccessor{TPixel}"/> of the same size.
/// </summary>
/// <param name="target">The target pixel buffer accessor.</param>
internal void CopyTo(PixelAccessor<TPixel> target)
{
this.CopyTo(target.PixelBuffer);
return this.PixelBuffer;
}
/// <summary>

48
src/ImageSharp/PixelAccessorExtensions.cs

@ -1,48 +0,0 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.PixelFormats;
namespace SixLabors.ImageSharp
{
/// <summary>
/// Helper methods fro acccess pixel accessors
/// </summary>
internal static class PixelAccessorExtensions
{
/// <summary>
/// Locks the image providing access to the pixels.
/// <remarks>
/// It is imperative that the accessor is correctly disposed off after use.
/// </remarks>
/// </summary>
/// <typeparam name="TPixel">The type of the pixel.</typeparam>
/// <param name="frame">The frame.</param>
/// <returns>
/// The <see cref="PixelAccessor{TPixel}" />
/// </returns>
internal static PixelAccessor<TPixel> Lock<TPixel>(this IPixelSource<TPixel> frame)
where TPixel : struct, IPixel<TPixel>
{
return new PixelAccessor<TPixel>(frame);
}
/// <summary>
/// Locks the image providing access to the pixels.
/// <remarks>
/// It is imperative that the accessor is correctly disposed off after use.
/// </remarks>
/// </summary>
/// <typeparam name="TPixel">The type of the pixel.</typeparam>
/// <param name="image">The image.</param>
/// <returns>
/// The <see cref="PixelAccessor{TPixel}" />
/// </returns>
internal static PixelAccessor<TPixel> Lock<TPixel>(this Image<TPixel> image)
where TPixel : struct, IPixel<TPixel>
{
return image.Frames.RootFrame.Lock();
}
}
}

9
src/ImageSharp/PixelAccessor{TPixel}.cs

@ -103,15 +103,6 @@ namespace SixLabors.ImageSharp
return oldPixels;
}
/// <summary>
/// Copies the pixels to another <see cref="PixelAccessor{TPixel}"/> of the same size.
/// </summary>
/// <param name="target">The target pixel buffer accessor.</param>
internal void CopyTo(PixelAccessor<TPixel> target)
{
this.PixelBuffer.GetSpan().CopyTo(target.PixelBuffer.GetSpan());
}
/// <summary>
/// Sets the pixel buffer in an unsafe manor this should not be used unless you know what its doing!!!
/// </summary>

46
tests/ImageSharp.Benchmarks/Codecs/CopyPixels.cs

@ -22,23 +22,21 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs
using (var source = new Image<Rgba32>(1024, 768))
using (var target = new Image<Rgba32>(1024, 768))
{
using (PixelAccessor<Rgba32> sourcePixels = source.Lock())
using (PixelAccessor<Rgba32> targetPixels = target.Lock())
{
Parallel.For(
0,
source.Height,
Configuration.Default.ParallelOptions,
y =>
Buffer2D<Rgba32> sourcePixels = source.GetRootFramePixelBuffer();
Buffer2D<Rgba32> targetPixels = target.GetRootFramePixelBuffer();
Parallel.For(
0,
source.Height,
Configuration.Default.ParallelOptions,
y =>
{
for (int x = 0; x < source.Width; x++)
{
for (int x = 0; x < source.Width; x++)
{
targetPixels[x, y] = sourcePixels[x, y];
}
});
targetPixels[x, y] = sourcePixels[x, y];
}
});
return targetPixels[0, 0];
}
return targetPixels[0, 0];
}
}
@ -48,14 +46,13 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs
using (var source = new Image<Rgba32>(1024, 768))
using (var target = new Image<Rgba32>(1024, 768))
{
using (PixelAccessor<Rgba32> sourcePixels = source.Lock())
using (PixelAccessor<Rgba32> targetPixels = target.Lock())
{
Parallel.For(
0,
source.Height,
Configuration.Default.ParallelOptions,
y =>
Buffer2D<Rgba32> sourcePixels = source.GetRootFramePixelBuffer();
Buffer2D<Rgba32> targetPixels = target.GetRootFramePixelBuffer();
Parallel.For(
0,
source.Height,
Configuration.Default.ParallelOptions,
y =>
{
Span<Rgba32> sourceRow = sourcePixels.GetRowSpan(y);
Span<Rgba32> targetRow = targetPixels.GetRowSpan(y);
@ -66,8 +63,7 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs
}
});
return targetPixels[0, 0];
}
return targetPixels[0, 0];
}
}

27
tests/ImageSharp.Benchmarks/PixelBlenders/PorterDuffBulkVsPixel.cs

@ -57,20 +57,19 @@ namespace SixLabors.ImageSharp.Benchmarks
[Benchmark(Description = "ImageSharp BulkVectorConvert")]
public CoreSize BulkVectorConvert()
{
using (Image<Rgba32> image = new Image<Rgba32>(800, 800))
using (var image = new Image<Rgba32>(800, 800))
{
using (IBuffer<float> amounts = Configuration.Default.MemoryAllocator.Allocate<float>(image.Width))
{
amounts.GetSpan().Fill(1);
using (PixelAccessor<Rgba32> pixels = image.Lock())
Buffer2D<Rgba32> pixels = image.GetRootFramePixelBuffer();
for (int y = 0; y < image.Height; y++)
{
for (int y = 0; y < image.Height; y++)
{
Span<Rgba32> span = pixels.GetRowSpan(y);
this.BulkVectorConvert(span, span, span, amounts.GetSpan());
}
Span<Rgba32> span = pixels.GetRowSpan(y);
this.BulkVectorConvert(span, span, span, amounts.GetSpan());
}
return new CoreSize(image.Width, image.Height);
}
}
@ -79,18 +78,16 @@ namespace SixLabors.ImageSharp.Benchmarks
[Benchmark(Description = "ImageSharp BulkPixelConvert")]
public CoreSize BulkPixelConvert()
{
using (Image<Rgba32> image = new Image<Rgba32>(800, 800))
using (var image = new Image<Rgba32>(800, 800))
{
using (IBuffer<float> amounts = Configuration.Default.MemoryAllocator.Allocate<float>(image.Width))
{
amounts.GetSpan().Fill(1);
using (PixelAccessor<Rgba32> pixels = image.Lock())
Buffer2D<Rgba32> pixels = image.GetRootFramePixelBuffer();
for (int y = 0; y < image.Height; y++)
{
for (int y = 0; y < image.Height; y++)
{
Span<Rgba32> span = pixels.GetRowSpan(y);
this.BulkPixelConvert(span, span, span, amounts.GetSpan());
}
Span<Rgba32> span = pixels.GetRowSpan(y);
this.BulkPixelConvert(span, span, span, amounts.GetSpan());
}
return new CoreSize(image.Width, image.Height);

2
tests/ImageSharp.Benchmarks/Samplers/Glow.cs

@ -103,7 +103,7 @@ namespace SixLabors.ImageSharp.Benchmarks
int width = maxX - minX;
using (IBuffer<TPixel> rowColors = Configuration.Default.MemoryAllocator.Allocate<TPixel>(width))
using (PixelAccessor<TPixel> sourcePixels = source.Lock())
using (Buffer2D<TPixel> sourcePixels = source.Lock())
{
rowColors.GetSpan().Fill(glowColor);

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

@ -11,6 +11,8 @@ using Xunit;
namespace SixLabors.ImageSharp.Tests.Drawing
{
using SixLabors.Memory;
public class Beziers : FileTestBase
{
[Fact]
@ -19,32 +21,30 @@ namespace SixLabors.ImageSharp.Tests.Drawing
string path = TestEnvironment.CreateOutputDirectory("Drawing", "BezierLine");
using (var image = new Image<Rgba32>(500, 500))
{
image.Mutate(x => x.BackgroundColor(Rgba32.Blue)
.DrawBeziers(Rgba32.HotPink, 5,
new SixLabors.Primitives.PointF[] {
new Vector2(10, 400),
new Vector2(30, 10),
new Vector2(240, 30),
new Vector2(300, 400)
}));
image.Mutate(
x => x.BackgroundColor(Rgba32.Blue).DrawBeziers(
Rgba32.HotPink,
5,
new SixLabors.Primitives.PointF[]
{
new Vector2(10, 400), new Vector2(30, 10), new Vector2(240, 30), new Vector2(300, 400)
}));
image.Save($"{path}/Simple.png");
using (PixelAccessor<Rgba32> sourcePixels = image.Lock())
{
//top of curve
Assert.Equal(Rgba32.HotPink, sourcePixels[138, 115]);
Buffer2D<Rgba32> sourcePixels = image.GetRootFramePixelBuffer();
//top of curve
Assert.Equal(Rgba32.HotPink, sourcePixels[138, 115]);
//start points
Assert.Equal(Rgba32.HotPink, sourcePixels[10, 395]);
Assert.Equal(Rgba32.HotPink, sourcePixels[300, 395]);
//start points
Assert.Equal(Rgba32.HotPink, sourcePixels[10, 395]);
Assert.Equal(Rgba32.HotPink, sourcePixels[300, 395]);
//curve points should not be never be set
Assert.Equal(Rgba32.Blue, sourcePixels[30, 10]);
Assert.Equal(Rgba32.Blue, sourcePixels[240, 30]);
//curve points should not be never be set
Assert.Equal(Rgba32.Blue, sourcePixels[30, 10]);
Assert.Equal(Rgba32.Blue, sourcePixels[240, 30]);
// inside shape should be empty
Assert.Equal(Rgba32.Blue, sourcePixels[200, 250]);
}
// inside shape should be empty
Assert.Equal(Rgba32.Blue, sourcePixels[200, 250]);
}
}
@ -58,36 +58,34 @@ namespace SixLabors.ImageSharp.Tests.Drawing
using (var image = new Image<Rgba32>(500, 500))
{
image.Mutate(x => x.BackgroundColor(Rgba32.Blue)
.DrawBeziers(color,
10,
new SixLabors.Primitives.PointF[]{
new Vector2(10, 400),
new Vector2(30, 10),
new Vector2(240, 30),
new Vector2(300, 400)
}));
image.Mutate(
x => x.BackgroundColor(Rgba32.Blue).DrawBeziers(
color,
10,
new SixLabors.Primitives.PointF[]
{
new Vector2(10, 400), new Vector2(30, 10), new Vector2(240, 30), new Vector2(300, 400)
}));
image.Save($"{path}/Opacity.png");
//shift background color towards foreground color by the opacity amount
var mergedColor = new Rgba32(Vector4.Lerp(Rgba32.Blue.ToVector4(), Rgba32.HotPink.ToVector4(), 150f / 255f));
var mergedColor = new Rgba32(
Vector4.Lerp(Rgba32.Blue.ToVector4(), Rgba32.HotPink.ToVector4(), 150f / 255f));
using (PixelAccessor<Rgba32> sourcePixels = image.Lock())
{
// top of curve
Assert.Equal(mergedColor, sourcePixels[138, 115]);
Buffer2D<Rgba32> sourcePixels = image.GetRootFramePixelBuffer();
// top of curve
Assert.Equal(mergedColor, sourcePixels[138, 115]);
// start points
Assert.Equal(mergedColor, sourcePixels[10, 395]);
Assert.Equal(mergedColor, sourcePixels[300, 395]);
// start points
Assert.Equal(mergedColor, sourcePixels[10, 395]);
Assert.Equal(mergedColor, sourcePixels[300, 395]);
// curve points should not be never be set
Assert.Equal(Rgba32.Blue, sourcePixels[30, 10]);
Assert.Equal(Rgba32.Blue, sourcePixels[240, 30]);
// curve points should not be never be set
Assert.Equal(Rgba32.Blue, sourcePixels[30, 10]);
Assert.Equal(Rgba32.Blue, sourcePixels[240, 30]);
// inside shape should be empty
Assert.Equal(Rgba32.Blue, sourcePixels[200, 250]);
}
// inside shape should be empty
Assert.Equal(Rgba32.Blue, sourcePixels[200, 250]);
}
}
}

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

@ -12,6 +12,8 @@ using Xunit;
namespace SixLabors.ImageSharp.Tests.Drawing
{
using SixLabors.Memory;
public class DrawPathTests : FileTestBase
{
[Fact]
@ -24,26 +26,23 @@ namespace SixLabors.ImageSharp.Tests.Drawing
new Vector2(10, 10),
new Vector2(200, 150),
new Vector2(50, 300));
var bazierSegment = new CubicBezierLineSegment(new Vector2(50, 300),
var bazierSegment = new CubicBezierLineSegment(
new Vector2(50, 300),
new Vector2(500, 500),
new Vector2(60, 10),
new Vector2(10, 400));
var p = new Path(linerSegemnt, bazierSegment);
image.Mutate(x => x
.BackgroundColor(Rgba32.Blue)
.Draw(Rgba32.HotPink, 5, p));
image.Mutate(x => x.BackgroundColor(Rgba32.Blue).Draw(Rgba32.HotPink, 5, p));
image.Save($"{path}/Simple.png");
using (PixelAccessor<Rgba32> sourcePixels = image.Lock())
{
Assert.Equal(Rgba32.HotPink, sourcePixels[11, 11]);
Buffer2D<Rgba32> sourcePixels = image.GetRootFramePixelBuffer();
Assert.Equal(Rgba32.HotPink, sourcePixels[11, 11]);
Assert.Equal(Rgba32.HotPink, sourcePixels[199, 149]);
Assert.Equal(Rgba32.HotPink, sourcePixels[199, 149]);
Assert.Equal(Rgba32.Blue, sourcePixels[50, 50]);
}
Assert.Equal(Rgba32.Blue, sourcePixels[50, 50]);
}
}
@ -71,22 +70,19 @@ namespace SixLabors.ImageSharp.Tests.Drawing
using (var image = new Image<Rgba32>(500, 500))
{
image.Mutate(x => x
.BackgroundColor(Rgba32.Blue)
.Draw(color, 10, p));
image.Mutate(x => x.BackgroundColor(Rgba32.Blue).Draw(color, 10, p));
image.Save($"{path}/Opacity.png");
//shift background color towards forground color by the opacity amount
var mergedColor = new Rgba32(Vector4.Lerp(Rgba32.Blue.ToVector4(), Rgba32.HotPink.ToVector4(), 150f / 255f));
var mergedColor = new Rgba32(
Vector4.Lerp(Rgba32.Blue.ToVector4(), Rgba32.HotPink.ToVector4(), 150f / 255f));
using (PixelAccessor<Rgba32> sourcePixels = image.Lock())
{
Assert.Equal(mergedColor, sourcePixels[11, 11]);
Buffer2D<Rgba32> sourcePixels = image.GetRootFramePixelBuffer();
Assert.Equal(mergedColor, sourcePixels[11, 11]);
Assert.Equal(mergedColor, sourcePixels[199, 149]);
Assert.Equal(mergedColor, sourcePixels[199, 149]);
Assert.Equal(Rgba32.Blue, sourcePixels[50, 50]);
}
Assert.Equal(Rgba32.Blue, sourcePixels[50, 50]);
}
}
@ -102,15 +98,15 @@ namespace SixLabors.ImageSharp.Tests.Drawing
for (int i = 0; i < 300; i += 20)
{
image.Mutate(x => x.DrawLines(pen, new SixLabors.Primitives.PointF[] { new Vector2(100, 2), new Vector2(-10, i) }));
image.Mutate(
x => x.DrawLines(
pen,
new SixLabors.Primitives.PointF[] { new Vector2(100, 2), new Vector2(-10, i) }));
}
image
.Save($"{path}/ClippedLines.png");
using (PixelAccessor<Rgba32> sourcePixels = image.Lock())
{
Assert.Equal(Rgba32.White, sourcePixels[0, 90]);
}
image.Save($"{path}/ClippedLines.png");
Buffer2D<Rgba32> sourcePixels = image.GetRootFramePixelBuffer();
Assert.Equal(Rgba32.White, sourcePixels[0, 90]);
}
}
}

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

@ -12,6 +12,8 @@ using Xunit;
namespace SixLabors.ImageSharp.Tests.Drawing
{
using SixLabors.Memory;
public class FillPatternBrushTests : FileTestBase
{
private void Test(string name, Rgba32 background, IBrush<Rgba32> brush, Rgba32[,] expectedPattern)
@ -19,36 +21,33 @@ namespace SixLabors.ImageSharp.Tests.Drawing
string path = TestEnvironment.CreateOutputDirectory("Fill", "PatternBrush");
using (var image = new Image<Rgba32>(20, 20))
{
image.Mutate(x => x
.Fill(background)
.Fill(brush));
image.Mutate(x => x.Fill(background).Fill(brush));
image.Save($"{path}/{name}.png");
using (PixelAccessor<Rgba32> sourcePixels = image.Lock())
Buffer2D<Rgba32> sourcePixels = image.GetRootFramePixelBuffer();
// lets pick random spots to start checking
var r = new Random();
var expectedPatternFast = new DenseMatrix<Rgba32>(expectedPattern);
int xStride = expectedPatternFast.Columns;
int yStride = expectedPatternFast.Rows;
int offsetX = r.Next(image.Width / xStride) * xStride;
int offsetY = r.Next(image.Height / yStride) * yStride;
for (int x = 0; x < xStride; x++)
{
// lets pick random spots to start checking
var r = new Random();
var expectedPatternFast = new DenseMatrix<Rgba32>(expectedPattern);
int xStride = expectedPatternFast.Columns;
int yStride = expectedPatternFast.Rows;
int offsetX = r.Next(image.Width / xStride) * xStride;
int offsetY = r.Next(image.Height / yStride) * yStride;
for (int x = 0; x < xStride; x++)
for (int y = 0; y < yStride; y++)
{
for (int y = 0; y < yStride; y++)
int actualX = x + offsetX;
int actualY = y + offsetY;
Rgba32 expected = expectedPatternFast[y, x]; // inverted pattern
Rgba32 actual = sourcePixels[actualX, actualY];
if (expected != actual)
{
int actualX = x + offsetX;
int actualY = y + offsetY;
Rgba32 expected = expectedPatternFast[y, x]; // inverted pattern
Rgba32 actual = sourcePixels[actualX, actualY];
if (expected != actual)
{
Assert.True(false, $"Expected {expected} but found {actual} at ({actualX},{actualY})");
}
Assert.True(false, $"Expected {expected} but found {actual} at ({actualX},{actualY})");
}
}
}
image.Mutate(x => x.Resize(80, 80));
image.Save($"{path}/{name}x4.png");
}

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

@ -13,6 +13,8 @@ using Xunit;
namespace SixLabors.ImageSharp.Tests.Drawing
{
using SixLabors.Memory;
public class LineComplexPolygonTests : FileTestBase
{
[Fact]
@ -32,34 +34,29 @@ namespace SixLabors.ImageSharp.Tests.Drawing
using (var image = new Image<Rgba32>(500, 500))
{
image.Mutate(x => x
.BackgroundColor(Rgba32.Blue)
.Draw(Rgba32.HotPink, 5, simplePath.Clip(hole1)));
image.Mutate(x => x.BackgroundColor(Rgba32.Blue).Draw(Rgba32.HotPink, 5, simplePath.Clip(hole1)));
image.Save($"{path}/Simple.png");
using (PixelAccessor<Rgba32> sourcePixels = image.Lock())
{
Assert.Equal(Rgba32.HotPink, sourcePixels[10, 10]);
Buffer2D<Rgba32> sourcePixels = image.GetRootFramePixelBuffer();
Assert.Equal(Rgba32.HotPink, sourcePixels[10, 10]);
Assert.Equal(Rgba32.HotPink, sourcePixels[200, 150]);
Assert.Equal(Rgba32.HotPink, sourcePixels[200, 150]);
Assert.Equal(Rgba32.HotPink, sourcePixels[50, 300]);
Assert.Equal(Rgba32.HotPink, sourcePixels[50, 300]);
Assert.Equal(Rgba32.HotPink, sourcePixels[37, 85]);
Assert.Equal(Rgba32.HotPink, sourcePixels[37, 85]);
Assert.Equal(Rgba32.HotPink, sourcePixels[93, 85]);
Assert.Equal(Rgba32.HotPink, sourcePixels[93, 85]);
Assert.Equal(Rgba32.HotPink, sourcePixels[65, 137]);
Assert.Equal(Rgba32.HotPink, sourcePixels[65, 137]);
Assert.Equal(Rgba32.Blue, sourcePixels[2, 2]);
Assert.Equal(Rgba32.Blue, sourcePixels[2, 2]);
//inside hole
Assert.Equal(Rgba32.Blue, sourcePixels[57, 99]);
//inside hole
Assert.Equal(Rgba32.Blue, sourcePixels[57, 99]);
//inside shape
Assert.Equal(Rgba32.Blue, sourcePixels[100, 192]);
}
//inside shape
Assert.Equal(Rgba32.Blue, sourcePixels[100, 192]);
}
}
@ -79,32 +76,27 @@ namespace SixLabors.ImageSharp.Tests.Drawing
using (var image = new Image<Rgba32>(500, 500))
{
image.Mutate(x => x
.BackgroundColor(Rgba32.Blue)
.Draw(Rgba32.HotPink, 5, simplePath.Clip(hole1)));
image.Mutate(x => x.BackgroundColor(Rgba32.Blue).Draw(Rgba32.HotPink, 5, simplePath.Clip(hole1)));
image.Save($"{path}/SimpleVanishHole.png");
using (PixelAccessor<Rgba32> sourcePixels = image.Lock())
{
Assert.Equal(Rgba32.HotPink, sourcePixels[10, 10]);
Assert.Equal(Rgba32.HotPink, sourcePixels[200, 150]);
Assert.Equal(Rgba32.HotPink, sourcePixels[50, 300]);
Buffer2D<Rgba32> sourcePixels = image.GetRootFramePixelBuffer();
Assert.Equal(Rgba32.HotPink, sourcePixels[10, 10]);
Assert.Equal(Rgba32.HotPink, sourcePixels[200, 150]);
Assert.Equal(Rgba32.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(Rgba32.Blue, sourcePixels[2, 2]);
Assert.Equal(Rgba32.Blue, sourcePixels[2, 2]);
//inside hole
Assert.Equal(Rgba32.Blue, sourcePixels[57, 99]);
//inside hole
Assert.Equal(Rgba32.Blue, sourcePixels[57, 99]);
//inside shape
Assert.Equal(Rgba32.Blue, sourcePixels[100, 192]);
}
//inside shape
Assert.Equal(Rgba32.Blue, sourcePixels[100, 192]);
}
}
@ -124,25 +116,21 @@ namespace SixLabors.ImageSharp.Tests.Drawing
using (var image = new Image<Rgba32>(500, 500))
{
image.Mutate(x => x
.BackgroundColor(Rgba32.Blue)
.Draw(Rgba32.HotPink, 5, simplePath.Clip(hole1)));
image.Mutate(x => x.BackgroundColor(Rgba32.Blue).Draw(Rgba32.HotPink, 5, simplePath.Clip(hole1)));
image.Save($"{path}/SimpleOverlapping.png");
using (PixelAccessor<Rgba32> sourcePixels = image.Lock())
{
Assert.Equal(Rgba32.HotPink, sourcePixels[10, 10]);
Assert.Equal(Rgba32.HotPink, sourcePixels[200, 150]);
Assert.Equal(Rgba32.HotPink, sourcePixels[50, 300]);
Assert.Equal(Rgba32.Blue, sourcePixels[130, 41]);
Assert.Equal(Rgba32.Blue, sourcePixels[2, 2]);
Buffer2D<Rgba32> sourcePixels = image.GetRootFramePixelBuffer();
Assert.Equal(Rgba32.HotPink, sourcePixels[10, 10]);
Assert.Equal(Rgba32.HotPink, sourcePixels[200, 150]);
Assert.Equal(Rgba32.HotPink, sourcePixels[50, 300]);
Assert.Equal(Rgba32.Blue, sourcePixels[130, 41]);
Assert.Equal(Rgba32.Blue, sourcePixels[2, 2]);
//inside hole
Assert.Equal(Rgba32.Blue, sourcePixels[57, 99]);
//inside hole
Assert.Equal(Rgba32.Blue, sourcePixels[57, 99]);
//inside shape
Assert.Equal(Rgba32.Blue, sourcePixels[100, 192]);
}
//inside shape
Assert.Equal(Rgba32.Blue, sourcePixels[100, 192]);
}
}
@ -186,30 +174,27 @@ namespace SixLabors.ImageSharp.Tests.Drawing
using (var image = new Image<Rgba32>(500, 500))
{
image.Mutate(x => x
.BackgroundColor(Rgba32.Blue)
.Draw(color, 5, simplePath.Clip(hole1)));
image.Mutate(x => x.BackgroundColor(Rgba32.Blue).Draw(color, 5, simplePath.Clip(hole1)));
image.Save($"{path}/Opacity.png");
//shift background color towards forground color by the opacity amount
var mergedColor = new Rgba32(Vector4.Lerp(Rgba32.Blue.ToVector4(), Rgba32.HotPink.ToVector4(), 150f / 255f));
using (PixelAccessor<Rgba32> sourcePixels = image.Lock())
{
Assert.Equal(mergedColor, sourcePixels[10, 10]);
Assert.Equal(mergedColor, sourcePixels[200, 150]);
Assert.Equal(mergedColor, sourcePixels[50, 300]);
Assert.Equal(mergedColor, sourcePixels[37, 85]);
Assert.Equal(mergedColor, sourcePixels[93, 85]);
Assert.Equal(mergedColor, sourcePixels[65, 137]);
Assert.Equal(Rgba32.Blue, sourcePixels[2, 2]);
//inside hole
Assert.Equal(Rgba32.Blue, sourcePixels[57, 99]);
//inside shape
Assert.Equal(Rgba32.Blue, sourcePixels[100, 192]);
}
var mergedColor = new Rgba32(
Vector4.Lerp(Rgba32.Blue.ToVector4(), Rgba32.HotPink.ToVector4(), 150f / 255f));
Buffer2D<Rgba32> sourcePixels = image.GetRootFramePixelBuffer();
Assert.Equal(mergedColor, sourcePixels[10, 10]);
Assert.Equal(mergedColor, sourcePixels[200, 150]);
Assert.Equal(mergedColor, sourcePixels[50, 300]);
Assert.Equal(mergedColor, sourcePixels[37, 85]);
Assert.Equal(mergedColor, sourcePixels[93, 85]);
Assert.Equal(mergedColor, sourcePixels[65, 137]);
Assert.Equal(Rgba32.Blue, sourcePixels[2, 2]);
//inside hole
Assert.Equal(Rgba32.Blue, sourcePixels[57, 99]);
//inside shape
Assert.Equal(Rgba32.Blue, sourcePixels[100, 192]);
}
}
}

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

@ -13,6 +13,8 @@ using Xunit;
namespace SixLabors.ImageSharp.Tests.Drawing
{
using SixLabors.Memory;
public class LineTests : FileTestBase
{
[Fact]
@ -21,24 +23,21 @@ namespace SixLabors.ImageSharp.Tests.Drawing
string path = TestEnvironment.CreateOutputDirectory("Drawing", "Lines");
using (var image = new Image<Rgba32>(500, 500))
{
image.Mutate(x => x
.BackgroundColor(Rgba32.Blue)
.DrawLines(Rgba32.HotPink, 5,
new SixLabors.Primitives.PointF[]{
new Vector2(10, 10),
new Vector2(200, 150),
new Vector2(50, 300)
}));
image.Mutate(
x => x.BackgroundColor(Rgba32.Blue).DrawLines(
Rgba32.HotPink,
5,
new Vector2(10, 10),
new Vector2(200, 150),
new Vector2(50, 300)));
image.Save($"{path}/Simple.png");
using (PixelAccessor<Rgba32> sourcePixels = image.Lock())
{
Assert.Equal(Rgba32.HotPink, sourcePixels[11, 11]);
Buffer2D<Rgba32> sourcePixels = image.GetRootFramePixelBuffer();
Assert.Equal(Rgba32.HotPink, sourcePixels[11, 11]);
Assert.Equal(Rgba32.HotPink, sourcePixels[199, 149]);
Assert.Equal(Rgba32.HotPink, sourcePixels[199, 149]);
Assert.Equal(Rgba32.Blue, sourcePixels[50, 50]);
}
Assert.Equal(Rgba32.Blue, sourcePixels[50, 50]);
}
}
@ -48,27 +47,22 @@ namespace SixLabors.ImageSharp.Tests.Drawing
string path = TestEnvironment.CreateOutputDirectory("Drawing", "Lines");
using (var image = new Image<Rgba32>(500, 500))
{
image.Mutate(x => x
.BackgroundColor(Rgba32.Blue)
.DrawLines(
image.Mutate(
x => x.BackgroundColor(Rgba32.Blue).DrawLines(
new GraphicsOptions(false),
Rgba32.HotPink,
5,
new SixLabors.Primitives.PointF[] {
new Vector2(10, 10),
new Vector2(200, 150),
new Vector2(50, 300)
}));
new Vector2(10, 10),
new Vector2(200, 150),
new Vector2(50, 300)));
image.Save($"{path}/Simple_noantialias.png");
using (PixelAccessor<Rgba32> sourcePixels = image.Lock())
{
Assert.Equal(Rgba32.HotPink, sourcePixels[11, 11]);
Buffer2D<Rgba32> sourcePixels = image.GetRootFramePixelBuffer();
Assert.Equal(Rgba32.HotPink, sourcePixels[11, 11]);
Assert.Equal(Rgba32.HotPink, sourcePixels[199, 149]);
Assert.Equal(Rgba32.HotPink, sourcePixels[199, 149]);
Assert.Equal(Rgba32.Blue, sourcePixels[50, 50]);
}
Assert.Equal(Rgba32.Blue, sourcePixels[50, 50]);
}
}
@ -151,26 +145,25 @@ namespace SixLabors.ImageSharp.Tests.Drawing
var image = new Image<Rgba32>(500, 500);
image.Mutate(x => x
.BackgroundColor(Rgba32.Blue)
.DrawLines(color, 10, new SixLabors.Primitives.PointF[] {
new Vector2(10, 10),
new Vector2(200, 150),
new Vector2(50, 300)
}));
image.Mutate(
x => x.BackgroundColor(Rgba32.Blue).DrawLines(
color,
10,
new Vector2(10, 10),
new Vector2(200, 150),
new Vector2(50, 300)));
image.Save($"{path}/Opacity.png");
//shift background color towards forground color by the opacity amount
var mergedColor = new Rgba32(Vector4.Lerp(Rgba32.Blue.ToVector4(), Rgba32.HotPink.ToVector4(), 150f / 255f));
var mergedColor =
new Rgba32(Vector4.Lerp(Rgba32.Blue.ToVector4(), Rgba32.HotPink.ToVector4(), 150f / 255f));
using (PixelAccessor<Rgba32> sourcePixels = image.Lock())
{
Assert.Equal(mergedColor, sourcePixels[11, 11]);
Buffer2D<Rgba32> sourcePixels = image.GetRootFramePixelBuffer();
Assert.Equal(mergedColor, sourcePixels[11, 11]);
Assert.Equal(mergedColor, sourcePixels[199, 149]);
Assert.Equal(mergedColor, sourcePixels[199, 149]);
Assert.Equal(Rgba32.Blue, sourcePixels[50, 50]);
}
Assert.Equal(Rgba32.Blue, sourcePixels[50, 50]);
}
[Fact]
@ -180,27 +173,24 @@ namespace SixLabors.ImageSharp.Tests.Drawing
var image = new Image<Rgba32>(500, 500);
image.Mutate(x => x
.BackgroundColor(Rgba32.Blue)
.DrawLines(Rgba32.HotPink, 10, new SixLabors.Primitives.PointF[] {
new Vector2(10, 10),
new Vector2(200, 10),
new Vector2(200, 150),
new Vector2(10, 150)
}));
image.Mutate(
x => x.BackgroundColor(Rgba32.Blue).DrawLines(
Rgba32.HotPink,
10,
new Vector2(10, 10),
new Vector2(200, 10),
new Vector2(200, 150),
new Vector2(10, 150)));
image.Save($"{path}/Rectangle.png");
using (PixelAccessor<Rgba32> sourcePixels = image.Lock())
{
Assert.Equal(Rgba32.HotPink, sourcePixels[11, 11]);
Buffer2D<Rgba32> sourcePixels = image.GetRootFramePixelBuffer();
Assert.Equal(Rgba32.HotPink, sourcePixels[11, 11]);
Assert.Equal(Rgba32.HotPink, sourcePixels[198, 10]);
Assert.Equal(Rgba32.HotPink, sourcePixels[198, 10]);
Assert.Equal(Rgba32.Blue, sourcePixels[10, 50]);
Assert.Equal(Rgba32.Blue, sourcePixels[10, 50]);
Assert.Equal(Rgba32.Blue, sourcePixels[50, 50]);
}
Assert.Equal(Rgba32.Blue, sourcePixels[50, 50]);
}
}
}

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

@ -12,6 +12,8 @@ using Xunit;
namespace SixLabors.ImageSharp.Tests.Drawing
{
using SixLabors.Memory;
public class PolygonTests : FileTestBase
{
[Fact]
@ -21,26 +23,23 @@ namespace SixLabors.ImageSharp.Tests.Drawing
using (Image<Rgba32> image = new Image<Rgba32>(500, 500))
{
image.Mutate(x => x
.BackgroundColor(Rgba32.Blue)
.DrawPolygon(Rgba32.HotPink, 5,
new SixLabors.Primitives.PointF[] {
new Vector2(10, 10),
new Vector2(200, 150),
new Vector2(50, 300)
}));
image.Mutate(
x => x.BackgroundColor(Rgba32.Blue).DrawPolygon(
Rgba32.HotPink,
5,
new Vector2(10, 10),
new Vector2(200, 150),
new Vector2(50, 300)));
image.Save($"{path}/Simple.png");
using (PixelAccessor<Rgba32> sourcePixels = image.Lock())
{
Assert.Equal(Rgba32.HotPink, sourcePixels[9, 9]);
Buffer2D<Rgba32> sourcePixels = image.GetRootFramePixelBuffer();
Assert.Equal(Rgba32.HotPink, sourcePixels[9, 9]);
Assert.Equal(Rgba32.HotPink, sourcePixels[199, 149]);
Assert.Equal(Rgba32.HotPink, sourcePixels[199, 149]);
Assert.Equal(Rgba32.Blue, sourcePixels[50, 50]);
Assert.Equal(Rgba32.Blue, sourcePixels[50, 50]);
Assert.Equal(Rgba32.Blue, sourcePixels[2, 2]);
}
Assert.Equal(Rgba32.Blue, sourcePixels[2, 2]);
}
}
@ -48,7 +47,7 @@ namespace SixLabors.ImageSharp.Tests.Drawing
public void ImageShouldBeOverlayedPolygonOutlineWithOpacity()
{
string path = TestEnvironment.CreateOutputDirectory("Drawing", "Polygons");
SixLabors.Primitives.PointF[] simplePath = new SixLabors.Primitives.PointF[] {
PointF[] simplePath = {
new Vector2(10, 10),
new Vector2(200, 150),
new Vector2(50, 300)
@ -58,24 +57,21 @@ namespace SixLabors.ImageSharp.Tests.Drawing
using (Image<Rgba32> image = new Image<Rgba32>(500, 500))
{
image.Mutate(x => x
.BackgroundColor(Rgba32.Blue)
.DrawPolygon(color, 10, simplePath));
image.Mutate(x => x.BackgroundColor(Rgba32.Blue).DrawPolygon(color, 10, simplePath));
image.Save($"{path}/Opacity.png");
//shift background color towards forground color by the opacity amount
Rgba32 mergedColor = new Rgba32(Vector4.Lerp(Rgba32.Blue.ToVector4(), Rgba32.HotPink.ToVector4(), 150f / 255f));
Rgba32 mergedColor = new Rgba32(
Vector4.Lerp(Rgba32.Blue.ToVector4(), Rgba32.HotPink.ToVector4(), 150f / 255f));
using (PixelAccessor<Rgba32> sourcePixels = image.Lock())
{
Assert.Equal(mergedColor, sourcePixels[9, 9]);
Buffer2D<Rgba32> sourcePixels = image.GetRootFramePixelBuffer();
Assert.Equal(mergedColor, sourcePixels[9, 9]);
Assert.Equal(mergedColor, sourcePixels[199, 149]);
Assert.Equal(mergedColor, sourcePixels[199, 149]);
Assert.Equal(Rgba32.Blue, sourcePixels[50, 50]);
Assert.Equal(Rgba32.Blue, sourcePixels[50, 50]);
Assert.Equal(Rgba32.Blue, sourcePixels[2, 2]);
}
Assert.Equal(Rgba32.Blue, sourcePixels[2, 2]);
}
}
@ -86,23 +82,20 @@ namespace SixLabors.ImageSharp.Tests.Drawing
using (Image<Rgba32> image = new Image<Rgba32>(500, 500))
{
image.Mutate(x => x
.BackgroundColor(Rgba32.Blue)
.Draw(Rgba32.HotPink, 10, new Rectangle(10, 10, 190, 140)));
image.Mutate(
x => x.BackgroundColor(Rgba32.Blue).Draw(Rgba32.HotPink, 10, new Rectangle(10, 10, 190, 140)));
image.Save($"{path}/Rectangle.png");
using (PixelAccessor<Rgba32> sourcePixels = image.Lock())
{
Assert.Equal(Rgba32.HotPink, sourcePixels[8, 8]);
Buffer2D<Rgba32> sourcePixels = image.GetRootFramePixelBuffer();
Assert.Equal(Rgba32.HotPink, sourcePixels[8, 8]);
Assert.Equal(Rgba32.HotPink, sourcePixels[198, 10]);
Assert.Equal(Rgba32.HotPink, sourcePixels[198, 10]);
Assert.Equal(Rgba32.HotPink, sourcePixels[10, 50]);
Assert.Equal(Rgba32.HotPink, sourcePixels[10, 50]);
Assert.Equal(Rgba32.Blue, sourcePixels[50, 50]);
Assert.Equal(Rgba32.Blue, sourcePixels[50, 50]);
Assert.Equal(Rgba32.Blue, sourcePixels[2, 2]);
}
Assert.Equal(Rgba32.Blue, sourcePixels[2, 2]);
}
}
}

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

@ -13,6 +13,8 @@ using Xunit;
namespace SixLabors.ImageSharp.Tests.Drawing
{
using SixLabors.Memory;
public class SolidComplexPolygonTests : FileTestBase
{
[Fact]
@ -32,18 +34,14 @@ namespace SixLabors.ImageSharp.Tests.Drawing
// var clipped = new Rectangle(10, 10, 100, 100).Clip(new Rectangle(20, 0, 20, 20));
using (var image = new Image<Rgba32>(500, 500))
{
image.Mutate(x => x
.BackgroundColor(Rgba32.Blue)
.Fill(Rgba32.HotPink, clipped));
image.Mutate(x => x.BackgroundColor(Rgba32.Blue).Fill(Rgba32.HotPink, clipped));
image.Save($"{path}/Simple.png");
using (PixelAccessor<Rgba32> sourcePixels = image.Lock())
{
Assert.Equal(Rgba32.HotPink, sourcePixels[20, 35]);
Buffer2D<Rgba32> sourcePixels = image.GetRootFramePixelBuffer();
Assert.Equal(Rgba32.HotPink, sourcePixels[20, 35]);
//inside hole
Assert.Equal(Rgba32.Blue, sourcePixels[60, 100]);
}
//inside hole
Assert.Equal(Rgba32.Blue, sourcePixels[60, 100]);
}
}
@ -64,18 +62,14 @@ namespace SixLabors.ImageSharp.Tests.Drawing
using (var image = new Image<Rgba32>(500, 500))
{
image.Mutate(x => x
.BackgroundColor(Rgba32.Blue)
.Fill(Rgba32.HotPink, simplePath.Clip(hole1)));
image.Mutate(x => x.BackgroundColor(Rgba32.Blue).Fill(Rgba32.HotPink, simplePath.Clip(hole1)));
image.Save($"{path}/SimpleOverlapping.png");
using (PixelAccessor<Rgba32> sourcePixels = image.Lock())
{
Assert.Equal(Rgba32.HotPink, sourcePixels[20, 35]);
Buffer2D<Rgba32> sourcePixels = image.GetRootFramePixelBuffer();
Assert.Equal(Rgba32.HotPink, sourcePixels[20, 35]);
//inside hole
Assert.Equal(Rgba32.Blue, sourcePixels[60, 100]);
}
//inside hole
Assert.Equal(Rgba32.Blue, sourcePixels[60, 100]);
}
}
@ -97,21 +91,18 @@ namespace SixLabors.ImageSharp.Tests.Drawing
using (var image = new Image<Rgba32>(500, 500))
{
image.Mutate(x => x
.BackgroundColor(Rgba32.Blue)
.Fill(color, simplePath.Clip(hole1)));
image.Mutate(x => x.BackgroundColor(Rgba32.Blue).Fill(color, simplePath.Clip(hole1)));
image.Save($"{path}/Opacity.png");
//shift background color towards forground color by the opacity amount
var mergedColor = new Rgba32(Vector4.Lerp(Rgba32.Blue.ToVector4(), Rgba32.HotPink.ToVector4(), 150f / 255f));
var mergedColor = new Rgba32(
Vector4.Lerp(Rgba32.Blue.ToVector4(), Rgba32.HotPink.ToVector4(), 150f / 255f));
using (PixelAccessor<Rgba32> sourcePixels = image.Lock())
{
Assert.Equal(mergedColor, sourcePixels[20, 35]);
Buffer2D<Rgba32> sourcePixels = image.GetRootFramePixelBuffer();
Assert.Equal(mergedColor, sourcePixels[20, 35]);
//inside hole
Assert.Equal(Rgba32.Blue, sourcePixels[60, 100]);
}
//inside hole
Assert.Equal(Rgba32.Blue, sourcePixels[60, 100]);
}
}
}

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

@ -15,6 +15,8 @@ using Xunit;
namespace SixLabors.ImageSharp.Tests.Drawing
{
using SixLabors.Memory;
public class SolidPolygonTests : FileTestBase
{
[Fact]
@ -29,14 +31,11 @@ namespace SixLabors.ImageSharp.Tests.Drawing
using (var image = new Image<Rgba32>(500, 500))
{
image.Mutate(x => x
.FillPolygon(new GraphicsOptions(true), Rgba32.HotPink, simplePath));
image.Mutate(x => x.FillPolygon(new GraphicsOptions(true), Rgba32.HotPink, simplePath));
image.Save($"{path}/Simple.png");
using (PixelAccessor<Rgba32> sourcePixels = image.Lock())
{
Assert.Equal(Rgba32.HotPink, sourcePixels[81, 145]);
}
Buffer2D<Rgba32> sourcePixels = image.GetRootFramePixelBuffer();
Assert.Equal(Rgba32.HotPink, sourcePixels[81, 145]);
}
}
@ -52,14 +51,12 @@ namespace SixLabors.ImageSharp.Tests.Drawing
using (var image = new Image<Rgba32>(500, 500))
{
image.Mutate(x => x
.FillPolygon(new GraphicsOptions(true), Brushes.Horizontal(Rgba32.HotPink), simplePath));
image.Mutate(
x => x.FillPolygon(new GraphicsOptions(true), Brushes.Horizontal(Rgba32.HotPink), simplePath));
image.Save($"{path}/Pattern.png");
using (PixelAccessor<Rgba32> sourcePixels = image.Lock())
{
Assert.Equal(Rgba32.HotPink, sourcePixels[81, 145]);
}
Buffer2D<Rgba32> sourcePixels = image.GetRootFramePixelBuffer();
Assert.Equal(Rgba32.HotPink, sourcePixels[81, 145]);
}
}
@ -75,21 +72,21 @@ namespace SixLabors.ImageSharp.Tests.Drawing
using (var image = new Image<Rgba32>(500, 500))
{
image.Mutate(x => x
.BackgroundColor(Rgba32.Blue)
.FillPolygon(new GraphicsOptions(false), Rgba32.HotPink, simplePath));
image.Mutate(
x => x.BackgroundColor(Rgba32.Blue).FillPolygon(
new GraphicsOptions(false),
Rgba32.HotPink,
simplePath));
image.Save($"{path}/Simple_NoAntialias.png");
using (PixelAccessor<Rgba32> sourcePixels = image.Lock())
{
Assert.True(Rgba32.HotPink == sourcePixels[11, 11], "[11, 11] wrong");
Buffer2D<Rgba32> sourcePixels = image.GetRootFramePixelBuffer();
Assert.True(Rgba32.HotPink == sourcePixels[11, 11], "[11, 11] wrong");
Assert.True(Rgba32.HotPink == sourcePixels[199, 149], "[199, 149] wrong");
Assert.True(Rgba32.HotPink == sourcePixels[199, 149], "[199, 149] wrong");
Assert.True(Rgba32.HotPink == sourcePixels[50, 50], "[50, 50] wrong");
Assert.True(Rgba32.HotPink == sourcePixels[50, 50], "[50, 50] wrong");
Assert.True(Rgba32.Blue == sourcePixels[2, 2], "[2, 2] wrong");
}
Assert.True(Rgba32.Blue == sourcePixels[2, 2], "[2, 2] wrong");
}
}
@ -128,18 +125,15 @@ namespace SixLabors.ImageSharp.Tests.Drawing
using (var image = new Image<Rgba32>(500, 500))
{
image.Mutate(x => x
.BackgroundColor(Rgba32.Blue)
.FillPolygon(color, simplePath));
image.Mutate(x => x.BackgroundColor(Rgba32.Blue).FillPolygon(color, simplePath));
image.Save($"{path}/Opacity.png");
//shift background color towards forground color by the opacity amount
var mergedColor = new Rgba32(Vector4.Lerp(Rgba32.Blue.ToVector4(), Rgba32.HotPink.ToVector4(), 150f / 255f));
var mergedColor = new Rgba32(
Vector4.Lerp(Rgba32.Blue.ToVector4(), Rgba32.HotPink.ToVector4(), 150f / 255f));
using (PixelAccessor<Rgba32> sourcePixels = image.Lock())
{
Assert.Equal(Rgba32.Blue, sourcePixels[2, 2]);
}
Buffer2D<Rgba32> sourcePixels = image.GetRootFramePixelBuffer();
Assert.Equal(Rgba32.Blue, sourcePixels[2, 2]);
}
}
@ -150,23 +144,22 @@ namespace SixLabors.ImageSharp.Tests.Drawing
using (var image = new Image<Rgba32>(500, 500))
{
image.Mutate(x => x
.BackgroundColor(Rgba32.Blue)
.Fill(Rgba32.HotPink, new SixLabors.Shapes.RectangularPolygon(10, 10, 190, 140)));
image.Mutate(
x => x.BackgroundColor(Rgba32.Blue).Fill(
Rgba32.HotPink,
new SixLabors.Shapes.RectangularPolygon(10, 10, 190, 140)));
image.Save($"{path}/Rectangle.png");
using (PixelAccessor<Rgba32> sourcePixels = image.Lock())
{
Assert.Equal(Rgba32.HotPink, sourcePixels[11, 11]);
Buffer2D<Rgba32> sourcePixels = image.GetRootFramePixelBuffer();
Assert.Equal(Rgba32.HotPink, sourcePixels[11, 11]);
Assert.Equal(Rgba32.HotPink, sourcePixels[198, 10]);
Assert.Equal(Rgba32.HotPink, sourcePixels[198, 10]);
Assert.Equal(Rgba32.HotPink, sourcePixels[10, 50]);
Assert.Equal(Rgba32.HotPink, sourcePixels[10, 50]);
Assert.Equal(Rgba32.HotPink, sourcePixels[50, 50]);
Assert.Equal(Rgba32.HotPink, sourcePixels[50, 50]);
Assert.Equal(Rgba32.Blue, sourcePixels[2, 2]);
}
Assert.Equal(Rgba32.Blue, sourcePixels[2, 2]);
}
}
@ -177,17 +170,14 @@ namespace SixLabors.ImageSharp.Tests.Drawing
using (var image = new Image<Rgba32>(100, 100))
{
image.Mutate(x => x
.BackgroundColor(Rgba32.Blue)
.Fill(Rgba32.HotPink, new RegularPolygon(50, 50, 3, 30)));
image.Mutate(
x => x.BackgroundColor(Rgba32.Blue).Fill(Rgba32.HotPink, new RegularPolygon(50, 50, 3, 30)));
image.Save($"{path}/Triangle.png");
using (PixelAccessor<Rgba32> sourcePixels = image.Lock())
{
Assert.Equal(Rgba32.Blue, sourcePixels[30, 65]);
Buffer2D<Rgba32> sourcePixels = image.GetRootFramePixelBuffer();
Assert.Equal(Rgba32.Blue, sourcePixels[30, 65]);
Assert.Equal(Rgba32.HotPink, sourcePixels[50, 50]);
}
Assert.Equal(Rgba32.HotPink, sourcePixels[50, 50]);
}
}

20
tests/ImageSharp.Tests/Formats/Jpg/GenericBlock8x8Tests.cs

@ -10,24 +10,24 @@ using Xunit;
namespace SixLabors.ImageSharp.Tests.Formats.Jpg
{
using SixLabors.Memory;
public class GenericBlock8x8Tests
{
public static Image<TPixel> CreateTestImage<TPixel>()
where TPixel : struct, IPixel<TPixel>
{
var image = new Image<TPixel>(10, 10);
using (PixelAccessor<TPixel> pixels = image.Lock())
Buffer2D<TPixel> pixels = image.GetRootFramePixelBuffer();
for (int i = 0; i < 10; i++)
{
for (int i = 0; i < 10; i++)
for (int j = 0; j < 10; j++)
{
for (int j = 0; j < 10; j++)
{
var rgba = new Rgba32((byte)(i + 1), (byte)(j + 1), (byte)200, (byte)255);
var color = default(TPixel);
color.PackFromRgba32(rgba);
pixels[i, j] = color;
}
var rgba = new Rgba32((byte)(i + 1), (byte)(j + 1), (byte)200, (byte)255);
var color = default(TPixel);
color.PackFromRgba32(rgba);
pixels[i, j] = color;
}
}

23
tests/ImageSharp.Tests/TestUtilities/ImageProviders/TestPatternProvider.cs

@ -9,6 +9,8 @@ using SixLabors.ImageSharp.PixelFormats;
namespace SixLabors.ImageSharp.Tests
{
using SixLabors.Memory;
public abstract partial class TestImageProvider<TPixel>
where TPixel : struct, IPixel<TPixel>
{
@ -54,19 +56,18 @@ namespace SixLabors.ImageSharp.Tests
private static void DrawTestPattern(Image<TPixel> image)
{
// first lets split the image into 4 quadrants
using (PixelAccessor<TPixel> pixels = image.Lock())
{
BlackWhiteChecker(pixels); // top left
VerticalBars(pixels); // top right
TransparentGradients(pixels); // bottom left
Rainbow(pixels); // bottom right
}
Buffer2D<TPixel> pixels = image.GetRootFramePixelBuffer();
BlackWhiteChecker(pixels); // top left
VerticalBars(pixels); // top right
TransparentGradients(pixels); // bottom left
Rainbow(pixels); // bottom right
}
/// <summary>
/// Fills the top right quadrant with alternating solid vertical bars.
/// </summary>
/// <param name="pixels"></param>
private static void VerticalBars(PixelAccessor<TPixel> pixels)
private static void VerticalBars(Buffer2D<TPixel> pixels)
{
// topLeft
int left = pixels.Width / 2;
@ -103,7 +104,7 @@ namespace SixLabors.ImageSharp.Tests
/// fills the top left quadrant with a black and white checker board.
/// </summary>
/// <param name="pixels"></param>
private static void BlackWhiteChecker(PixelAccessor<TPixel> pixels)
private static void BlackWhiteChecker(Buffer2D<TPixel> pixels)
{
// topLeft
int left = 0;
@ -142,7 +143,7 @@ namespace SixLabors.ImageSharp.Tests
/// Fills the bottom left quadrent with 3 horizental bars in Red, Green and Blue with a alpha gradient from left (transparent) to right (solid).
/// </summary>
/// <param name="pixels"></param>
private static void TransparentGradients(PixelAccessor<TPixel> pixels)
private static void TransparentGradients(Buffer2D<TPixel> pixels)
{
// topLeft
int left = 0;
@ -187,7 +188,7 @@ namespace SixLabors.ImageSharp.Tests
/// A better algorithm could be used but it works
/// </summary>
/// <param name="pixels"></param>
private static void Rainbow(PixelAccessor<TPixel> pixels)
private static void Rainbow(Buffer2D<TPixel> pixels)
{
int left = pixels.Width / 2;
int right = pixels.Width;

47
tests/ImageSharp.Tests/TestUtilities/TestUtils.cs

@ -15,6 +15,7 @@ using SixLabors.Primitives;
namespace SixLabors.ImageSharp.Tests
{
using SixLabors.ImageSharp.Advanced;
using SixLabors.Memory;
/// <summary>
/// Various utility and extension methods.
@ -63,36 +64,30 @@ namespace SixLabors.ImageSharp.Tests
var rgb1 = default(Rgb24);
var rgb2 = default(Rgb24);
using (PixelAccessor<TPixel> pixA = a.Lock())
Buffer2D<TPixel> pixA = a.GetRootFramePixelBuffer();
Buffer2D<TPixel> pixB = b.GetRootFramePixelBuffer();
for (int y = 0; y < a.Height; y++)
{
using (PixelAccessor<TPixel> pixB = b.Lock())
for (int x = 0; x < a.Width; x++)
{
for (int y = 0; y < a.Height; y++)
TPixel ca = pixA[x, y];
TPixel cb = pixB[x, y];
if (compareAlpha)
{
if (!ca.Equals(cb))
{
return false;
}
}
else
{
for (int x = 0; x < a.Width; x++)
ca.ToRgb24(ref rgb1);
cb.ToRgb24(ref rgb2);
if (rgb1.R != rgb2.R || rgb1.G != rgb2.G || rgb1.B != rgb2.B)
{
TPixel ca = pixA[x, y];
TPixel cb = pixB[x, y];
if (compareAlpha)
{
if (!ca.Equals(cb))
{
return false;
}
}
else
{
ca.ToRgb24(ref rgb1);
cb.ToRgb24(ref rgb2);
if (rgb1.R != rgb2.R ||
rgb1.G != rgb2.G ||
rgb1.B != rgb2.B)
{
return false;
}
}
return false;
}
}
}

22
tests/ImageSharp.Tests/TestUtilities/Tests/TestImageProviderTests.cs

@ -13,6 +13,8 @@ using SixLabors.ImageSharp.Formats;
namespace SixLabors.ImageSharp.Tests
{
using SixLabors.Memory;
public class TestImageProviderTests
{
public TestImageProviderTests(ITestOutputHelper output)
@ -282,19 +284,17 @@ namespace SixLabors.ImageSharp.Tests
var rgba = default(Rgba32);
using (PixelAccessor<TPixel> pixels = img.Lock())
Buffer2D<TPixel> pixels = img.GetRootFramePixelBuffer();
for (int y = 0; y < pixels.Height; y++)
{
for (int y = 0; y < pixels.Height; y++)
for (int x = 0; x < pixels.Width; x++)
{
for (int x = 0; x < pixels.Width; x++)
{
pixels[x, y].ToRgba32(ref rgba);
Assert.Equal(255, rgba.R);
Assert.Equal(100, rgba.G);
Assert.Equal(50, rgba.B);
Assert.Equal(200, rgba.A);
}
pixels[x, y].ToRgba32(ref rgba);
Assert.Equal(255, rgba.R);
Assert.Equal(100, rgba.G);
Assert.Equal(50, rgba.B);
Assert.Equal(200, rgba.A);
}
}
}

19
tests/ImageSharp.Tests/TestUtilities/Tests/TestUtilityExtensionsTests.cs

@ -14,6 +14,7 @@ using Xunit.Abstractions;
namespace SixLabors.ImageSharp.Tests
{
using SixLabors.ImageSharp.Processing.Effects;
using SixLabors.Memory;
public class TestUtilityExtensionsTests
{
@ -29,20 +30,18 @@ namespace SixLabors.ImageSharp.Tests
{
var image = new Image<TPixel>(10, 10);
using (PixelAccessor<TPixel> pixels = image.Lock())
Buffer2D<TPixel> pixels = image.GetRootFramePixelBuffer();
for (int i = 0; i < 10; i++)
{
for (int i = 0; i < 10; i++)
for (int j = 0; j < 10; j++)
{
for (int j = 0; j < 10; j++)
{
var v = new Vector4(i, j, 0, 1);
v /= 10;
var v = new Vector4(i, j, 0, 1);
v /= 10;
var color = default(TPixel);
color.PackFromVector4(v);
var color = default(TPixel);
color.PackFromVector4(v);
pixels[i, j] = color;
}
pixels[i, j] = color;
}
}

Loading…
Cancel
Save