Skip to content

Commit 0322ee2

Browse files
Merge pull request #1058 from Sergio0694/improvement_bokeh-blur-speedup-and-memory-reduction
Bokeh blur speedup and memory usage improvement
2 parents ec4eca1 + 8a89fdc commit 0322ee2

File tree

6 files changed

+41
-242
lines changed

6 files changed

+41
-242
lines changed

src/ImageSharp/Common/Helpers/Buffer2DUtils.cs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Licensed under the Apache License, Version 2.0.
33

44
using System;
5+
using System.Numerics;
56
using System.Runtime.CompilerServices;
67
using System.Runtime.InteropServices;
78

@@ -62,7 +63,7 @@ public static void Convolve4<TPixel>(
6263
}
6364

6465
/// <summary>
65-
/// Computes the sum of vectors in <paramref name="targetRow"/> weighted by the kernel weight values.
66+
/// Computes the sum of vectors in <paramref name="targetRow"/> weighted by the kernel weight values and accumulates the partial results.
6667
/// </summary>
6768
/// <param name="kernel">The 1D convolution kernel.</param>
6869
/// <param name="sourceValues">The source frame.</param>
@@ -73,16 +74,20 @@ public static void Convolve4<TPixel>(
7374
/// <param name="maxRow">The maximum working area row.</param>
7475
/// <param name="minColumn">The minimum working area column.</param>
7576
/// <param name="maxColumn">The maximum working area column.</param>
76-
public static void Convolve4(
77+
/// <param name="z">The weight factor for the real component of the complex pixel values.</param>
78+
/// <param name="w">The weight factor for the imaginary component of the complex pixel values.</param>
79+
public static void Convolve4AndAccumulatePartials(
7780
Span<Complex64> kernel,
7881
Buffer2D<ComplexVector4> sourceValues,
79-
Span<ComplexVector4> targetRow,
82+
Span<Vector4> targetRow,
8083
int row,
8184
int column,
8285
int minRow,
8386
int maxRow,
8487
int minColumn,
85-
int maxColumn)
88+
int maxColumn,
89+
float z,
90+
float w)
8691
{
8792
ComplexVector4 vector = default;
8893
int kernelLength = kernel.Length;
@@ -99,7 +104,7 @@ public static void Convolve4(
99104
vector.Sum(Unsafe.Add(ref baseRef, x) * Unsafe.Add(ref sourceRef, offsetX));
100105
}
101106

102-
targetRow[column] = vector;
107+
targetRow[column] += vector.WeightedSum(z, w);
103108
}
104109
}
105110
}

src/ImageSharp/Memory/Buffer2D{T}.cs

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -69,23 +69,6 @@ internal Buffer2D(MemorySource<T> memorySource, int width, int height)
6969
}
7070
}
7171

72-
/// <summary>
73-
/// Creates a new <see cref="Buffer2D{T}"/> instance that maps to a target rows interval from the current instance.
74-
/// </summary>
75-
/// <param name="y">The target vertical offset for the rows interval to retrieve.</param>
76-
/// <param name="h">The desired number of rows to extract.</param>
77-
/// <returns>The new <see cref="Buffer2D{T}"/> instance with the requested rows interval.</returns>
78-
public Buffer2D<T> Slice(int y, int h)
79-
{
80-
DebugGuard.MustBeGreaterThanOrEqualTo(y, 0, nameof(y));
81-
DebugGuard.MustBeGreaterThan(h, 0, nameof(h));
82-
DebugGuard.MustBeLessThanOrEqualTo(y + h, this.Height, nameof(h));
83-
84-
Memory<T> slice = this.GetMemory().Slice(y * this.Width, h * this.Width);
85-
var memory = new MemorySource<T>(slice);
86-
return new Buffer2D<T>(memory, this.Width, h);
87-
}
88-
8972
/// <summary>
9073
/// Disposes the <see cref="Buffer2D{T}"/> instance
9174
/// </summary>

src/ImageSharp/Processing/BokehBlurExecutionMode.cs

Lines changed: 0 additions & 23 deletions
This file was deleted.

src/ImageSharp/Processing/Extensions/BokehBlurExtensions.cs

