diff --git a/src/ImageSharp.Drawing/DrawImage.cs b/src/ImageSharp.Drawing/DrawImage.cs index d55e224162..b84a1c16a4 100644 --- a/src/ImageSharp.Drawing/DrawImage.cs +++ b/src/ImageSharp.Drawing/DrawImage.cs @@ -16,7 +16,10 @@ namespace SixLabors.ImageSharp /// Draws the given image together with the current one by blending their pixels. /// /// The image this method extends. - /// The image to blend with the currently processing image. + /// + /// The image to blend with the currently processing image. + /// If the image dimensions do not match the given then the image will be resized to match. + /// /// The pixel format. /// The size to draw the blended image. /// The location to draw the blended image. @@ -45,7 +48,7 @@ namespace SixLabors.ImageSharp /// The pixel format. /// The image this method extends. /// The image to blend with the currently processing image. - /// The opacity of the image image to blend. Must be between 0 and 1. + /// The opacity of the image to blend. Must be between 0 and 1. /// The . public static IImageProcessingContext Blend(this IImageProcessingContext source, Image image, float percent) where TPixel : struct, IPixel @@ -62,7 +65,7 @@ namespace SixLabors.ImageSharp /// The image this method extends. /// The image to blend with the currently processing image. /// The blending mode. - /// The opacity of the image image to blend. Must be between 0 and 1. + /// The opacity of the image to blend. Must be between 0 and 1. /// The . public static IImageProcessingContext Blend(this IImageProcessingContext source, Image image, PixelBlenderMode blender, float percent) where TPixel : struct, IPixel @@ -79,7 +82,7 @@ namespace SixLabors.ImageSharp /// The pixel format. /// The image this method extends. /// The image to blend with the currently processing image. - /// The options, including the blending type and belnding amount. + /// The options, including the blending type and blending amount. /// The . public static IImageProcessingContext Blend(this IImageProcessingContext source, Image image, GraphicsOptions options) where TPixel : struct, IPixel @@ -91,9 +94,12 @@ namespace SixLabors.ImageSharp /// Draws the given image together with the current one by blending their pixels. /// /// The image this method extends. - /// The image to blend with the currently processing image. + /// + /// The image to blend with the currently processing image. + /// If the image dimensions do not match the given then the image will be resized to match. + /// /// The pixel format. - /// The opacity of the image image to blend. Must be between 0 and 1. + /// The opacity of the image to blend. Must be between 0 and 1. /// The size to draw the blended image. /// The location to draw the blended image. /// The . @@ -109,10 +115,13 @@ namespace SixLabors.ImageSharp /// Draws the given image together with the current one by blending their pixels. /// /// The image this method extends. - /// The image to blend with the currently processing image. + /// + /// The image to blend with the currently processing image. + /// If the image dimensions do not match the given then the image will be resized to match. + /// /// The pixel format. /// The type of bending to apply. - /// The opacity of the image image to blend. Must be between 0 and 1. + /// The opacity of the image to blend. Must be between 0 and 1. /// The size to draw the blended image. /// The location to draw the blended image. /// The . diff --git a/src/ImageSharp.Drawing/Processors/DrawImageProcessor.cs b/src/ImageSharp.Drawing/Processors/DrawImageProcessor.cs index 47763c0aaf..4bb12b9957 100644 --- a/src/ImageSharp.Drawing/Processors/DrawImageProcessor.cs +++ b/src/ImageSharp.Drawing/Processors/DrawImageProcessor.cs @@ -24,15 +24,25 @@ namespace SixLabors.ImageSharp.Drawing.Processors /// /// Initializes a new instance of the class. /// - /// The image to blend with the currently processing image. + /// + /// The image to blend with the currently processing image. + /// If the image dimensions do not match the given then the image will be resized to match. + /// /// The size to draw the blended image. /// The location to draw the blended image. /// The opacity of the image to blend. Between 0 and 100. public DrawImageProcessor(Image image, Size size, Point location, GraphicsOptions options) { Guard.MustBeBetweenOrEqualTo(options.BlendPercentage, 0, 1, nameof(options.BlendPercentage)); - this.Image = image; + this.Size = size; + + if (image.Size() != size) + { + image.Mutate(x => x.Resize(size.Width, size.Height)); + } + + this.Image = image; this.Alpha = options.BlendPercentage; this.blender = PixelOperations.Instance.GetPixelBlender(options.BlenderMode); this.Location = location; @@ -61,51 +71,38 @@ namespace SixLabors.ImageSharp.Drawing.Processors /// protected override void OnApply(ImageFrame source, Rectangle sourceRectangle, Configuration configuration) { - Image disposableImage = null; Image targetImage = this.Image; - try - { - if (targetImage.Size() != this.Size) - { - targetImage = disposableImage = this.Image.Clone(x => x.Resize(this.Size.Width, this.Size.Height)); - } + // Align start/end positions. + 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; - // Align start/end positions. - 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); - int minY = Math.Max(this.Location.Y, sourceRectangle.Y); - int maxY = Math.Min(this.Location.Y + bounds.Height, sourceRectangle.Bottom); + maxY = Math.Min(this.Location.Y + this.Size.Height, maxY); - maxY = Math.Min(this.Location.Y + this.Size.Height, maxY); - - int width = maxX - minX; - using (var amount = new Buffer(width)) + int width = maxX - minX; + using (var amount = new Buffer(width)) + { + for (int i = 0; i < width; i++) { - for (int i = 0; i < width; i++) - { - amount[i] = this.Alpha; - } - - Parallel.For( - minY, - maxY, - configuration.ParallelOptions, - y => - { - 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); - }); + amount[i] = this.Alpha; } - } - finally - { - disposableImage?.Dispose(); + + Parallel.For( + minY, + maxY, + configuration.ParallelOptions, + y => + { + 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); + }); } } }