Skip to content

Commit 22d5fc5

Browse files
committed
Added channel overloads to Normalize, BilateralBlur and MotionBlur.
1 parent 336b6fe commit 22d5fc5

8 files changed

Lines changed: 141 additions & 10 deletions

File tree

‎src/Magick.NET.Core/IMagickImage.cs‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1395,6 +1395,14 @@ public partial interface IMagickImage : IMagickImageCreateOperations, IDisposabl
13951395
/// <exception cref="MagickException">Thrown when an error is raised by ImageMagick.</exception>
13961396
void Normalize();
13971397

1398+
/// <summary>
1399+
/// Normalize the specified channel(s) of the image (increase contrast by normalizing the pixel
1400+
/// values to span the full range of color values).
1401+
/// </summary>
1402+
/// <param name="channels">The channel(s) that should be normalized.</param>
1403+
/// <exception cref="MagickException">Thrown when an error is raised by ImageMagick.</exception>
1404+
void Normalize(Channels channels);
1405+
13981406
/// <summary>
13991407
/// Perform a ordered dither based on a number of pre-defined dithering threshold maps, but over
14001408
/// multiple intensity levels.

‎src/Magick.NET.Core/IMagickImageCreateOperations.cs‎

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,15 @@ public interface IMagickImageCreateOperations
200200
/// <exception cref="MagickException">Thrown when an error is raised by ImageMagick.</exception>
201201
void BilateralBlur(uint width, uint height);
202202

203+
/// <summary>
204+
/// Applies a non-linear, edge-preserving, and noise-reducing smoothing filter.
205+
/// </summary>
206+
/// <param name="width">The width of the neighborhood in pixels.</param>
207+
/// <param name="height">The height of the neighborhood in pixels.</param>
208+
/// <param name="channels">The channel(s) that should be blurred.</param>
209+
/// <exception cref="MagickException">Thrown when an error is raised by ImageMagick.</exception>
210+
void BilateralBlur(uint width, uint height, Channels channels);
211+
203212
/// <summary>
204213
/// Applies a non-linear, edge-preserving, and noise-reducing smoothing filter.
205214
/// </summary>
@@ -210,6 +219,17 @@ public interface IMagickImageCreateOperations
210219
/// <exception cref="MagickException">Thrown when an error is raised by ImageMagick.</exception>
211220
void BilateralBlur(uint width, uint height, double intensitySigma, double spatialSigma);
212221

222+
/// <summary>
223+
/// Applies a non-linear, edge-preserving, and noise-reducing smoothing filter.
224+
/// </summary>
225+
/// <param name="width">The width of the neighborhood in pixels.</param>
226+
/// <param name="height">The height of the neighborhood in pixels.</param>
227+
/// <param name="intensitySigma">The sigma in the intensity space.</param>
228+
/// <param name="spatialSigma">The sigma in the coordinate space.</param>
229+
/// <param name="channels">The channel(s) that should be blurred.</param>
230+
/// <exception cref="MagickException">Thrown when an error is raised by ImageMagick.</exception>
231+
void BilateralBlur(uint width, uint height, double intensitySigma, double spatialSigma, Channels channels);
232+
213233
/// <summary>
214234
/// Simulate a scene at nighttime in the moonlight.
215235
/// </summary>
@@ -746,6 +766,16 @@ public interface IMagickImageCreateOperations
746766
/// <exception cref="MagickException">Thrown when an error is raised by ImageMagick.</exception>
747767
void MotionBlur(double radius, double sigma, double angle);
748768

769+
/// <summary>
770+
/// Motion blur the specified channel(s) of the image with the specified blur factor.
771+
/// </summary>
772+
/// <param name="radius">The radius of the Gaussian, in pixels, not counting the center pixel.</param>
773+
/// <param name="sigma">The standard deviation of the Laplacian, in pixels.</param>
774+
/// <param name="angle">The angle the object appears to be comming from (zero degrees is from the right).</param>
775+
/// <param name="channels">The channel(s) that should be blurred.</param>
776+
/// <exception cref="MagickException">Thrown when an error is raised by ImageMagick.</exception>
777+
void MotionBlur(double radius, double sigma, double angle, Channels channels);
778+
749779
/// <summary>
750780
/// Oilpaint image (image looks like oil painting).
751781
/// </summary>

