Skip to content

Commit

Permalink
Merge pull request #306 from SixLabors/js/fix-305
Browse files Browse the repository at this point in the history
Expose ImageBrush source region constructor.
  • Loading branch information
JimBobSquarePants authored Dec 6, 2023
2 parents 2316146 + 3ee51ef commit ec146c9
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 14 deletions.
13 changes: 5 additions & 8 deletions src/ImageSharp.Drawing/Processing/ImageBrush.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public class ImageBrush : Brush
/// <summary>
/// Initializes a new instance of the <see cref="ImageBrush"/> class.
/// </summary>
/// <param name="image">The image.</param>
/// <param name="image">The source image to draw.</param>
public ImageBrush(Image image)
: this(image, image.Bounds)
{
Expand All @@ -33,15 +33,12 @@ public ImageBrush(Image image)
/// <summary>
/// Initializes a new instance of the <see cref="ImageBrush"/> class.
/// </summary>
/// <param name="image">The image.</param>
/// <param name="region">
/// The region of interest.
/// This overrides any region used to initialize the brush applicator.
/// </param>
internal ImageBrush(Image image, RectangleF region)
/// <param name="image">The source image.</param>
/// <param name="region">The region of interest within the source image to draw.</param>
public ImageBrush(Image image, RectangleF region)
{
this.image = image;
this.region = region;
this.region = RectangleF.Intersect(image.Bounds, region);
}

/// <inheritdoc />
Expand Down
63 changes: 57 additions & 6 deletions tests/ImageSharp.Drawing.Tests/Drawing/FillImageBrushTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ public class FillImageBrushTests
[Fact]
public void DoesNotDisposeImage()
{
using (var src = new Image<Rgba32>(5, 5))
using (Image<Rgba32> src = new(5, 5))
{
var brush = new ImageBrush(src);
using (var dest = new Image<Rgba32>(10, 10))
ImageBrush brush = new(src);
using (Image<Rgba32> dest = new(10, 10))
{
dest.Mutate(c => c.Fill(brush, new Rectangle(0, 0, 10, 10)));
dest.Mutate(c => c.Fill(brush, new Rectangle(0, 0, 10, 10)));
Expand All @@ -36,7 +36,7 @@ public void UseBrushOfDifferentPixelType<TPixel>(TestImageProvider<TPixel> provi
? Image.Load<Bgra32>(data)
: Image.Load<Rgba32>(data);

var brush = new ImageBrush(overlay);
ImageBrush brush = new(overlay);
background.Mutate(c => c.Fill(brush));

background.DebugSave(provider, appendSourceFileOrDescription: false);
Expand All @@ -54,7 +54,7 @@ public void CanDrawLandscapeImage<TPixel>(TestImageProvider<TPixel> provider)

overlay.Mutate(c => c.Crop(new Rectangle(0, 0, 125, 90)));

var brush = new ImageBrush(overlay);
ImageBrush brush = new(overlay);
background.Mutate(c => c.Fill(brush));

background.DebugSave(provider, appendSourceFileOrDescription: false);
Expand All @@ -72,10 +72,61 @@ public void CanDrawPortraitImage<TPixel>(TestImageProvider<TPixel> provider)

overlay.Mutate(c => c.Crop(new Rectangle(0, 0, 90, 125)));

var brush = new ImageBrush(overlay);
ImageBrush brush = new(overlay);
background.Mutate(c => c.Fill(brush));

background.DebugSave(provider, appendSourceFileOrDescription: false);
background.CompareToReferenceOutput(provider, appendSourceFileOrDescription: false);
}

[Theory]
[WithSolidFilledImages(1000, 1000, "White", PixelTypes.Rgba32)]
public void CanDrawNegativeOffsetImage<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel>
{
byte[] data = TestFile.Create(TestImages.Png.Ducky).Bytes;
using Image<TPixel> background = provider.GetImage();
using Image overlay = Image.Load<Rgba32>(data);

overlay.Mutate(c => c.Resize(100, 100));

ImageBrush halfBrush = new(overlay, new RectangleF(50, 0, 50, 100));
ImageBrush fullBrush = new(overlay);
background.Mutate(c => DrawFull(c, new Size(100, 100), fullBrush, halfBrush, background.Width, background.Height));

background.DebugSave(provider, appendSourceFileOrDescription: false);
background.CompareToReferenceOutput(provider, appendSourceFileOrDescription: false);
}

private static void DrawFull(IImageProcessingContext ctx, Size size, ImageBrush brush, ImageBrush halfBrush, int width, int height)
{
int j = 0;
while (j < height)
{
bool half = false;
int limitWidth = width;
int i = 0;
if ((j / size.Height) % 2 != 0)
{
half = true;
}

while (i < limitWidth)
{
if (half)
{
ctx.Fill(halfBrush, new RectangleF(i, j, size.Width / 2f, size.Height));
i += (int)(size.Width / 2f);
half = false;
}
else
{
ctx.Fill(brush, new RectangleF(new PointF(i, j), size));
i += size.Width;
}
}

j += size.Height;
}
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit ec146c9

Please sign in to comment.