diff --git a/src/ImageSharp.Drawing/Processors/DrawImageProcessor.cs b/src/ImageSharp.Drawing/Processors/DrawImageProcessor.cs
index 213ab1b4a..47763c0aa 100644
--- a/src/ImageSharp.Drawing/Processors/DrawImageProcessor.cs
+++ b/src/ImageSharp.Drawing/Processors/DrawImageProcessor.cs
@@ -2,7 +2,6 @@
// Licensed under the Apache License, Version 2.0.
using System;
-using System.Numerics;
using System.Threading.Tasks;
using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.Helpers;
@@ -42,7 +41,7 @@ namespace SixLabors.ImageSharp.Drawing.Processors
///
/// Gets the image to blend.
///
- public Image Image { get; private set; }
+ public Image Image { get; }
///
/// Gets the alpha percentage value.
@@ -73,10 +72,11 @@ namespace SixLabors.ImageSharp.Drawing.Processors
}
// Align start/end positions.
- Rectangle bounds = this.Image.Bounds();
+ Rectangle bounds = targetImage.Bounds();
int minX = Math.Max(this.Location.X, sourceRectangle.X);
int maxX = Math.Min(this.Location.X + bounds.Width, sourceRectangle.Width);
maxX = Math.Min(this.Location.X + this.Size.Width, maxX);
+ int targetX = minX - this.Location.X;
int minY = Math.Max(this.Location.Y, sourceRectangle.Y);
int maxY = Math.Min(this.Location.Y + bounds.Height, sourceRectangle.Bottom);
@@ -84,9 +84,7 @@ namespace SixLabors.ImageSharp.Drawing.Processors
maxY = Math.Min(this.Location.Y + this.Size.Height, maxY);
int width = maxX - minX;
- using (Buffer amount = new Buffer(width))
- using (PixelAccessor toBlendPixels = targetImage.Lock())
- using (PixelAccessor sourcePixels = source.Lock())
+ using (var amount = new Buffer(width))
{
for (int i = 0; i < width; i++)
{
@@ -99,8 +97,8 @@ namespace SixLabors.ImageSharp.Drawing.Processors
configuration.ParallelOptions,
y =>
{
- Span background = sourcePixels.GetRowSpan(y).Slice(minX, width);
- Span foreground = toBlendPixels.GetRowSpan(y - this.Location.Y).Slice(0, width);
+ Span background = source.GetPixelRowSpan(y).Slice(minX, width);
+ Span foreground = targetImage.GetPixelRowSpan(y - this.Location.Y).Slice(targetX, width);
this.blender.Blend(background, background, foreground, amount);
});
}
diff --git a/tests/ImageSharp.Tests/Drawing/DrawImageTest.cs b/tests/ImageSharp.Tests/Drawing/DrawImageTest.cs
index 94dd903b4..2e3a730fc 100644
--- a/tests/ImageSharp.Tests/Drawing/DrawImageTest.cs
+++ b/tests/ImageSharp.Tests/Drawing/DrawImageTest.cs
@@ -9,6 +9,8 @@ using Xunit;
namespace SixLabors.ImageSharp.Tests
{
+ using System;
+
public class DrawImageTest : FileTestBase
{
private const PixelTypes PixelTypes = Tests.PixelTypes.Rgba32;
@@ -42,5 +44,49 @@ namespace SixLabors.ImageSharp.Tests
image.DebugSave(provider, new { mode });
}
}
+
+ [Theory]
+ [WithSolidFilledImages(100, 100, 255, 255, 255, PixelTypes.Rgba32)]
+ public void ImageShouldHandleNegativeLocation(TestImageProvider provider)
+ {
+ using (Image background = provider.GetImage())
+ using (var overlay = new Image(50, 50))
+ {
+ overlay.Mutate(x => x.Fill(Rgba32.Black));
+
+ int xy = -25;
+ Rgba32 backgroundPixel = background[0, 0];
+ Rgba32 overlayPixel = overlay[Math.Abs(xy) + 1, Math.Abs(xy) + 1];
+
+ background.Mutate(x => x.DrawImage(overlay, PixelBlenderMode.Normal, 1F, new Size(overlay.Width, overlay.Height), new Point(xy, xy)));
+
+ Assert.Equal(Rgba32.White, backgroundPixel);
+ Assert.Equal(overlayPixel, background[0, 0]);
+
+ background.DebugSave(provider, new[] { "Negative" });
+ }
+ }
+
+ [Theory]
+ [WithSolidFilledImages(100, 100, 255, 255, 255, PixelTypes.Rgba32)]
+ public void ImageShouldHandlePositiveLocation(TestImageProvider provider)
+ {
+ using (Image background = provider.GetImage())
+ using (var overlay = new Image(50, 50))
+ {
+ overlay.Mutate(x => x.Fill(Rgba32.Black));
+
+ int xy = 25;
+ Rgba32 backgroundPixel = background[xy - 1, xy - 1];
+ Rgba32 overlayPixel = overlay[0, 0];
+
+ background.Mutate(x => x.DrawImage(overlay, PixelBlenderMode.Normal, 1F, new Size(overlay.Width, overlay.Height), new Point(xy, xy)));
+
+ Assert.Equal(Rgba32.White, backgroundPixel);
+ Assert.Equal(overlayPixel, background[xy, xy]);
+
+ background.DebugSave(provider, new[] { "Positive" });
+ }
+ }
}
}