‎src/Magick.NET/MagickImage.CloneMutator.cs‎

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -115,13 +115,19 @@ public void AutoOrient()
115115
=> SetResult(NativeMagickImage.AutoOrient());
116116

117117
public void BilateralBlur(uint width, uint height)
118+
=> BilateralBlur(width, height, ImageMagick.Channels.Undefined);
119+
120+
public void BilateralBlur(uint width, uint height, Channels channels)
118121
{
119122
var intensitySigma = Math.Sqrt((width * width) + (height * height));
120-
BilateralBlur(width, height, intensitySigma, intensitySigma * 0.25);
123+
BilateralBlur(width, height, intensitySigma, intensitySigma * 0.25, channels);
121124
}
122125

123126
public void BilateralBlur(uint width, uint height, double intensitySigma, double spatialSigma)
124-
=> SetResult(NativeMagickImage.BilateralBlur(width, height, intensitySigma, spatialSigma));
127+
=> BilateralBlur(width, height, intensitySigma, spatialSigma, ImageMagick.Channels.Undefined);
128+
129+
public void BilateralBlur(uint width, uint height, double intensitySigma, double spatialSigma, Channels channels)
130+
=> SetResult(NativeMagickImage.BilateralBlur(width, height, intensitySigma, spatialSigma, channels));
125131

126132
public void BlueShift()
127133
=> BlueShift(1.5);
@@ -420,17 +426,20 @@ public void Morphology(IMorphologySettings settings)
420426

421427
if (settings.UserKernel is not null && settings.UserKernel.Length > 0)
422428
{
423-
SetResult(NativeMagickImage.Morphology(settings.Method, settings.UserKernel, settings.Channels, settings.Iterations));
429+
SetResult(NativeMagickImage.Morphology(settings.Method, settings.UserKernel, settings.Iterations, settings.Channels));
424430
}
425431
else
426432
{
427433
var kernel = EnumHelper.GetName(settings.Kernel).ToLowerInvariant() + ":" + settings.KernelArguments;
428-
SetResult(NativeMagickImage.Morphology(settings.Method, kernel, settings.Channels, settings.Iterations));
434+
SetResult(NativeMagickImage.Morphology(settings.Method, kernel, settings.Iterations, settings.Channels));
429435
}
430436
}
431437

432438
public void MotionBlur(double radius, double sigma, double angle)
433-
=> SetResult(NativeMagickImage.MotionBlur(radius, sigma, angle));
439+
=> MotionBlur(radius, sigma, angle, ImageMagick.Channels.Undefined);
440+
441+
public void MotionBlur(double radius, double sigma, double angle, Channels channels)
442+
=> SetResult(NativeMagickImage.MotionBlur(radius, sigma, angle, channels));
434443

435444
public void OilPaint()
436445
=> OilPaint(3.0, 1.0);

‎src/Magick.NET/MagickImage.cs‎

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1274,6 +1274,19 @@ public void BilateralBlur(uint width, uint height)
12741274
mutator.BilateralBlur(width, height);
12751275
}
12761276

1277+
/// <summary>
1278+
/// Applies a non-linear, edge-preserving, and noise-reducing smoothing filter.
1279+
/// </summary>
1280+
/// <param name="width">The width of the neighborhood in pixels.</param>
1281+
/// <param name="height">The height of the neighborhood in pixels.</param>
1282+
/// <param name="channels">The channel(s) that should be blurred.</param>
1283+
/// <exception cref="MagickException">Thrown when an error is raised by ImageMagick.</exception>
1284+
public void BilateralBlur(uint width, uint height, Channels channels)
1285+
{
1286+
using var mutator = new Mutator(_nativeInstance);
1287+
mutator.BilateralBlur(width, height, channels);
1288+
}
1289+
12771290
/// <summary>
12781291
/// Applies a non-linear, edge-preserving, and noise-reducing smoothing filter.
12791292
/// </summary>
@@ -1288,6 +1301,21 @@ public void BilateralBlur(uint width, uint height, double intensitySigma, double
12881301
mutator.BilateralBlur(width, height, intensitySigma, spatialSigma);
12891302
}
12901303

