Browse Source

fix warnings and improve xmldocs

pull/904/head
Anton Firszov 7 years ago
parent
commit
6554db9732
  1. 1
      src/ImageSharp/Advanced/AdvancedImageExtensions.cs
  2. 1
      src/ImageSharp/Formats/Bmp/BmpDecoder.cs
  3. 3
      src/ImageSharp/Formats/Gif/GifDecoder.cs
  4. 11
      src/ImageSharp/Formats/IImageDecoder.cs
  5. 3
      src/ImageSharp/Formats/Jpeg/JpegDecoder.cs
  6. 3
      src/ImageSharp/Formats/Png/PngDecoder.cs
  7. 22
      src/ImageSharp/IImageVisitor.cs
  8. 4
      src/ImageSharp/Image.Decode.cs
  9. 13
      src/ImageSharp/Image.FromFile.cs
  10. 1
      src/ImageSharp/Image.FromStream.cs
  11. 8
      src/ImageSharp/Image.WrapMemory.cs
  12. 43
      src/ImageSharp/Image.cs
  13. 3
      src/ImageSharp/ImageExtensions.cs
  14. 25
      src/ImageSharp/Image{TPixel}.cs
  15. 42
      src/ImageSharp/Processing/IImageProcessingContext.cs
  16. 26
      src/ImageSharp/Processing/IImageProcessingContext{TPixel}.cs
  17. 3
      src/ImageSharp/Processing/PadExtensions.cs
  18. 1
      src/ImageSharp/Processing/PolaroidExtensions.cs
  19. 85
      src/ImageSharp/Processing/ProcessingExtensions.cs
  20. 3
      src/ImageSharp/Processing/Processors/Filters/BlackWhiteProcessor.cs
  21. 4
      src/ImageSharp/Processing/Processors/Filters/FilterProcessor.cs
  22. 13
      src/ImageSharp/Processing/Processors/Filters/LomographProcessorImplementation.cs
  23. 3
      src/ImageSharp/Processing/Processors/Filters/OpacityProcessor.cs
  24. 26
      src/ImageSharp/Processing/Processors/Filters/PolaroidProcessor.cs
  25. 31
      src/ImageSharp/Processing/Processors/Filters/PolaroidProcessorImplementation.cs
  26. 1
      src/ImageSharp/Processing/Processors/Filters/ProtanopiaProcessor.cs
  27. 13
      src/ImageSharp/Processing/Processors/IImageProcessor.cs
  28. 72
      src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeProcessor.cs
  29. 6
      src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeProcessorImplementation.cs
  30. 10
      src/ImageSharp/Processing/ResizeExtensions.cs
  31. 3
      tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.csproj

1
src/ImageSharp/Advanced/AdvancedImageExtensions.cs

@ -18,7 +18,6 @@ namespace SixLabors.ImageSharp.Advanced
/// <summary>
/// Gets the configuration for the image.
/// </summary>
/// <typeparam name="TPixel">The Pixel format.</typeparam>
/// <param name="source">The source image.</param>
/// <returns>Returns the configuration.</returns>
public static Configuration GetConfiguration(this Image source)

1
src/ImageSharp/Formats/Bmp/BmpDecoder.cs

@ -30,6 +30,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp
return new BmpDecoderCore(configuration, this).Decode<TPixel>(stream);
}
/// <inheritdoc />
public Image Decode(Configuration configuration, Stream stream) => this.Decode<Rgba32>(configuration, stream);
/// <inheritdoc/>

3
src/ImageSharp/Formats/Gif/GifDecoder.cs

@ -44,7 +44,8 @@ namespace SixLabors.ImageSharp.Formats.Gif
var decoder = new GifDecoderCore(configuration, this);
return decoder.Identify(stream);
}
/// <inheritdoc />
public Image Decode(Configuration configuration, Stream stream) => this.Decode<Rgba32>(configuration, stream);
}
}

11
src/ImageSharp/Formats/IImageDecoder.cs

@ -12,15 +12,22 @@ namespace SixLabors.ImageSharp.Formats
public interface IImageDecoder
{
/// <summary>
/// Decodes the image from the specified stream to the <see cref="ImageFrame{TPixel}"/>.
/// Decodes the image from the specified stream to an <see cref="Image{TPixel}"/> of a specific pixel type.
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="configuration">The configuration for the image.</param>
/// <param name="stream">The <see cref="Stream"/> containing image data.</param>
/// <returns>The decoded image</returns>
/// <returns>The decoded image of a given pixel type.</returns>
Image<TPixel> Decode<TPixel>(Configuration configuration, Stream stream)
where TPixel : struct, IPixel<TPixel>;
/// <summary>
/// Decodes the image from the specified stream to an <see cref="Image"/>.
/// The decoder is free to choose the pixel type.
/// </summary>
/// <param name="configuration">The configuration for the image.</param>
/// <param name="stream">The <see cref="Stream"/> containing image data.</param>
/// <returns>The decoded image of a pixel type chosen by the decoder.</returns>
Image Decode(Configuration configuration, Stream stream);
}
}

3
src/ImageSharp/Formats/Jpeg/JpegDecoder.cs

@ -38,7 +38,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
return decoder.Identify(stream);
}
}
/// <inheritdoc />
public Image Decode(Configuration configuration, Stream stream) => this.Decode<Rgba32>(configuration, stream);
}
}

