diff --git a/src/ImageSharp/Image.cs b/src/ImageSharp/Image.cs index 6bea675b9..00a9a2075 100644 --- a/src/ImageSharp/Image.cs +++ b/src/ImageSharp/Image.cs @@ -1,6 +1,7 @@ // Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. +using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.Formats; using SixLabors.ImageSharp.Metadata; using SixLabors.ImageSharp.PixelFormats; @@ -13,8 +14,10 @@ namespace SixLabors.ImageSharp where TPixel : struct, IPixel; } - public abstract partial class Image : IImage + public abstract partial class Image : IImage, IConfigurable { + protected readonly Configuration configuration; + /// public PixelTypeInfo PixelType { get; } @@ -27,14 +30,20 @@ namespace SixLabors.ImageSharp /// public ImageMetadata Metadata { get; } - protected Image(PixelTypeInfo pixelType, ImageMetadata metadata) + /// + /// Gets the pixel buffer. + /// + Configuration IConfigurable.Configuration => this.configuration; + + protected Image(Configuration configuration, PixelTypeInfo pixelType, ImageMetadata metadata) { + this.configuration = configuration ?? Configuration.Default; this.PixelType = pixelType; this.Metadata = metadata ?? new ImageMetadata(); } public abstract void Dispose(); - internal abstract void ApplyVisitor(IImageVisitor visitor); + internal abstract void AcceptVisitor(IImageVisitor visitor); } } \ No newline at end of file diff --git a/src/ImageSharp/Image{TPixel}.cs b/src/ImageSharp/Image{TPixel}.cs index 2cf389d37..64ec87c4d 100644 --- a/src/ImageSharp/Image{TPixel}.cs +++ b/src/ImageSharp/Image{TPixel}.cs @@ -18,11 +18,9 @@ namespace SixLabors.ImageSharp /// Encapsulates an image, which consists of the pixel data for a graphics image and its attributes. /// /// The pixel format. - public sealed class Image : IImage, IConfigurable + public sealed class Image : Image where TPixel : struct, IPixel { - private readonly Configuration configuration; - /// /// Initializes a new instance of the class /// with the height and the width of the image. @@ -68,8 +66,8 @@ namespace SixLabors.ImageSharp /// The height of the image in pixels. /// The images metadata. internal Image(Configuration configuration, int width, int height, ImageMetadata metadata) + : base(configuration, PixelTypeInfo.Create(), metadata) { - this.configuration = configuration ?? Configuration.Default; this.PixelType = new PixelTypeInfo(Unsafe.SizeOf() * 8); this.Metadata = metadata ?? new ImageMetadata(); this.Frames = new ImageFrameCollection(this, width, height, default(TPixel)); @@ -85,8 +83,8 @@ namespace SixLabors.ImageSharp /// The height of the image in pixels. /// The images metadata. internal Image(Configuration configuration, MemorySource memorySource, int width, int height, ImageMetadata metadata) + : base(configuration, PixelTypeInfo.Create(), metadata) { - this.configuration = configuration; this.PixelType = new PixelTypeInfo(Unsafe.SizeOf() * 8); this.Metadata = metadata; this.Frames = new ImageFrameCollection(this, width, height, memorySource); @@ -102,8 +100,8 @@ namespace SixLabors.ImageSharp /// The color to initialize the pixels with. /// The images metadata. internal Image(Configuration configuration, int width, int height, TPixel backgroundColor, ImageMetadata metadata) + : base(configuration, PixelTypeInfo.Create(), metadata) { - this.configuration = configuration ?? Configuration.Default; this.PixelType = new PixelTypeInfo(Unsafe.SizeOf() * 8); this.Metadata = metadata ?? new ImageMetadata(); this.Frames = new ImageFrameCollection(this, width, height, backgroundColor); @@ -117,18 +115,14 @@ namespace SixLabors.ImageSharp /// The images metadata. /// The frames that will be owned by this image instance. internal Image(Configuration configuration, ImageMetadata metadata, IEnumerable> frames) + : base(configuration,PixelTypeInfo.Create(), metadata) { - this.configuration = configuration ?? Configuration.Default; this.PixelType = new PixelTypeInfo(Unsafe.SizeOf() * 8); this.Metadata = metadata ?? new ImageMetadata(); this.Frames = new ImageFrameCollection(this, frames); } - /// - /// Gets the pixel buffer. - /// - Configuration IConfigurable.Configuration => this.configuration; /// public PixelTypeInfo PixelType { get; } @@ -142,7 +136,6 @@ namespace SixLabors.ImageSharp /// public ImageMetadata Metadata { get; } - /// /// Gets the frames. /// public ImageFrameCollection Frames { get; } @@ -220,7 +213,7 @@ namespace SixLabors.ImageSharp /// public void Dispose() => this.Frames.Dispose(); - internal override void ApplyVisitor(IImageVisitor visitor) + internal override void AcceptVisitor(IImageVisitor visitor) { visitor.Visit(this); } diff --git a/src/ImageSharp/Processing/IImageProcessingContext{TPixel}.cs b/src/ImageSharp/Processing/IImageProcessingContext{TPixel}.cs index 72b78b32a..1b4fbd3be 100644 --- a/src/ImageSharp/Processing/IImageProcessingContext{TPixel}.cs +++ b/src/ImageSharp/Processing/IImageProcessingContext{TPixel}.cs @@ -9,16 +9,6 @@ using SixLabors.Primitives; namespace SixLabors.ImageSharp.Processing { public interface IImageProcessingContext - { - - } - - /// - /// An interface to queue up image operations to apply to an image. - /// - /// The pixel format - public interface IImageProcessingContext - where TPixel : struct, IPixel { /// /// Gets a reference to the used to allocate buffers @@ -31,7 +21,15 @@ namespace SixLabors.ImageSharp.Processing /// /// The Size GetCurrentSize(); - + } + + /// + /// An interface to queue up image operations to apply to an image. + /// + /// The pixel format + public interface IImageProcessingContext : IImageProcessingContext + where TPixel : struct, IPixel + { /// /// Adds the processor to the current set of image operations to be applied. /// diff --git a/src/ImageSharp/Processing/ProcessingExtensions.cs b/src/ImageSharp/Processing/ProcessingExtensions.cs index c96b97111..a1acf3aa0 100644 --- a/src/ImageSharp/Processing/ProcessingExtensions.cs +++ b/src/ImageSharp/Processing/ProcessingExtensions.cs @@ -13,9 +13,41 @@ namespace SixLabors.ImageSharp.Processing /// public static class ProcessingExtensions { - public static void Mutate(this Image source, Action operation) + class ProcessingVisitor : IImageVisitor { + private readonly Action operation; + + private readonly bool mutate; + public Image ResultImage { get; private set; } + + public ProcessingVisitor(Action operation, bool mutate) + { + this.operation = operation; + this.mutate = mutate; + } + + public void Visit(Image image) + where TPixel : struct, IPixel + { + IInternalImageProcessingContext operationsRunner = image.GetConfiguration() + .ImageOperationsProvider.CreateImageProcessingContext(image, this.mutate); + this.operation(operationsRunner); + this.ResultImage = operationsRunner.Apply(); + } + } + + public static void Mutate(this Image source, Action operation) + { + ProcessingVisitor visitor = new ProcessingVisitor(operation, true); + source.AcceptVisitor(visitor); + } + + public static Image Clone(this Image source, Action operation) + { + ProcessingVisitor visitor = new ProcessingVisitor(operation, false); + source.AcceptVisitor(visitor); + return visitor.ResultImage; } ///