diff --git a/src/ImageProcessor/Filters/ImageFilterExtensions.cs b/src/ImageProcessor/Filters/ImageFilterExtensions.cs
index f435829b2..81b096c85 100644
--- a/src/ImageProcessor/Filters/ImageFilterExtensions.cs
+++ b/src/ImageProcessor/Filters/ImageFilterExtensions.cs
@@ -39,8 +39,7 @@ namespace ImageProcessor.Filters
/// Combines 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 opacity of the image image to blend. Must be between 0 and 100.
+ /// The color to set as the background.
/// The .
public static Image BackgroundColor(this Image source, Color color)
{
diff --git a/src/ImageProcessor/Samplers/Resampler.cs b/src/ImageProcessor/Samplers/Resampler.cs
index 401e4f451..2b81db34e 100644
--- a/src/ImageProcessor/Samplers/Resampler.cs
+++ b/src/ImageProcessor/Samplers/Resampler.cs
@@ -6,7 +6,7 @@
namespace ImageProcessor.Samplers
{
using System;
- using System.Collections.Immutable;
+ using System.Collections.Generic;
using System.Numerics;
using System.Threading.Tasks;
@@ -97,6 +97,22 @@ namespace ImageProcessor.Samplers
}
}
+ ///
+ /// Resamples the specified at the specified location
+ /// and with the specified size.
+ ///
+ /// Target image to apply the process to.
+ /// The source image. Cannot be null.
+ ///
+ /// The structure that specifies the location and size of the drawn image.
+ /// The image is scaled to fit the rectangle.
+ ///
+ /// The index of the row within the source image to start processing.
+ /// The index of the row within the source image to end processing.
+ ///
+ /// The method keeps the source image unchanged and returns the
+ /// the result of image process as new image.
+ ///
private void ApplyResizeOnly(ImageBase target, ImageBase source, Rectangle targetRectangle, int startY, int endY)
{
int targetY = targetRectangle.Y;
@@ -111,13 +127,11 @@ namespace ImageProcessor.Samplers
{
if (y >= targetY && y < targetBottom)
{
- ImmutableArray verticalValues = this.verticalWeights[y].Values;
- float verticalSum = this.verticalWeights[y].Sum;
+ Weight[] verticalValues = this.verticalWeights[y].Values;
for (int x = startX; x < endX; x++)
{
- ImmutableArray horizontalValues = this.horizontalWeights[x].Values;
- float horizontalSum = this.horizontalWeights[x].Sum;
+ Weight[] horizontalValues = this.horizontalWeights[x].Values;
// Destination color components
Color destination = new Color(0, 0, 0, 0);
@@ -130,7 +144,7 @@ namespace ImageProcessor.Samplers
{
int originX = xw.Index;
Color sourceColor = Color.InverseCompand(source[originX, originY]);
- float weight = (yw.Value / verticalSum) * (xw.Value / horizontalSum);
+ float weight = yw.Value * xw.Value;
destination.R += sourceColor.R * weight;
destination.G += sourceColor.G * weight;
@@ -150,6 +164,25 @@ namespace ImageProcessor.Samplers
});
}
+ ///
+ /// Resamples and rotates the specified at the specified location
+ /// and with the specified size.
+ ///
+ /// Target image to apply the process to.
+ /// The source image. Cannot be null.
+ ///
+ /// The structure that specifies the location and size of the drawn image.
+ /// The image is scaled to fit the rectangle.
+ ///
+ ///
+ /// The structure that specifies the portion of the image object to draw.
+ ///
+ /// The index of the row within the source image to start processing.
+ /// The index of the row within the source image to end processing.
+ ///
+ /// The method keeps the source image unchanged and returns the
+ /// the result of image process as new image.
+ ///
private void ApplyResizeAndRotate(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
{
int targetY = targetRectangle.Y;
@@ -166,13 +199,11 @@ namespace ImageProcessor.Samplers
{
if (y >= targetY && y < targetBottom)
{
- ImmutableArray verticalValues = this.verticalWeights[y].Values;
- float verticalSum = this.verticalWeights[y].Sum;
+ Weight[] verticalValues = this.verticalWeights[y].Values;
for (int x = startX; x < endX; x++)
{
- ImmutableArray horizontalValues = this.horizontalWeights[x].Values;
- float horizontalSum = this.horizontalWeights[x].Sum;
+ Weight[] horizontalValues = this.horizontalWeights[x].Values;
// Destination color components
Color destination = new Color(0, 0, 0, 0);
@@ -193,13 +224,19 @@ namespace ImageProcessor.Samplers
if (sourceRectangle.Contains(rotatedX, rotatedY))
{
Color sourceColor = Color.InverseCompand(source[rotatedX, rotatedY]);
- float weight = (yw.Value / verticalSum) * (xw.Value / horizontalSum);
-
+ float weight = yw.Value * xw.Value;
destination.R += sourceColor.R * weight;
destination.G += sourceColor.G * weight;
destination.B += sourceColor.B * weight;
destination.A += sourceColor.A * weight;
}
+ else
+ {
+ // This is well hacky but clears up most of the
+ // Alpha bleeding issues present in rotated images.
+ float weight = yw.Value * xw.Value;
+ destination.A += .9f * weight;
+ }
}
}
@@ -258,7 +295,7 @@ namespace ImageProcessor.Samplers
float sum = 0;
result[i] = new Weights();
- ImmutableArray.Builder builder = ImmutableArray.CreateBuilder();
+ List builder = new List();
for (int a = startU; a <= endU; a++)
{
float w = sampler.GetValue((a - fu) / scale);
@@ -270,7 +307,13 @@ namespace ImageProcessor.Samplers
}
}
- result[i].Values = builder.ToImmutable();
+ // Normalise the values
+ if (Math.Abs(sum) > 0.00001f)
+ {
+ builder.ForEach(w => w.Value /= sum);
+ }
+
+ result[i].Values = builder.ToArray();
result[i].Sum = sum;
});
@@ -280,7 +323,7 @@ namespace ImageProcessor.Samplers
///
/// Represents the weight to be added to a scaled pixel.
///
- protected struct Weight
+ protected class Weight
{
///
/// The pixel index.
@@ -288,12 +331,7 @@ namespace ImageProcessor.Samplers
public readonly int Index;
///
- /// The result of the interpolation algorithm.
- ///
- public readonly float Value;
-
- ///
- /// Initializes a new instance of the struct.
+ /// Initializes a new instance of the class.
///
/// The index.
/// The value.
@@ -302,6 +340,11 @@ namespace ImageProcessor.Samplers
this.Index = index;
this.Value = value;
}
+
+ ///
+ /// Gets or sets the result of the interpolation algorithm.
+ ///
+ public float Value { get; set; }
}
///
@@ -312,7 +355,7 @@ namespace ImageProcessor.Samplers
///
/// Gets or sets the values.
///
- public ImmutableArray Values { get; set; }
+ public Weight[] Values { get; set; }
///
/// Gets or sets the sum.