diff --git a/src/ImageSharp/Drawing/Brushes/ImageBrush.cs b/src/ImageSharp/Drawing/Brushes/ImageBrush.cs
new file mode 100644
index 0000000000..8ac4f43d29
--- /dev/null
+++ b/src/ImageSharp/Drawing/Brushes/ImageBrush.cs
@@ -0,0 +1,108 @@
+//
+// Copyright (c) James Jackson-South and contributors.
+// Licensed under the Apache License, Version 2.0.
+//
+
+namespace ImageSharp.Drawing.Brushes
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Numerics;
+ using System.Threading.Tasks;
+ using Processors;
+
+ ///
+ /// Provides an implementaion of a solid brush for painting with repeating images.
+ ///
+ public class ImageBrush : ImageBrush
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The color.
+ public ImageBrush(IImageBase image)
+ : base(image)
+ {
+ }
+ }
+
+ ///
+ /// Provides an implementaion of a solid brush for painting solid color areas.
+ ///
+ /// The type of the color.
+ /// The type of the packed.
+ public class ImageBrush : IBrush
+ where TColor : struct, IPackedPixel
+ where TPacked : struct
+ {
+ private readonly IImageBase image;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The color.
+ public ImageBrush(IImageBase image)
+ {
+ this.image = image;
+ }
+
+ ///
+ /// Creates the applicator for this brush.
+ ///
+ /// The region the brush will be applied to.
+ ///
+ /// The brush applicator for this brush
+ ///
+ ///
+ /// The when being applied to things like shapes would ussually be the
+ /// bounding box of the shape not necessarily the bounds of the whole image
+ ///
+ public IBrushApplicator CreateApplicator(RectangleF region)
+ {
+ return new ImageBrushApplicator(this.image, region);
+ }
+
+ private class ImageBrushApplicator : IBrushApplicator
+ {
+ private readonly PixelAccessor source;
+ private readonly int yLength;
+ private readonly int xLength;
+ private readonly Vector2 offset;
+ private readonly float YOffset;
+
+ public ImageBrushApplicator(IImageBase image, RectangleF region)
+ {
+ this.source = image.Lock();
+ this.xLength = image.Width;
+ this.yLength = image.Height;
+ this.offset = new Vector2((float)Math.Max(Math.Floor(region.Top), 0),
+ (float)Math.Max(Math.Floor(region.Left), 0));
+ }
+
+ ///
+ /// Gets the color for a single pixel.
+ ///
+ /// The point.
+ ///
+ /// The color
+ ///
+ public TColor GetColor(Vector2 point)
+ {
+ //offset the requested pixel by the value in the rectangle (the shapes position)
+ point = point - offset;
+ var x = (int)point.X % this.xLength;
+ var y = (int)point.Y % this.yLength;
+
+ return source[x, y];
+ }
+
+ ///
+ /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
+ ///
+ public void Dispose()
+ {
+ source.Dispose();
+ }
+ }
+ }
+}
diff --git a/tests/ImageSharp.Tests/Drawing/SolidPolygonTests.cs b/tests/ImageSharp.Tests/Drawing/SolidPolygonTests.cs
index 9903e699af..cc2e34accf 100644
--- a/tests/ImageSharp.Tests/Drawing/SolidPolygonTests.cs
+++ b/tests/ImageSharp.Tests/Drawing/SolidPolygonTests.cs
@@ -12,6 +12,7 @@ namespace ImageSharp.Tests.Drawing
using System.IO;
using System.Numerics;
using Xunit;
+ using ImageSharp.Drawing.Brushes;
public class SolidPolygonTests : FileTestBase
{
@@ -77,6 +78,28 @@ namespace ImageSharp.Tests.Drawing
}
}
+ [Fact]
+ public void ImageShouldBeOverlayedByFilledPolygon_Image()
+ {
+ string path = CreateOutputDirectory("Drawing", "FilledPolygons");
+ var simplePath = new[] {
+ new Vector2(10, 10),
+ new Vector2(200, 150),
+ new Vector2(50, 300)
+ };
+
+ var brush = new ImageBrush(Files[2].CreateImage());
+ var image = new Image(500, 500);
+
+ using (FileStream output = File.OpenWrite($"{path}/Image.png"))
+ {
+ image
+ .BackgroundColor(Color.Blue)
+ .FillPolygon(brush, simplePath)
+ .Save(output);
+ }
+ }
+
[Fact]
public void ImageShouldBeOverlayedByFilledPolygonOpacity()
{
@@ -87,7 +110,7 @@ namespace ImageSharp.Tests.Drawing
new Vector2(50, 300)
};
var 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"))