1304+
/// <summary>
1305+
/// Applies a non-linear, edge-preserving, and noise-reducing smoothing filter.
1306+
/// </summary>
1307+
/// <param name="width">The width of the neighborhood in pixels.</param>
1308+
/// <param name="height">The height of the neighborhood in pixels.</param>
1309+
/// <param name="intensitySigma">The sigma in the intensity space.</param>
1310+
/// <param name="spatialSigma">The sigma in the coordinate space.</param>
1311+
/// <param name="channels">The channel(s) that should be blurred.</param>
1312+
/// <exception cref="MagickException">Thrown when an error is raised by ImageMagick.</exception>
1313+
public void BilateralBlur(uint width, uint height, double intensitySigma, double spatialSigma, Channels channels)
1314+
{
1315+
using var mutator = new Mutator(_nativeInstance);
1316+
mutator.BilateralBlur(width, height, intensitySigma, spatialSigma, channels);
1317+
}
1318+
12911319
/// <summary>
12921320
/// Forces all pixels below the threshold into black while leaving all pixels at or above
12931321
/// the threshold unchanged.
@@ -4188,6 +4216,20 @@ public void MotionBlur(double radius, double sigma, double angle)
41884216
mutator.MotionBlur(radius, sigma, angle);
41894217
}
41904218

4219+
/// <summary>
4220+
/// Motion blur the specified channel(s) of the image with the specified blur factor.
4221+
/// </summary>
4222+
/// <param name="radius">The radius of the Gaussian, in pixels, not counting the center pixel.</param>
4223+
/// <param name="sigma">The standard deviation of the Laplacian, in pixels.</param>
4224+
/// <param name="angle">The angle the object appears to be comming from (zero degrees is from the right).</param>
4225+
/// <param name="channels">The channel(s) that should be blurred.</param>
4226+
/// <exception cref="MagickException">Thrown when an error is raised by ImageMagick.</exception>
4227+
public void MotionBlur(double radius, double sigma, double angle, Channels channels)
4228+
{
4229+
using var mutator = new Mutator(_nativeInstance);
4230+
mutator.MotionBlur(radius, sigma, angle, channels);
4231+
}
4232+
41914233
/// <summary>
41924234
/// Negate colors in image.
41934235
/// </summary>
@@ -4224,7 +4266,16 @@ public void NegateGrayscale(Channels channels)
42244266
/// </summary>
42254267
/// <exception cref="MagickException">Thrown when an error is raised by ImageMagick.</exception>
42264268
public void Normalize()
4227-
=> _nativeInstance.Normalize();
4269+
=> Normalize(ImageMagick.Channels.Undefined);
4270+
4271+
/// <summary>
4272+
/// Normalize the specified channel(s) of the image (increase contrast by normalizing the pixel
4273+
/// values to span the full range of color values).
4274+
/// </summary>
4275+
/// <param name="channels">The channel(s) that should be normalized.</param>
4276+
/// <exception cref="MagickException">Thrown when an error is raised by ImageMagick.</exception>
4277+
public void Normalize(Channels channels)
4278+
=> _nativeInstance.Normalize(channels);
42284279

42294280
/// <summary>
42304281
/// Oilpaint image (image looks like oil painting).

‎src/Magick.NET/Native/MagickImage.cs‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ private unsafe sealed partial class NativeMagickImage : NativeInstance, INativeM
260260
public partial void AutoThreshold(AutoThresholdMethod method);
261261