Lines changed: 0 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,6 @@ public static class BokehBlurExtensions
1919
public static IImageProcessingContext BokehBlur(this IImageProcessingContext source)
2020
=> source.ApplyProcessor(new BokehBlurProcessor());
2121

22-
/// <summary>
23-
/// Applies a bokeh blur to the image.
24-
/// </summary>
25-
/// <param name="source">The image this method extends.</param>
26-
/// <param name="executionMode">The execution mode to use when applying the processor.</param>
27-
/// <returns>The <see cref="IImageProcessingContext"/> to allow chaining of operations.</returns>
28-
public static IImageProcessingContext BokehBlur(this IImageProcessingContext source, BokehBlurExecutionMode executionMode)
29-
=> source.ApplyProcessor(new BokehBlurProcessor(executionMode));
30-
3122
/// <summary>
3223
/// Applies a bokeh blur to the image.
3324
/// </summary>
@@ -39,18 +30,6 @@ public static IImageProcessingContext BokehBlur(this IImageProcessingContext sou
3930
public static IImageProcessingContext BokehBlur(this IImageProcessingContext source, int radius, int components, float gamma)
4031
=> source.ApplyProcessor(new BokehBlurProcessor(radius, components, gamma));
4132

42-
/// <summary>
43-
/// Applies a bokeh blur to the image.
44-
/// </summary>
45-
/// <param name="source">The image this method extends.</param>
46-
/// <param name="radius">The 'radius' value representing the size of the area to sample.</param>
47-
/// <param name="components">The 'components' value representing the number of kernels to use to approximate the bokeh effect.</param>
48-
/// <param name="gamma">The gamma highlight factor to use to emphasize bright spots in the source image</param>
49-
/// <param name="executionMode">The execution mode to use when applying the processor.</param>
50-
/// <returns>The <see cref="IImageProcessingContext"/> to allow chaining of operations.</returns>
51-
public static IImageProcessingContext BokehBlur(this IImageProcessingContext source, int radius, int components, float gamma, BokehBlurExecutionMode executionMode)
52-
=> source.ApplyProcessor(new BokehBlurProcessor(radius, components, gamma, executionMode));
53-
5433
/// <summary>
5534
/// Applies a bokeh blur to the image.
5635
/// </summary>
@@ -62,18 +41,6 @@ public static IImageProcessingContext BokehBlur(this IImageProcessingContext sou
6241
public static IImageProcessingContext BokehBlur(this IImageProcessingContext source, Rectangle rectangle)
6342
=> source.ApplyProcessor(new BokehBlurProcessor(), rectangle);
6443

65-
/// <summary>
66-
/// Applies a bokeh blur to the image.
67-
/// </summary>
68-
/// <param name="source">The image this method extends.</param>
69-
/// <param name="rectangle">
70-
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
71-
/// </param>
72-
/// <param name="executionMode">The execution mode to use when applying the processor.</param>
73-
/// <returns>The <see cref="IImageProcessingContext"/> to allow chaining of operations.</returns>
74-
public static IImageProcessingContext BokehBlur(this IImageProcessingContext source, Rectangle rectangle, BokehBlurExecutionMode executionMode)
75-
=> source.ApplyProcessor(new BokehBlurProcessor(executionMode), rectangle);
76-
7744
/// <summary>
7845
/// Applies a bokeh blur to the image.
7946
/// </summary>
@@ -87,20 +54,5 @@ public static IImageProcessingContext BokehBlur(this IImageProcessingContext sou
8754
/// <returns>The <see cref="IImageProcessingContext"/> to allow chaining of operations.</returns>
8855
public static IImageProcessingContext BokehBlur(this IImageProcessingContext source, int radius, int components, float gamma, Rectangle rectangle)
8956
=> source.ApplyProcessor(new BokehBlurProcessor(radius, components, gamma), rectangle);
90-
91-
/// <summary>
92-
/// Applies a bokeh blur to the image.
93-
/// </summary>
94-
/// <param name="source">The image this method extends.</param>
95-
/// <param name="radius">The 'radius' value representing the size of the area to sample.</param>
96-
/// <param name="components">The 'components' value representing the number of kernels to use to approximate the bokeh effect.</param>
97-
/// <param name="gamma">The gamma highlight factor to use to emphasize bright spots in the source image</param>
98-
/// <param name="executionMode">The execution mode to use when applying the processor.</param>
99-
/// <param name="rectangle">
100-
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
101-
/// </param>
102-
/// <returns>The <see cref="IImageProcessingContext"/> to allow chaining of operations.</returns>
103-
public static IImageProcessingContext BokehBlur(this IImageProcessingContext source, int radius, int components, float gamma, BokehBlurExecutionMode executionMode, Rectangle rectangle)
104-
=> source.ApplyProcessor(new BokehBlurProcessor(radius, components, gamma, executionMode), rectangle);
10557
}
10658
}

src/ImageSharp/Processing/Processors/Convolution/BokehBlurProcessor.cs

Lines changed: 1 addition & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -26,27 +26,11 @@ public sealed class BokehBlurProcessor : IImageProcessor
2626
/// </summary>
2727
public const float DefaultGamma = 3F;
2828

29-
/// <summary>
30-
/// The default execution mode used by the parameterless constructor.
31-
/// </summary>
32-
public const BokehBlurExecutionMode DefaultExecutionMode = BokehBlurExecutionMode.PreferLowMemoryUsage;
33-
3429
/// <summary>
3530
/// Initializes a new instance of the <see cref="BokehBlurProcessor"/> class.
3631
/// </summary>
3732
public BokehBlurProcessor()
38-
: this(DefaultRadius, DefaultComponents, DefaultGamma, DefaultExecutionMode)
39-
{
40-
}
41-
42-
/// <summary>
43-
/// Initializes a new instance of the <see cref="BokehBlurProcessor"/> class.
44-
/// </summary>
45-
/// <param name="executionMode">
46-
/// The execution mode to use when applying the processor.
47-
/// </param>
48-
public BokehBlurProcessor(BokehBlurExecutionMode executionMode)
49-
: this(DefaultRadius, DefaultComponents, DefaultGamma, executionMode)
33+
: this(DefaultRadius, DefaultComponents, DefaultGamma)
5034
{
5135
}
5236

@@ -63,33 +47,12 @@ public BokehBlurProcessor(BokehBlurExecutionMode executionMode)
6347
/// The gamma highlight factor to use to further process the image.
6448
/// </param>
6549
public BokehBlurProcessor(int radius, int components, float gamma)
66-
: this(radius, components, gamma, DefaultExecutionMode)
67-
{
68-
}
69-
70-
/// <summary>
71-
/// Initializes a new instance of the <see cref="BokehBlurProcessor"/> class.
72-
/// </summary>
73-
/// <param name="radius">
74-
/// The 'radius' value representing the size of the area to sample.
75-
/// </param>
76-
/// <param name="components">
77-
/// The number of components to use to approximate the original 2D bokeh blur convolution kernel.
78-
/// </param>
79-
/// <param name="gamma">
80-
/// The gamma highlight factor to use to further process the image.
81-
/// </param>
82-
/// <param name="executionMode">
83-
/// The execution mode to use when applying the processor.
84-
/// </param>
85-
public BokehBlurProcessor(int radius, int components, float gamma, BokehBlurExecutionMode executionMode)
8650
{
8751
Guard.MustBeGreaterThanOrEqualTo(gamma, 1, nameof(gamma));
8852

8953
this.Radius = radius;
9054
this.Components = components;
9155
this.Gamma = gamma;
92-
this.ExecutionMode = executionMode;
9356
}
9457

9558
/// <summary>
@@ -107,11 +70,6 @@ public BokehBlurProcessor(int radius, int components, float gamma, BokehBlurExec
10770
/// </summary>
10871
public float Gamma { get; }
10972

110-
/// <summary>
111-
/// Gets the execution mode to use when applying the effect.
112-
/// </summary>
113-
public BokehBlurExecutionMode ExecutionMode { get; }
114-
11573
/// <inheritdoc />
11674
public IImageProcessor<TPixel> CreatePixelSpecificProcessor<TPixel>(Image<TPixel> source, Rectangle sourceRectangle)
11775
where TPixel : struct, IPixel<TPixel>

0 commit comments

Comments
 (0)