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