262262
[Throws]
263-
public partial IntPtr BilateralBlur(nuint width, nuint height, double intensitySigma, double spatialSigma);
263+
public partial IntPtr BilateralBlur(nuint width, nuint height, double intensitySigma, double spatialSigma, Channels channels);
264264

265265
[Throws]
266266
public partial void BlackThreshold(string threshold, Channels channels);
@@ -537,16 +537,16 @@ private unsafe sealed partial class NativeMagickImage : NativeInstance, INativeM
537537
public partial IntPtr MinimumBoundingBox(out nuint length);
538538

539539
[Throws]
540-
public partial IntPtr Morphology(MorphologyMethod method, string kernel, Channels channels, nint iterations);
540+
public partial IntPtr Morphology(MorphologyMethod method, string kernel, nint iterations, Channels channels);
541541

542542
[Throws]
543-
public partial IntPtr MotionBlur(double radius, double sigma, double angle);
543+
public partial IntPtr MotionBlur(double radius, double sigma, double angle, Channels channels);
544544

545545
[Throws]
546546
public partial void Negate(bool onlyGrayscale, Channels channels);
547547

548548
[Throws]
549-
public partial void Normalize();
549+
public partial void Normalize(Channels channels);
550550

551551
[Throws]
552552
public partial IntPtr OilPaint(double radius, double sigma);

‎tests/Magick.NET.Tests/MagickImageTests/TheBilateralBlurMethod.cs‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,16 @@ public void ShouldApplyTheFilter()
2323
Assert.InRange(image.Compare(blurredImage, ErrorMetric.RootMeanSquared), 0.00084, 0.00085);
2424
#endif
2525
}
26+
27+
[Fact]
28+
public void ShouldOnlyBlurTheSpecifiedChannels()
29+
{
30+
using var image = new MagickImage(Files.NoisePNG);
31+
using var original = image.Clone();
32+
image.BilateralBlur(2, 2, Channels.Red);
33+
34+
Assert.NotEqual(0, original.Compare(image, ErrorMetric.RootMeanSquared, Channels.Red));
35+
Assert.Equal(0, original.Compare(image, ErrorMetric.RootMeanSquared, Channels.Green | Channels.Blue));
36+
}
2637
}
2738
}

‎tests/Magick.NET.Tests/MagickImageTests/TheMotionBlurMethod.cs‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,16 @@ public void ShouldMotionBlurTheImage()
2020

2121
Assert.InRange(motionBlurred.Compare(original, ErrorMetric.RootMeanSquared), 0.11019, 0.11020);
2222
}
23+
24+
[Fact]
25+
public void ShouldOnlyBlurTheSpecifiedChannels()
26+
{
27+
using var image = new MagickImage(Files.Builtin.Logo);
28+
using var original = image.Clone();
29+
image.MotionBlur(4.0, 5.4, 10.6, Channels.Red);
30+
31+
Assert.NotEqual(0, original.Compare(image, ErrorMetric.RootMeanSquared, Channels.Red));
32+
Assert.Equal(0, original.Compare(image, ErrorMetric.RootMeanSquared, Channels.Green | Channels.Blue));
33+
}
2334
}
2435
}

‎tests/Magick.NET.Tests/MagickImageTests/TheNormalizeMethod.cs‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,5 +37,16 @@ public void ShouldNormalizeTheImage()
3737
ColorAssert.Equal(new MagickColor("#00000000b3ef"), colorRange, 101, 99);
3838
#endif
3939
}
40+
41+
[Fact]
42+
public void ShouldOnlyNormalizeTheSpecifiedChannels()
43+
{
44+
using var image = new MagickImage("gradient:gray70-gray30", 100, 100);
45+
using var original = image.Clone();
46+
image.Normalize(Channels.Red);
47+
48+
Assert.NotEqual(0, original.Compare(image, ErrorMetric.RootMeanSquared, Channels.Red));
49+
Assert.Equal(0, original.Compare(image, ErrorMetric.RootMeanSquared, Channels.Green | Channels.Blue));
50+
}
4051
}
4152
}

0 commit comments

Comments
 (0)