3
src/ImageSharp/Formats/Png/PngDecoder.cs

@ -59,7 +59,8 @@ namespace SixLabors.ImageSharp.Formats.Png
var decoder = new PngDecoderCore(configuration, this);
return decoder.Identify(stream);
}
/// <inheritdoc />
public Image Decode(Configuration configuration, Stream stream) => this.Decode<Rgba32>(configuration, stream);
}
}

22
src/ImageSharp/IImageVisitor.cs

@ -0,0 +1,22 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using SixLabors.ImageSharp.PixelFormats;
namespace SixLabors.ImageSharp
{
/// <summary>
/// A visitor to implement double-dispatch pattern in order to apply pixel-specific operations
/// on non-generic <see cref="Image"/> instances. The operation is dispatched by <see cref="Image.AcceptVisitor"/>.
/// </summary>
internal interface IImageVisitor
{
/// <summary>
/// Provides a pixel-specific implementation for a given operation.
/// </summary>
/// <param name="image">The image.</param>
/// <typeparam name="TPixel">The pixel type.</typeparam>
void Visit<TPixel>(Image<TPixel> image)
where TPixel : struct, IPixel<TPixel>;
}
}

4
src/ImageSharp/Image.Decode.cs

@ -22,7 +22,7 @@ namespace SixLabors.ImageSharp
/// The image might be filled with memory garbage.
/// </summary>
/// <typeparam name="TPixel">The pixel type</typeparam>
/// <param name="configuration">The <see cref="Configuration"/></param>
/// <param name="configuration">The <see cref="ImageSharp.Configuration"/></param>
/// <param name="width">The width of the image</param>
/// <param name="height">The height of the image</param>
/// <param name="metadata">The <see cref="ImageMetadata"/></param>
@ -102,7 +102,7 @@ namespace SixLabors.ImageSharp
Image<TPixel> img = decoder.Decode<TPixel>(config, stream);
return (img, format);
}
private static (Image img, IImageFormat format) Decode(Stream stream, Configuration config)
{
IImageDecoder decoder = DiscoverDecoder(stream, config, out IImageFormat format);

13
src/ImageSharp/Image.FromFile.cs

@ -162,7 +162,18 @@ namespace SixLabors.ImageSharp
return Load<TPixel>(config, stream, out format);
}
}
/// <summary>
/// Create a new instance of the <see cref="Image"/> class from the given file.
/// The pixel type is selected by the decoder.
/// </summary>
/// <param name="config">The configuration options.</param>
/// <param name="path">The file path to the image.</param>
/// <param name="format">The mime type of the decoded image.</param>
/// <exception cref="NotSupportedException">
/// Thrown if the stream is not readable nor seekable.
/// </exception>
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>
public static Image Load(Configuration config, string path, out IImageFormat format)
{
using (Stream stream = config.FileSystem.OpenRead(path))

1
src/ImageSharp/Image.FromStream.cs

@ -182,6 +182,7 @@ namespace SixLabors.ImageSharp
throw new NotSupportedException(sb.ToString());
}
private static Image Load(Configuration config, Stream stream, out IImageFormat format)
{
config = config ?? Configuration.Default;

8
src/ImageSharp/Image.WrapMemory.cs

@ -20,7 +20,7 @@ namespace SixLabors.ImageSharp
/// allowing to view/manipulate it as an ImageSharp <see cref="Image{TPixel}"/> instance.
/// </summary>
/// <typeparam name="TPixel">The pixel type</typeparam>
/// <param name="config">The <see cref="Configuration"/></param>
/// <param name="config">The <see cref="ImageSharp.Configuration"/></param>
/// <param name="pixelMemory">The pixel memory.</param>
/// <param name="width">The width of the memory image.</param>
/// <param name="height">The height of the memory image.</param>
@ -43,7 +43,7 @@ namespace SixLabors.ImageSharp
/// allowing to view/manipulate it as an ImageSharp <see cref="Image{TPixel}"/> instance.
/// </summary>
/// <typeparam name="TPixel">The pixel type</typeparam>
/// <param name="config">The <see cref="Configuration"/></param>
/// <param name="config">The <see cref="ImageSharp.Configuration"/></param>
/// <param name="pixelMemory">The pixel memory.</param>
/// <param name="width">The width of the memory image.</param>
/// <param name="height">The height of the memory image.</param>
@ -85,7 +85,7 @@ namespace SixLabors.ImageSharp
/// It will be disposed together with the result image.
/// </summary>
/// <typeparam name="TPixel">The pixel type</typeparam>
/// <param name="config">The <see cref="Configuration"/></param>
/// <param name="config">The <see cref="ImageSharp.Configuration"/></param>
/// <param name="pixelMemoryOwner">The <see cref="IMemoryOwner{T}"/> that is being transferred to the image</param>
/// <param name="width">The width of the memory image.</param>
/// <param name="height">The height of the memory image.</param>
@ -111,7 +111,7 @@ namespace SixLabors.ImageSharp
/// It will be disposed together with the result image.
/// </summary>
/// <typeparam name="TPixel">The pixel type.</typeparam>
/// <param name="config">The <see cref="Configuration"/></param>
/// <param name="config">The <see cref="ImageSharp.Configuration"/></param>
/// <param name="pixelMemoryOwner">The <see cref="IMemoryOwner{T}"/> that is being transferred to the image.</param>
/// <param name="width">The width of the memory image.</param>
/// <param name="height">The height of the memory image.</param>

43
src/ImageSharp/Image.cs

@ -10,15 +10,30 @@ using SixLabors.ImageSharp.PixelFormats;
namespace SixLabors.ImageSharp
{
internal interface IImageVisitor
{
void Visit<TPixel>(Image<TPixel> image)
where TPixel : struct, IPixel<TPixel>;
}
/// <summary>
/// Encapsulates an image, which consists of the pixel data for a graphics image and its attributes.
/// For the non-generic <see cref="Image"/> type, the pixel type is only known at runtime.
/// <see cref="Image"/> is always implemented by a pixel-specific <see cref="Image{TPixel}"/> instance.
/// </summary>
public abstract partial class Image : IImage, IConfigurable
{
protected readonly Configuration configuration;
/// <summary>
/// Initializes a new instance of the <see cref="Image"/> class.
/// </summary>
/// <param name="configuration">The <see cref="Configuration"/>.</param>
/// <param name="pixelType">The <see cref="PixelTypeInfo"/>.</param>
/// <param name="metadata">The <see cref="ImageMetadata"/>.</param>
protected Image(Configuration configuration, PixelTypeInfo pixelType, ImageMetadata metadata)
{
this.Configuration = configuration ?? Configuration.Default;
this.PixelType = pixelType;
this.Metadata = metadata ?? new ImageMetadata();
}
/// <summary>
/// Gets the <see cref="Configuration"/>.
/// </summary>
protected Configuration Configuration { get; }
/// <inheritdoc/>
public PixelTypeInfo PixelType { get; }
@ -28,22 +43,16 @@ namespace SixLabors.ImageSharp
/// <inheritdoc />
public abstract int Height { get; }
/// <inheritdoc/>
public ImageMetadata Metadata { get; }
/// <summary>
/// Gets the pixel buffer.
/// </summary>
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();
}
Configuration IConfigurable.Configuration => this.Configuration;
/// <inheritdoc />
public abstract void Dispose();
internal abstract void AcceptVisitor(IImageVisitor visitor);
@ -63,7 +72,7 @@ namespace SixLabors.ImageSharp
this.AcceptVisitor(visitor);
}
class EncodeVisitor : IImageVisitor
private class EncodeVisitor : IImageVisitor
{
private readonly IImageEncoder encoder;

3
src/ImageSharp/ImageExtensions.cs

@ -19,7 +19,6 @@ namespace SixLabors.ImageSharp
/// <summary>
/// Writes the image to the given stream using the currently loaded image format.
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="source">The source image.</param>
/// <param name="filePath">The file path to save the image to.</param>
/// <exception cref="System.ArgumentNullException">Thrown if the stream is null.</exception>
@ -61,7 +60,6 @@ namespace SixLabors.ImageSharp
/// <summary>
/// Writes the image to the given stream using the currently loaded image format.
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="source">The source image.</param>
/// <param name="filePath">The file path to save the image to.</param>
/// <param name="encoder">The encoder to save the image with.</param>
@ -78,7 +76,6 @@ namespace SixLabors.ImageSharp
/// <summary>
/// Writes the image to the given stream using the currently loaded image format.
/// </summary>
/// <typeparam name="TPixel">The Pixel format.</typeparam>
/// <param name="source">The source image.</param>
/// <param name="stream">The stream to save the image to.</param>
/// <param name="format">The format to save the image in.</param>

25
src/ImageSharp/Image{TPixel}.cs

@ -16,6 +16,7 @@ namespace SixLabors.ImageSharp
{
/// <summary>
/// Encapsulates an image, which consists of the pixel data for a graphics image and its attributes.
/// For generic <see cref="Image{TPixel}"/>-s the pixel type is known at compile time.
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
public sealed class Image<TPixel> : Image
@ -68,8 +69,6 @@ namespace SixLabors.ImageSharp
internal Image(Configuration configuration, int width, int height, ImageMetadata metadata)
: base(configuration, PixelTypeInfo.Create<TPixel>(), metadata)
{
this.PixelType = new PixelTypeInfo(Unsafe.SizeOf<TPixel>() * 8);
this.Metadata = metadata ?? new ImageMetadata();
this.Frames = new ImageFrameCollection<TPixel>(this, width, height, default(TPixel));
}
@ -85,8 +84,6 @@ namespace SixLabors.ImageSharp
internal Image(Configuration configuration, MemorySource<TPixel> memorySource, int width, int height, ImageMetadata metadata)
: base(configuration, PixelTypeInfo.Create<TPixel>(), metadata)
{
this.PixelType = new PixelTypeInfo(Unsafe.SizeOf<TPixel>() * 8);
this.Metadata = metadata;
this.Frames = new ImageFrameCollection<TPixel>(this, width, height, memorySource);
}
@ -102,8 +99,6 @@ namespace SixLabors.ImageSharp
internal Image(Configuration configuration, int width, int height, TPixel backgroundColor, ImageMetadata metadata)
: base(configuration, PixelTypeInfo.Create<TPixel>(), metadata)
{
this.PixelType = new PixelTypeInfo(Unsafe.SizeOf<TPixel>() * 8);
this.Metadata = metadata ?? new ImageMetadata();
this.Frames = new ImageFrameCollection<TPixel>(this, width, height, backgroundColor);
}
@ -115,27 +110,18 @@ namespace SixLabors.ImageSharp
/// <param name="metadata">The images metadata.</param>
/// <param name="frames">The frames that will be owned by this image instance.</param>
internal Image(Configuration configuration, ImageMetadata metadata, IEnumerable<ImageFrame<TPixel>> frames)
: base(configuration,PixelTypeInfo.Create<TPixel>(), metadata)
: base(configuration, PixelTypeInfo.Create<TPixel>(), metadata)
{
this.PixelType = new PixelTypeInfo(Unsafe.SizeOf<TPixel>() * 8);
this.Metadata = metadata ?? new ImageMetadata();
this.Frames = new ImageFrameCollection<TPixel>(this, frames);
}
/// <inheritdoc/>
public PixelTypeInfo PixelType { get; }
/// <inheritdoc/>
public override int Width => this.Frames.RootFrame.Width;
/// <inheritdoc/>
public override int Height => this.Frames.RootFrame.Height;
/// <inheritdoc/>
public ImageMetadata Metadata { get; }
/// <summary>
/// Gets the frames.
/// </summary>
public ImageFrameCollection<TPixel> Frames { get; }
@ -154,7 +140,6 @@ namespace SixLabors.ImageSharp
public TPixel this[int x, int y]
{
get => this.PixelSource.PixelBuffer[x, y];
set => this.PixelSource.PixelBuffer[x, y] = value;
}
@ -162,7 +147,7 @@ namespace SixLabors.ImageSharp
/// Clones the current image
/// </summary>
/// <returns>Returns a new image with all the same metadata as the original.</returns>
public Image<TPixel> Clone() => this.Clone(this.configuration);
public Image<TPixel> Clone() => this.Clone(this.Configuration);
/// <summary>
/// Clones the current image with the given configuration.
@ -181,7 +166,7 @@ namespace SixLabors.ImageSharp
/// <typeparam name="TPixel2">The pixel format.</typeparam>
/// <returns>The <see cref="Image{TPixel2}"/></returns>
public Image<TPixel2> CloneAs<TPixel2>()
where TPixel2 : struct, IPixel<TPixel2> => this.CloneAs<TPixel2>(this.configuration);
where TPixel2 : struct, IPixel<TPixel2> => this.CloneAs<TPixel2>(this.Configuration);
/// <summary>
/// Returns a copy of the image in the given pixel format.

42
src/ImageSharp/Processing/IImageProcessingContext.cs

@ -0,0 +1,42 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using SixLabors.ImageSharp.Processing.Processors;
using SixLabors.Memory;
using SixLabors.Primitives;
namespace SixLabors.ImageSharp.Processing
{
/// <summary>
/// A pixel-agnostic interface to queue up image operations to apply to an image.
/// </summary>
public interface IImageProcessingContext
{
/// <summary>
/// Gets a reference to the <see cref="MemoryAllocator" /> used to allocate buffers
/// for this context.
/// </summary>
MemoryAllocator MemoryAllocator { get; }
/// <summary>
/// Gets the image dimensions at the current point in the processing pipeline.
/// </summary>
/// <returns>The <see cref="Rectangle"/>.</returns>
Size GetCurrentSize();
/// <summary>
/// Adds the processor to the current set of image operations to be applied.
/// </summary>
/// <param name="processor">The processor to apply.</param>
/// <param name="rectangle">The area to apply it to.</param>
/// <returns>The current operations class to allow chaining of operations.</returns>
IImageProcessingContext ApplyProcessor(IImageProcessor processor, Rectangle rectangle);
/// <summary>
/// Adds the processor to the current set of image operations to be applied.
/// </summary>
/// <param name="processor">The processor to apply.</param>
/// <returns>The current operations class to allow chaining of operations.</returns>
IImageProcessingContext ApplyProcessor(IImageProcessor processor);
}
}

26
src/ImageSharp/Processing/IImageProcessingContext{TPixel}.cs

@ -3,32 +3,12 @@
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing.Processors;
using SixLabors.Memory;
using SixLabors.Primitives;
namespace SixLabors.ImageSharp.Processing
{
public interface IImageProcessingContext
{
/// <summary>
/// Gets a reference to the <see cref="MemoryAllocator" /> used to allocate buffers
/// for this context.
/// </summary>
MemoryAllocator MemoryAllocator { get; }
/// <summary>
/// Gets the image dimensions at the current point in the processing pipeline.
/// </summary>
/// <returns>The <see cref="Rectangle"/></returns>
Size GetCurrentSize();
IImageProcessingContext ApplyProcessor(IImageProcessor processor, Rectangle rectangle);
IImageProcessingContext ApplyProcessor(IImageProcessor processor);
}
/// <summary>
/// An interface to queue up image operations to apply to an image.
/// A pixel-specific interface to queue up image operations to apply to an image.
/// </summary>
/// <typeparam name="TPixel">The pixel format</typeparam>
public interface IImageProcessingContext<TPixel> : IImageProcessingContext
@ -37,8 +17,8 @@ namespace SixLabors.ImageSharp.Processing
/// <summary>
/// Adds the processor to the current set of image operations to be applied.
/// </summary>
/// <param name="processor">The processor to apply</param>
/// <param name="rectangle">The area to apply it to</param>
/// <param name="processor">The processor to apply.</param>
/// <param name="rectangle">The area to apply it to.</param>
/// <returns>The current operations class to allow chaining of operations.</returns>
IImageProcessingContext<TPixel> ApplyProcessor(IImageProcessor<TPixel> processor, Rectangle rectangle);

3
src/ImageSharp/Processing/PadExtensions.cs

@ -14,7 +14,6 @@ namespace SixLabors.ImageSharp.Processing
/// <summary>
/// Evenly pads an image to fit the new dimensions.
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="source">The source image to pad.</param>
/// <param name="width">The new width.</param>
/// <param name="height">The new height.</param>
@ -25,7 +24,7 @@ namespace SixLabors.ImageSharp.Processing
{
Size = new Size(width, height),
Mode = ResizeMode.BoxPad,
Sampler = KnownResamplers.NearestNeighbor
Sampler = KnownResamplers.NearestNeighbor,
};
return source.Resize(options);

1
src/ImageSharp/Processing/PolaroidExtensions.cs

@ -23,7 +23,6 @@ namespace SixLabors.ImageSharp.Processing
/// <summary>
/// Alters the colors of the image recreating an old Polaroid camera effect.
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="source">The image this method extends.</param>
/// <param name="rectangle">
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.

85
src/ImageSharp/Processing/ProcessingExtensions.cs

@ -13,43 +13,6 @@ namespace SixLabors.ImageSharp.Processing
/// </summary>
public static class ProcessingExtensions
{
class ProcessingVisitor : IImageVisitor
{
private readonly Action<IImageProcessingContext> operation;
private readonly bool mutate;
public Image ResultImage { get; private set; }
public ProcessingVisitor(Action<IImageProcessingContext> operation, bool mutate)
{
this.operation = operation;
this.mutate = mutate;
}
public void Visit<TPixel>(Image<TPixel> image)
where TPixel : struct, IPixel<TPixel>
{
IInternalImageProcessingContext<TPixel> operationsRunner = image.GetConfiguration()
.ImageOperationsProvider.CreateImageProcessingContext(image, this.mutate);
this.operation(operationsRunner);
this.ResultImage = operationsRunner.Apply();
}
}
public static void Mutate(this Image source, Action<IImageProcessingContext> operation)
{
ProcessingVisitor visitor = new ProcessingVisitor(operation, true);
source.AcceptVisitor(visitor);
}
public static Image Clone(this Image source, Action<IImageProcessingContext> operation)
{
ProcessingVisitor visitor = new ProcessingVisitor(operation, false);
source.AcceptVisitor(visitor);
return visitor.ResultImage;
}
/// <summary>
/// Applies the given operation to the mutable image.
/// Useful when we need to extract information like Width/Height to parametrize the next operation working on the <see cref="IImageProcessingContext{TPixel}"/> chain.
@ -62,6 +25,17 @@ namespace SixLabors.ImageSharp.Processing
public static IImageProcessingContext<TPixel> Apply<TPixel>(this IImageProcessingContext<TPixel> source, Action<Image<TPixel>> operation)
where TPixel : struct, IPixel<TPixel> => source.ApplyProcessor(new DelegateProcessor<TPixel>(operation));
/// <summary>
/// Mutates the source image by applying the image operation to it.
/// </summary>
/// <param name="source">The image to mutate.</param>
/// <param name="operation">The operation to perform on the source.</param>
public static void Mutate(this Image source, Action<IImageProcessingContext> operation)
{
ProcessingVisitor visitor = new ProcessingVisitor(operation, true);
source.AcceptVisitor(visitor);
}
/// <summary>
/// Mutates the source image by applying the image operation to it.
/// </summary>
@ -96,6 +70,19 @@ namespace SixLabors.ImageSharp.Processing
operationsRunner.Apply();
}
/// <summary>
/// Creates a deep clone of the current image. The clone is then mutated by the given operation.
/// </summary>
/// <param name="source">The image to clone.</param>
/// <param name="operation">The operation to perform on the clone.</param>
/// <returns>The new <see cref="SixLabors.ImageSharp.Image"/>.</returns>
public static Image Clone(this Image source, Action<IImageProcessingContext> operation)
{
ProcessingVisitor visitor = new ProcessingVisitor(operation, false);
source.AcceptVisitor(visitor);
return visitor.ResultImage;
}
/// <summary>
/// Creates a deep clone of the current image. The clone is then mutated by the given operation.
/// </summary>
@ -149,5 +136,29 @@ namespace SixLabors.ImageSharp.Processing
return source;
}
private class ProcessingVisitor : IImageVisitor
{
private readonly Action<IImageProcessingContext> operation;
private readonly bool mutate;
public ProcessingVisitor(Action<IImageProcessingContext> operation, bool mutate)
{
this.operation = operation;
this.mutate = mutate;
}
public Image ResultImage { get; private set; }
public void Visit<TPixel>(Image<TPixel> image)
where TPixel : struct, IPixel<TPixel>
{
IInternalImageProcessingContext<TPixel> operationsRunner = image.GetConfiguration()
.ImageOperationsProvider.CreateImageProcessingContext(image, this.mutate);
this.operation(operationsRunner);
this.ResultImage = operationsRunner.Apply();
}
}
}
}

3
src/ImageSharp/Processing/Processors/Filters/BlackWhiteProcessor.cs

@ -8,11 +8,10 @@ namespace SixLabors.ImageSharp.Processing.Processors.Filters
/// <summary>
/// Applies a black and white filter matrix to the image
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
internal class BlackWhiteProcessor : FilterProcessor
{
/// <summary>
/// Initializes a new instance of the <see cref="BlackWhiteProcessor{TPixel}"/> class.
/// Initializes a new instance of the <see cref="BlackWhiteProcessor"/> class.
/// </summary>
public BlackWhiteProcessor()
: base(KnownFilterMatrices.BlackWhiteFilter)

4
src/ImageSharp/Processing/Processors/Filters/FilterProcessor.cs

@ -6,6 +6,9 @@ using SixLabors.ImageSharp.Primitives;
namespace SixLabors.ImageSharp.Processing.Processors.Filters
{
/// <summary>
/// Provides methods that accept a <see cref="ColorMatrix"/> matrix to apply free-form filters to images.
/// </summary>
public class FilterProcessor : IImageProcessor
{
/// <summary>
@ -19,6 +22,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Filters
/// </summary>
public ColorMatrix Matrix { get; }
/// <inheritdoc />
public virtual IImageProcessor<TPixel> CreatePixelSpecificProcessor<TPixel>()
where TPixel : struct, IPixel<TPixel>
{

13
src/ImageSharp/Processing/Processors/Filters/LomographProcessorImplementation.cs

@ -7,20 +7,23 @@ using SixLabors.Primitives;
namespace SixLabors.ImageSharp.Processing.Processors.Filters
{
/// <summary>
/// Converts the colors of the image recreating an old Lomograph effect.
/// </summary>
internal class LomographProcessorImplementation<TPixel> : FilterProcessorImplementation<TPixel>
where TPixel : struct, IPixel<TPixel>
{
private static readonly TPixel VeryDarkGreen = ColorBuilder<TPixel>.FromRGBA(0, 10, 0, 255);
/// <inheritdoc/>
protected override void AfterFrameApply(ImageFrame<TPixel> source, Rectangle sourceRectangle, Configuration configuration)
public LomographProcessorImplementation(LomographProcessor definition)
: base(definition)
{
new VignetteProcessor<TPixel>(VeryDarkGreen).Apply(source, sourceRectangle, configuration);
}
public LomographProcessorImplementation(FilterProcessor definition)
: base(definition)
/// <inheritdoc/>
protected override void AfterFrameApply(ImageFrame<TPixel> source, Rectangle sourceRectangle, Configuration configuration)
{
new VignetteProcessor<TPixel>(VeryDarkGreen).Apply(source, sourceRectangle, configuration);
}
}
}

3
src/ImageSharp/Processing/Processors/Filters/OpacityProcessor.cs

@ -8,11 +8,10 @@ namespace SixLabors.ImageSharp.Processing.Processors.Filters
/// <summary>
/// Applies an opacity filter matrix using the given amount.
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
internal class OpacityProcessor : FilterProcessor
{
/// <summary>
/// Initializes a new instance of the <see cref="OpacityProcessor{TPixel}"/> class.
/// Initializes a new instance of the <see cref="OpacityProcessor"/> class.
/// </summary>
/// <param name="amount">The proportion of the conversion. Must be between 0 and 1.</param>
public OpacityProcessor(float amount)

26
src/ImageSharp/Processing/Processors/Filters/PolaroidProcessor.cs

@ -1,10 +1,6 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing.Processors.Overlays;
using SixLabors.Primitives;
namespace SixLabors.ImageSharp.Processing.Processors.Filters
{
/// <summary>
@ -13,33 +9,15 @@ namespace SixLabors.ImageSharp.Processing.Processors.Filters
public class PolaroidProcessor : FilterProcessor
{
/// <summary>
/// Initializes a new instance of the <see cref="PolaroidProcessor{TPixel}" /> class.
/// Initializes a new instance of the <see cref="PolaroidProcessor" /> class.
/// </summary>
public PolaroidProcessor()
: base(KnownFilterMatrices.PolaroidFilter)
{
}
/// <inheritdoc />
public override IImageProcessor<TPixel> CreatePixelSpecificProcessor<TPixel>() =>
new PolaroidProcessorImplementation<TPixel>(this);
}
internal class PolaroidProcessorImplementation<TPixel> : FilterProcessorImplementation<TPixel>
where TPixel : struct, IPixel<TPixel>
{
private static readonly TPixel VeryDarkOrange = ColorBuilder<TPixel>.FromRGB(102, 34, 0);
private static readonly TPixel LightOrange = ColorBuilder<TPixel>.FromRGBA(255, 153, 102, 128);
/// <inheritdoc/>
protected override void AfterFrameApply(ImageFrame<TPixel> source, Rectangle sourceRectangle, Configuration configuration)
{
new VignetteProcessor<TPixel>(VeryDarkOrange).Apply(source, sourceRectangle, configuration);
new GlowProcessor<TPixel>(LightOrange, source.Width / 4F).Apply(source, sourceRectangle, configuration);
}
public PolaroidProcessorImplementation(FilterProcessor definition)
: base(definition)
{
}
}
}

31
src/ImageSharp/Processing/Processors/Filters/PolaroidProcessorImplementation.cs

@ -0,0 +1,31 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing.Processors.Overlays;
using SixLabors.Primitives;
namespace SixLabors.ImageSharp.Processing.Processors.Filters
{
/// <summary>
/// Converts the colors of the image recreating an old Polaroid effect.
/// </summary>
internal class PolaroidProcessorImplementation<TPixel> : FilterProcessorImplementation<TPixel>
where TPixel : struct, IPixel<TPixel>
{
private static readonly TPixel VeryDarkOrange = ColorBuilder<TPixel>.FromRGB(102, 34, 0);
private static readonly TPixel LightOrange = ColorBuilder<TPixel>.FromRGBA(255, 153, 102, 128);
public PolaroidProcessorImplementation(FilterProcessor definition)
: base(definition)
{
}
/// <inheritdoc/>
protected override void AfterFrameApply(ImageFrame<TPixel> source, Rectangle sourceRectangle, Configuration configuration)
{
new VignetteProcessor<TPixel>(VeryDarkOrange).Apply(source, sourceRectangle, configuration);
new GlowProcessor<TPixel>(LightOrange, source.Width / 4F).Apply(source, sourceRectangle, configuration);
}
}
}

1
src/ImageSharp/Processing/Processors/Filters/ProtanopiaProcessor.cs

@ -8,7 +8,6 @@ namespace SixLabors.ImageSharp.Processing.Processors.Filters
/// <summary>
/// Converts the colors of the image recreating Protanopia (Red-Blind) color blindness.
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
internal class ProtanopiaProcessor : FilterProcessor
{
/// <summary>

13
src/ImageSharp/Processing/Processors/IImageProcessor.cs

@ -6,14 +6,23 @@ using SixLabors.Primitives;
namespace SixLabors.ImageSharp.Processing.Processors
{
/// <summary>
/// Defines an algorithm to alter the pixels of an image.
/// </summary>
public interface IImageProcessor
{
/// <summary>
/// Creates a pixel specific <see cref="IImageProcessor{TPixel}"/> that is capable for executing
/// the processing algorithm on an <see cref="Image{TPixel}"/>.
/// </summary>
/// <typeparam name="TPixel">The pixel type.</typeparam>
/// <returns>The <see cref="IImageProcessor{TPixel}"/></returns>
IImageProcessor<TPixel> CreatePixelSpecificProcessor<TPixel>()
where TPixel : struct, IPixel<TPixel>;
}
/// <summary>
/// Encapsulates methods to alter the pixels of an image.
/// Implements an algorithm to alter the pixels of an image.
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
public interface IImageProcessor<TPixel>
@ -58,7 +67,7 @@ namespace SixLabors.ImageSharp.Processing.Processors
public void Visit<TPixel>(Image<TPixel> image)
where TPixel : struct, IPixel<TPixel>
{
var processorImpl = processor.CreatePixelSpecificProcessor<TPixel>();
var processorImpl = this.processor.CreatePixelSpecificProcessor<TPixel>();
processorImpl.Apply(image, this.sourceRectangle);
}
}

72
src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeProcessor.cs

@ -8,36 +8,20 @@ using SixLabors.Primitives;
namespace SixLabors.ImageSharp.Processing.Processors.Transforms
{
// The non-generic processor is responsible for:
// - Encapsulating the parameters of the processor
// - Implementing a factory method to create the pixel-specific processor that contains the implementation
/// <summary>
/// Implements resizing of images using various resamplers.
/// </summary>
public class ResizeProcessor : IImageProcessor
{
/// <summary>
/// Gets the sampler to perform the resize operation.
/// Initializes a new instance of the <see cref="ResizeProcessor"/> class.
/// </summary>
public IResampler Sampler { get; }
/// <summary>
/// Gets the target width.
/// </summary>
public int Width { get; }
/// <summary>
/// Gets the target height.
/// </summary>
public int Height { get; }
/// <summary>
/// Gets the resize rectangle.
/// </summary>
public Rectangle TargetRectangle { get; }
/// <summary>
/// Gets a value indicating whether to compress or expand individual pixel color values on processing.
/// </summary>
public bool Compand { get; }
/// <param name="sampler">The <see cref="IResampler"/>.</param>
/// <param name="width">The width.</param>
/// <param name="height">The height.</param>
/// <param name="sourceSize">The size of the source image.</param>
/// <param name="targetRectangle">The target rectangle to resize into.</param>
/// <param name="compand">A value indicating whether to apply RGBA companding.</param>
public ResizeProcessor(IResampler sampler, int width, int height, Size sourceSize, Rectangle targetRectangle, bool compand)
{
Guard.NotNull(sampler, nameof(sampler));
@ -67,12 +51,12 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
this.TargetRectangle = targetRectangle;
this.Compand = compand;
}
/// <summary>
/// Initializes a new instance of the <see cref="ResizeProcessorImplementation{TPixel}"/> class.
/// Initializes a new instance of the <see cref="ResizeProcessor"/> class.
/// </summary>
/// <param name="options">The resize options</param>
/// <param name="sourceSize">The source image size</param>
/// <param name="options">The resize options.</param>
/// <param name="sourceSize">The source image size.</param>
public ResizeProcessor(ResizeOptions options, Size sourceSize)
{
Guard.NotNull(options, nameof(options));
@ -109,7 +93,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
}
/// <summary>
/// Initializes a new instance of the <see cref="ResizeProcessorImplementation{TPixel}"/> class.
/// Initializes a new instance of the <see cref="ResizeProcessor"/> class.
/// </summary>
/// <param name="sampler">The sampler to perform the resize operation.</param>
/// <param name="width">The target width.</param>
@ -120,6 +104,32 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
{
}
/// <summary>
/// Gets the sampler to perform the resize operation.
/// </summary>
public IResampler Sampler { get; }
/// <summary>
/// Gets the target width.
/// </summary>
public int Width { get; }
/// <summary>
/// Gets the target height.
/// </summary>
public int Height { get; }
/// <summary>
/// Gets the resize rectangle.
/// </summary>
public Rectangle TargetRectangle { get; }
/// <summary>
/// Gets a value indicating whether to compress or expand individual pixel color values on processing.
/// </summary>
public bool Compand { get; }
/// <inheritdoc />
public IImageProcessor<TPixel> CreatePixelSpecificProcessor<TPixel>()
where TPixel : struct, IPixel<TPixel>
{

6
src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeProcessorImplementation.cs

@ -19,9 +19,11 @@ using SixLabors.Primitives;
namespace SixLabors.ImageSharp.Processing.Processors.Transforms
{
/// <summary>
/// Provides methods that allow the resizing of images using various algorithms.
/// Adapted from <see href="http://www.realtimerendering.com/resources/GraphicsGems/gemsiii/filter_rcg.c"/>
/// Implements resizing of images using various resamplers.
/// </summary>
/// <remarks>
/// The original code has been adapted from <see href="http://www.realtimerendering.com/resources/GraphicsGems/gemsiii/filter_rcg.c"/>.
/// </remarks>
/// <typeparam name="TPixel">The pixel format.</typeparam>
internal class ResizeProcessorImplementation<TPixel> : TransformProcessorBase<TPixel>
where TPixel : struct, IPixel<TPixel>

10
src/ImageSharp/Processing/ResizeExtensions.cs

@ -15,7 +15,6 @@ namespace SixLabors.ImageSharp.Processing
/// <summary>
/// Resizes an image in accordance with the given <see cref="ResizeOptions"/>.
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="source">The image to resize.</param>
/// <param name="options">The resize options.</param>
/// <returns>The <see cref="Image{TPixel}"/></returns>
@ -26,7 +25,6 @@ namespace SixLabors.ImageSharp.Processing
/// <summary>
/// Resizes an image to the given <see cref="Size"/>.
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="source">The image to resize.</param>
/// <param name="size">The target image size.</param>
/// <returns>The <see cref="Image{TPixel}"/></returns>
@ -37,7 +35,6 @@ namespace SixLabors.ImageSharp.Processing
/// <summary>
/// Resizes an image to the given <see cref="Size"/>.
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="source">The image to resize.</param>
/// <param name="size">The target image size.</param>
/// <param name="compand">Whether to compress and expand the image color-space to gamma correct the image during processing.</param>
@ -49,7 +46,6 @@ namespace SixLabors.ImageSharp.Processing
/// <summary>
/// Resizes an image to the given width and height.
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="source">The image to resize.</param>
/// <param name="width">The target image width.</param>
/// <param name="height">The target image height.</param>
@ -61,7 +57,6 @@ namespace SixLabors.ImageSharp.Processing
/// <summary>
/// Resizes an image to the given width and height.
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="source">The image to resize.</param>
/// <param name="width">The target image width.</param>
/// <param name="height">The target image height.</param>
@ -74,7 +69,6 @@ namespace SixLabors.ImageSharp.Processing
/// <summary>
/// Resizes an image to the given width and height with the given sampler.
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="source">The image to resize.</param>
/// <param name="width">The target image width.</param>
/// <param name="height">The target image height.</param>
@ -87,7 +81,6 @@ namespace SixLabors.ImageSharp.Processing
/// <summary>
/// Resizes an image to the given width and height with the given sampler.
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="source">The image to resize.</param>
/// <param name="size">The target image size.</param>
/// <param name="sampler">The <see cref="IResampler"/> to perform the resampling.</param>
@ -100,7 +93,6 @@ namespace SixLabors.ImageSharp.Processing
/// <summary>
/// Resizes an image to the given width and height with the given sampler.
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="source">The image to resize.</param>
/// <param name="width">The target image width.</param>
/// <param name="height">The target image height.</param>
@ -115,7 +107,6 @@ namespace SixLabors.ImageSharp.Processing
/// Resizes an image to the given width and height with the given sampler and
/// source rectangle.
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="source">The image to resize.</param>
/// <param name="width">The target image width.</param>
/// <param name="height">The target image height.</param>
@ -142,7 +133,6 @@ namespace SixLabors.ImageSharp.Processing
/// <summary>
/// Resizes an image to the given width and height with the given sampler and source rectangle.
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="source">The image to resize.</param>
/// <param name="width">The target image width.</param>
/// <param name="height">The target image height.</param>

3
tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.csproj

@ -1,6 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netcoreapp2.1;net472</TargetFrameworks>
<!--<TargetFrameworks>netcoreapp2.1;net472</TargetFrameworks>-->
<TargetFramework>netcoreapp2.1</TargetFramework>
<OutputType>Exe</OutputType>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<RootNamespace>SixLabors.ImageSharp.Benchmarks</RootNamespace>

Loading…
Cancel
Save