diff --git a/src/ImageSharp/Image/IImageCallbacks.cs b/src/ImageSharp/Image/IImageCallbacks.cs
new file mode 100644
index 0000000000..ed9b1f97cb
--- /dev/null
+++ b/src/ImageSharp/Image/IImageCallbacks.cs
@@ -0,0 +1,46 @@
+//
+// Copyright (c) James Jackson-South and contributors.
+// Licensed under the Apache License, Version 2.0.
+//
+
+namespace ImageSharp
+{
+ using System;
+ using System.Collections.Generic;
+ using System.IO;
+ using System.Text;
+ using ImageSharp.Processing;
+
+ ///
+ /// Provides a set of methods that are called as part of the images lifetime/processes.
+ ///
+ internal interface IImageCallbacks
+ {
+ ///
+ /// Invoked before the image is saved.
+ ///
+ /// The color
+ /// The image
+ /// The destination stream
+ /// The encoder
+ /// The options
+ ///
+ /// return true if the processor should be applied otherwise false.
+ ///
+ bool OnSaving(ImageBase image, Stream stream, Formats.IImageEncoder encoder, IEncoderOptions options)
+ where TColor : struct, IPixel;
+
+ ///
+ /// Invoked before the image is processed.
+ ///
+ /// The color
+ /// The image
+ /// The processor.
+ /// The rectangle.
+ ///
+ /// return true if the processor should be applied otherwise false.
+ ///
+ bool OnProcessing(ImageBase image, IImageProcessor processor, Rectangle rectangle)
+ where TColor : struct, IPixel;
+ }
+}
diff --git a/src/ImageSharp/Image/ImageBase{TColor}.cs b/src/ImageSharp/Image/ImageBase{TColor}.cs
index 878ba09b39..f905123132 100644
--- a/src/ImageSharp/Image/ImageBase{TColor}.cs
+++ b/src/ImageSharp/Image/ImageBase{TColor}.cs
@@ -116,6 +116,11 @@ namespace ImageSharp
///
public Configuration Configuration { get; private set; }
+ ///
+ /// Gets or sets the callbacks item which will be called during the lifetime of the image being processed.
+ ///
+ internal IImageCallbacks Callbacks { get; set; }
+
///
/// Applies the processor.
///
@@ -123,7 +128,12 @@ namespace ImageSharp
/// The rectangle.
public virtual void ApplyProcessor(IImageProcessor processor, Rectangle rectangle)
{
- processor.Apply(this, rectangle);
+ // this will be null true or false, if its null or true then apply the processor
+ // thus is not false then apply the processors (allows for tests to save time and not actually run the prcessor is required)
+ if (this.Callbacks?.OnProcessing(this, processor, rectangle) != false)
+ {
+ processor.Apply(this, rectangle);
+ }
}
///
diff --git a/src/ImageSharp/Image/Image{TColor}.cs b/src/ImageSharp/Image/Image{TColor}.cs
index 3ac1585a82..8e33715bb8 100644
--- a/src/ImageSharp/Image/Image{TColor}.cs
+++ b/src/ImageSharp/Image/Image{TColor}.cs
@@ -560,22 +560,6 @@ namespace ImageSharp
return target;
}
- ///
- /// Internally saves the image to the given stream using the given image encoder and options.
- /// Can be used by overridden by tests to verify save opperations.
- ///
- /// The stream to save the image to.
- /// The encoder to save the image with.
- /// The options for the encoder.
- /// Thrown if the stream or encoder is null.
- internal virtual void SaveInternal(Stream stream, IImageEncoder encoder, IEncoderOptions options)
- {
- Guard.NotNull(stream, nameof(stream));
- Guard.NotNull(encoder, nameof(encoder));
-
- encoder.Encode(this, stream, options);
- }
-
///
/// Creates a new from this instance
///
@@ -597,6 +581,25 @@ namespace ImageSharp
base.Dispose(disposing);
}
+ ///
+ /// Internally saves the image to the given stream using the given image encoder and options.
+ /// Can be used by overridden by tests to verify save opperations.
+ ///
+ /// The stream to save the image to.
+ /// The encoder to save the image with.
+ /// The options for the encoder.
+ /// Thrown if the stream or encoder is null.
+ private void SaveInternal(Stream stream, IImageEncoder encoder, IEncoderOptions options)
+ {
+ Guard.NotNull(stream, nameof(stream));
+ Guard.NotNull(encoder, nameof(encoder));
+
+ if (this.Callbacks?.OnSaving(this, stream, encoder, options) != false)
+ {
+ encoder.Encode(this, stream, options);
+ }
+ }
+
///
/// Copies the properties from the other .
///
diff --git a/tests/ImageSharp.Tests/Drawing/Paths/ProcessorWatchingImage.cs b/tests/ImageSharp.Tests/Drawing/Paths/ProcessorWatchingImage.cs
index 3bb3b3e777..ff4432fd16 100644
--- a/tests/ImageSharp.Tests/Drawing/Paths/ProcessorWatchingImage.cs
+++ b/tests/ImageSharp.Tests/Drawing/Paths/ProcessorWatchingImage.cs
@@ -6,31 +6,35 @@ namespace ImageSharp.Tests.Drawing.Paths
using ImageSharp;
using Processing;
using System.Collections.Generic;
+ using ImageSharp.Formats;
///
/// Watches but does not actually run the processors against the image.
///
///
- public class ProcessorWatchingImage : Image
+ public class ProcessorWatchingImage : Image, IImageCallbacks
{
public List ProcessorApplications { get; } = new List();
public ProcessorWatchingImage(int width, int height)
: base(width, height, Configuration.CreateDefaultInstance())
{
+ this.Callbacks = this;
}
- public override void ApplyProcessor(IImageProcessor processor, Rectangle rectangle)
+ public bool OnSaving(ImageBase image, Stream stream, IImageEncoder encoder, IEncoderOptions options) where TColor : struct, IPixel
{
- ProcessorApplications.Add(new ProcessorDetails
+ return true;
+ }
+
+ public bool OnProcessing(ImageBase image, IImageProcessor processor, Rectangle rectangle) where TColor : struct, IPixel
+ {
+ this.ProcessorApplications.Add(new ProcessorDetails
{
- processor = processor,
+ processor = (IImageProcessor)processor,
rectangle = rectangle
});
-
- // doesn't really apply the processor to the fake images as this is supposed
- // to be just used to test which processor was finally applied and to interogate
- // its settings
+ return false;// do not really apply the processor to speed up testing
}
public struct ProcessorDetails
diff --git a/tests/ImageSharp.Tests/Image/SaveWatchingImage.cs b/tests/ImageSharp.Tests/Image/SaveWatchingImage.cs
index e9b45da696..0436146913 100644
--- a/tests/ImageSharp.Tests/Image/SaveWatchingImage.cs
+++ b/tests/ImageSharp.Tests/Image/SaveWatchingImage.cs
@@ -13,7 +13,7 @@ namespace ImageSharp.Tests
/// Watches but does not actually run the processors against the image.
///
///
- public class SaveWatchingImage : Image
+ public class SaveWatchingImage : Image, IImageCallbacks
{
public List Saves { get; } = new List();
@@ -22,9 +22,11 @@ namespace ImageSharp.Tests
{
//switch out the file system for tests
this.Configuration.FileSystem = fs ?? this.Configuration.FileSystem;
+
+ this.Callbacks = this;
}
- internal override void SaveInternal(Stream stream, IImageEncoder encoder, IEncoderOptions options)
+ public bool OnSaving(ImageBase image, Stream stream, IImageEncoder encoder, IEncoderOptions options) where TColor : struct, IPixel
{
this.Saves.Add(new OperationDetails
{
@@ -32,6 +34,13 @@ namespace ImageSharp.Tests
options = options,
stream = stream
});
+
+ return false;
+ }
+
+ public bool OnProcessing(ImageBase image, IImageProcessor processor, Rectangle rectangle) where TColor : struct, IPixel
+ {
+ return false;
}
public struct OperationDetails