Browse Source

Add broken implementation. Help needed!

pull/386/head
James Jackson-South 8 years ago
parent
commit
ab5dcdf7a2
  1. 44
      src/ImageSharp/Processing/Processors/Transforms/AffineProcessor.cs
  2. 36
      src/ImageSharp/Processing/Processors/Transforms/RotateProcessor.cs
  3. 37
      src/ImageSharp/Processing/Processors/Transforms/SkewProcessor.cs

44
src/ImageSharp/Processing/Processors/Transforms/AffineProcessor.cs

@ -4,6 +4,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Runtime.CompilerServices;
using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.Primitives;
@ -91,5 +92,48 @@ namespace SixLabors.ImageSharp.Processing.Processors
var translateToSourceCenter = Matrix3x2.CreateTranslation(source.Width * .5F, source.Height * .5F);
return (translationToTargetCenter * matrix) * translateToSourceCenter;
}
/// <summary>
/// Computes the weighted sum at the given XY position
/// </summary>
/// <param name="source">The source image</param>
/// <param name="maxX">The maximum x value</param>
/// <param name="maxY">The maximum y value</param>
/// <param name="windowX">The horizontal weights</param>
/// <param name="windowY">The vertical weights</param>
/// <param name="point">The transformed position</param>
/// <returns>The <see cref="Vector4"/></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected Vector4 ComputeWeightedSumAtPosition(ImageFrame<TPixel> source, int maxX, int maxY, ref WeightsWindow windowX, ref WeightsWindow windowY, ref Point point)
{
ref float horizontalValues = ref windowX.GetStartReference();
ref float verticalValues = ref windowY.GetStartReference();
int xLeft = windowX.Left;
int yLeft = windowY.Left;
int xLength = windowX.Length;
int yLength = windowY.Length;
Vector4 result = Vector4.Zero;
// TODO: Fix this.
// Currently the output image is the separable values duplicated with half the transform applied
// and not the combined values as it should be. I must be sampling the wrong values.
for (int i = 0; i < xLength; i++)
{
int offsetX = xLeft + i + point.X;
offsetX = offsetX.Clamp(0, maxX);
float weight = Unsafe.Add(ref horizontalValues, i);
result += source[offsetX, point.Y].ToVector4() * weight;
}
for (int i = 0; i < yLength; i++)
{
int offsetY = yLeft + i + point.Y;
offsetY = offsetY.Clamp(0, maxY);
float weight = Unsafe.Add(ref verticalValues, i);
result += source[point.X, offsetY].ToVector4() * weight;
}
return result;
}
}
}

36
src/ImageSharp/Processing/Processors/Transforms/RotateProcessor.cs

@ -86,7 +86,33 @@ namespace SixLabors.ImageSharp.Processing.Processors
Matrix3x2 matrix = this.GetCenteredMatrix(source, this.CreateProcessingMatrix());
Rectangle sourceBounds = source.Bounds();
// TODO: Use our new weights functionality to resample on transform
if (this.Sampler is NearestNeighborResampler)
{
Parallel.For(
0,
height,
configuration.ParallelOptions,
y =>
{
Span<TPixel> destRow = destination.GetPixelRowSpan(y);
for (int x = 0; x < width; x++)
{
var transformedPoint = Point.Rotate(new Point(x, y), matrix);
if (sourceBounds.Contains(transformedPoint.X, transformedPoint.Y))
{
destRow[x] = source[transformedPoint.X, transformedPoint.Y];
}
}
});
return;
}
int maxX = source.Height - 1;
int maxY = source.Width - 1;
Parallel.For(
0,
height,
@ -94,14 +120,16 @@ namespace SixLabors.ImageSharp.Processing.Processors
y =>
{
Span<TPixel> destRow = destination.GetPixelRowSpan(y);
for (int x = 0; x < width; x++)
{
var transformedPoint = Point.Rotate(new Point(x, y), matrix);
if (sourceBounds.Contains(transformedPoint.X, transformedPoint.Y))
{
destRow[x] = source[transformedPoint.X, transformedPoint.Y];
WeightsWindow windowX = this.HorizontalWeights.Weights[transformedPoint.X];
WeightsWindow windowY = this.VerticalWeights.Weights[transformedPoint.Y];
Vector4 dXY = this.ComputeWeightedSumAtPosition(source, maxX, maxY, ref windowX, ref windowY, ref transformedPoint);
ref TPixel dest = ref destRow[x];
dest.PackFromVector4(dXY);
}
}
});

37
src/ImageSharp/Processing/Processors/Transforms/SkewProcessor.cs

@ -58,7 +58,33 @@ namespace SixLabors.ImageSharp.Processing.Processors
Matrix3x2 matrix = this.GetCenteredMatrix(source, this.CreateProcessingMatrix());
Rectangle sourceBounds = source.Bounds();
// TODO: Use our new weights functionality to resample on transform
if (this.Sampler is NearestNeighborResampler)
{
Parallel.For(
0,
height,
configuration.ParallelOptions,
y =>
{
Span<TPixel> destRow = destination.GetPixelRowSpan(y);
for (int x = 0; x < width; x++)
{
var transformedPoint = Point.Skew(new Point(x, y), matrix);
if (sourceBounds.Contains(transformedPoint.X, transformedPoint.Y))
{
destRow[x] = source[transformedPoint.X, transformedPoint.Y];
}
}
});
return;
}
int maxX = source.Height - 1;
int maxY = source.Width - 1;
Parallel.For(
0,
height,
@ -66,14 +92,17 @@ namespace SixLabors.ImageSharp.Processing.Processors
y =>
{
Span<TPixel> destRow = destination.GetPixelRowSpan(y);
for (int x = 0; x < width; x++)
{
var transformedPoint = Point.Skew(new Point(x, y), matrix);
if (sourceBounds.Contains(transformedPoint.X, transformedPoint.Y))
{
destRow[x] = source[transformedPoint.X, transformedPoint.Y];
WeightsWindow windowX = this.HorizontalWeights.Weights[transformedPoint.X];
WeightsWindow windowY = this.VerticalWeights.Weights[transformedPoint.Y];
Vector4 dXY = this.ComputeWeightedSumAtPosition(source, maxX, maxY, ref windowX, ref windowY, ref transformedPoint);
ref TPixel dest = ref destRow[x];
dest.PackFromVector4(dXY);
}
}
});

Loading…
Cancel
Save