Browse Source

Merge pull request #364 from SixLabors/js/fix-252

Handle negative x offset for DrawImage
af/merge-core
James Jackson-South 8 years ago
committed by GitHub
parent
commit
ebfebe4cbf
  1. 14
      src/ImageSharp.Drawing/Processors/DrawImageProcessor.cs
  2. 46
      tests/ImageSharp.Tests/Drawing/DrawImageTest.cs

14
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
/// <summary>
/// Gets the image to blend.
/// </summary>
public Image<TPixel> Image { get; private set; }
public Image<TPixel> Image { get; }
/// <summary>
/// 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<float> amount = new Buffer<float>(width))
using (PixelAccessor<TPixel> toBlendPixels = targetImage.Lock())
using (PixelAccessor<TPixel> sourcePixels = source.Lock())
using (var amount = new Buffer<float>(width))
{
for (int i = 0; i < width; i++)
{
@ -99,8 +97,8 @@ namespace SixLabors.ImageSharp.Drawing.Processors
configuration.ParallelOptions,
y =>
{
Span<TPixel> background = sourcePixels.GetRowSpan(y).Slice(minX, width);
Span<TPixel> foreground = toBlendPixels.GetRowSpan(y - this.Location.Y).Slice(0, width);
Span<TPixel> background = source.GetPixelRowSpan(y).Slice(minX, width);
Span<TPixel> foreground = targetImage.GetPixelRowSpan(y - this.Location.Y).Slice(targetX, width);
this.blender.Blend(background, background, foreground, amount);
});
}

46
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<Rgba32> provider)
{
using (Image<Rgba32> background = provider.GetImage())
using (var overlay = new Image<Rgba32>(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<Rgba32> provider)
{
using (Image<Rgba32> background = provider.GetImage())
using (var overlay = new Image<Rgba32>(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" });
}
}
}
}

Loading…
Cancel
Save