Browse Source

pixel agnostic Mutate/Clone defined

af/merge-core
Anton Firszov 7 years ago
parent
commit
0d2c0e78c8
  1. 15
      src/ImageSharp/Image.cs
  2. 19
      src/ImageSharp/Image{TPixel}.cs
  3. 20
      src/ImageSharp/Processing/IImageProcessingContext{TPixel}.cs
  4. 34
      src/ImageSharp/Processing/ProcessingExtensions.cs

15
src/ImageSharp/Image.cs

@ -1,6 +1,7 @@
// Copyright (c) Six Labors and contributors. // Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0. // Licensed under the Apache License, Version 2.0.
using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.Formats; using SixLabors.ImageSharp.Formats;
using SixLabors.ImageSharp.Metadata; using SixLabors.ImageSharp.Metadata;
using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.PixelFormats;
@ -13,8 +14,10 @@ namespace SixLabors.ImageSharp
where TPixel : struct, IPixel<TPixel>; where TPixel : struct, IPixel<TPixel>;
} }
public abstract partial class Image : IImage public abstract partial class Image : IImage, IConfigurable
{ {
protected readonly Configuration configuration;
/// <inheritdoc/> /// <inheritdoc/>
public PixelTypeInfo PixelType { get; } public PixelTypeInfo PixelType { get; }
@ -27,14 +30,20 @@ namespace SixLabors.ImageSharp
/// <inheritdoc/> /// <inheritdoc/>
public ImageMetadata Metadata { get; } public ImageMetadata Metadata { get; }
protected Image(PixelTypeInfo pixelType, ImageMetadata metadata) /// <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.PixelType = pixelType;
this.Metadata = metadata ?? new ImageMetadata(); this.Metadata = metadata ?? new ImageMetadata();
} }
public abstract void Dispose(); public abstract void Dispose();
internal abstract void ApplyVisitor(IImageVisitor visitor); internal abstract void AcceptVisitor(IImageVisitor visitor);
} }
} }

19
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. /// Encapsulates an image, which consists of the pixel data for a graphics image and its attributes.
/// </summary> /// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam> /// <typeparam name="TPixel">The pixel format.</typeparam>
public sealed class Image<TPixel> : IImage, IConfigurable public sealed class Image<TPixel> : Image
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
private readonly Configuration configuration;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="Image{TPixel}"/> class /// Initializes a new instance of the <see cref="Image{TPixel}"/> class
/// with the height and the width of the image. /// with the height and the width of the image.
@ -68,8 +66,8 @@ namespace SixLabors.ImageSharp
/// <param name="height">The height of the image in pixels.</param> /// <param name="height">The height of the image in pixels.</param>
/// <param name="metadata">The images metadata.</param> /// <param name="metadata">The images metadata.</param>
internal Image(Configuration configuration, int width, int height, ImageMetadata metadata) internal Image(Configuration configuration, int width, int height, ImageMetadata metadata)
: base(configuration, PixelTypeInfo.Create<TPixel>(), metadata)
{ {
this.configuration = configuration ?? Configuration.Default;
this.PixelType = new PixelTypeInfo(Unsafe.SizeOf<TPixel>() * 8); this.PixelType = new PixelTypeInfo(Unsafe.SizeOf<TPixel>() * 8);
this.Metadata = metadata ?? new ImageMetadata(); this.Metadata = metadata ?? new ImageMetadata();
this.Frames = new ImageFrameCollection<TPixel>(this, width, height, default(TPixel)); this.Frames = new ImageFrameCollection<TPixel>(this, width, height, default(TPixel));
@ -85,8 +83,8 @@ namespace SixLabors.ImageSharp
/// <param name="height">The height of the image in pixels.</param> /// <param name="height">The height of the image in pixels.</param>
/// <param name="metadata">The images metadata.</param> /// <param name="metadata">The images metadata.</param>
internal Image(Configuration configuration, MemorySource<TPixel> memorySource, int width, int height, ImageMetadata metadata) internal Image(Configuration configuration, MemorySource<TPixel> memorySource, int width, int height, ImageMetadata metadata)
: base(configuration, PixelTypeInfo.Create<TPixel>(), metadata)
{ {
this.configuration = configuration;
this.PixelType = new PixelTypeInfo(Unsafe.SizeOf<TPixel>() * 8); this.PixelType = new PixelTypeInfo(Unsafe.SizeOf<TPixel>() * 8);
this.Metadata = metadata; this.Metadata = metadata;
this.Frames = new ImageFrameCollection<TPixel>(this, width, height, memorySource); this.Frames = new ImageFrameCollection<TPixel>(this, width, height, memorySource);
@ -102,8 +100,8 @@ namespace SixLabors.ImageSharp
/// <param name="backgroundColor">The color to initialize the pixels with.</param> /// <param name="backgroundColor">The color to initialize the pixels with.</param>
/// <param name="metadata">The images metadata.</param> /// <param name="metadata">The images metadata.</param>
internal Image(Configuration configuration, int width, int height, TPixel backgroundColor, ImageMetadata metadata) internal Image(Configuration configuration, int width, int height, TPixel backgroundColor, ImageMetadata metadata)
: base(configuration, PixelTypeInfo.Create<TPixel>(), metadata)
{ {
this.configuration = configuration ?? Configuration.Default;
this.PixelType = new PixelTypeInfo(Unsafe.SizeOf<TPixel>() * 8); this.PixelType = new PixelTypeInfo(Unsafe.SizeOf<TPixel>() * 8);
this.Metadata = metadata ?? new ImageMetadata(); this.Metadata = metadata ?? new ImageMetadata();
this.Frames = new ImageFrameCollection<TPixel>(this, width, height, backgroundColor); this.Frames = new ImageFrameCollection<TPixel>(this, width, height, backgroundColor);
@ -117,18 +115,14 @@ namespace SixLabors.ImageSharp
/// <param name="metadata">The images metadata.</param> /// <param name="metadata">The images metadata.</param>
/// <param name="frames">The frames that will be owned by this image instance.</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) internal Image(Configuration configuration, ImageMetadata metadata, IEnumerable<ImageFrame<TPixel>> frames)
: base(configuration,PixelTypeInfo.Create<TPixel>(), metadata)
{ {
this.configuration = configuration ?? Configuration.Default;
this.PixelType = new PixelTypeInfo(Unsafe.SizeOf<TPixel>() * 8); this.PixelType = new PixelTypeInfo(Unsafe.SizeOf<TPixel>() * 8);
this.Metadata = metadata ?? new ImageMetadata(); this.Metadata = metadata ?? new ImageMetadata();
this.Frames = new ImageFrameCollection<TPixel>(this, frames); this.Frames = new ImageFrameCollection<TPixel>(this, frames);
} }
/// <summary>
/// Gets the pixel buffer.
/// </summary>
Configuration IConfigurable.Configuration => this.configuration;
/// <inheritdoc/> /// <inheritdoc/>
public PixelTypeInfo PixelType { get; } public PixelTypeInfo PixelType { get; }
@ -142,7 +136,6 @@ namespace SixLabors.ImageSharp
/// <inheritdoc/> /// <inheritdoc/>
public ImageMetadata Metadata { get; } public ImageMetadata Metadata { get; }
/// <summary>
/// Gets the frames. /// Gets the frames.
/// </summary> /// </summary>
public ImageFrameCollection<TPixel> Frames { get; } public ImageFrameCollection<TPixel> Frames { get; }
@ -220,7 +213,7 @@ namespace SixLabors.ImageSharp
/// <inheritdoc/> /// <inheritdoc/>
public void Dispose() => this.Frames.Dispose(); public void Dispose() => this.Frames.Dispose();
internal override void ApplyVisitor(IImageVisitor visitor) internal override void AcceptVisitor(IImageVisitor visitor)
{ {
visitor.Visit(this); visitor.Visit(this);
} }

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

@ -9,16 +9,6 @@ using SixLabors.Primitives;
namespace SixLabors.ImageSharp.Processing namespace SixLabors.ImageSharp.Processing
{ {
public interface IImageProcessingContext public interface IImageProcessingContext
{
}
/// <summary>
/// An interface to queue up image operations to apply to an image.
/// </summary>
/// <typeparam name="TPixel">The pixel format</typeparam>
public interface IImageProcessingContext<TPixel>
where TPixel : struct, IPixel<TPixel>
{ {
/// <summary> /// <summary>
/// Gets a reference to the <see cref="MemoryAllocator" /> used to allocate buffers /// Gets a reference to the <see cref="MemoryAllocator" /> used to allocate buffers
@ -31,7 +21,15 @@ namespace SixLabors.ImageSharp.Processing
/// </summary> /// </summary>
/// <returns>The <see cref="Rectangle"/></returns> /// <returns>The <see cref="Rectangle"/></returns>
Size GetCurrentSize(); Size GetCurrentSize();
}
/// <summary>
/// An interface to queue up image operations to apply to an image.
/// </summary>
/// <typeparam name="TPixel">The pixel format</typeparam>
public interface IImageProcessingContext<TPixel> : IImageProcessingContext
where TPixel : struct, IPixel<TPixel>
{
/// <summary> /// <summary>
/// Adds the processor to the current set of image operations to be applied. /// Adds the processor to the current set of image operations to be applied.
/// </summary> /// </summary>

34
src/ImageSharp/Processing/ProcessingExtensions.cs

@ -13,9 +13,41 @@ namespace SixLabors.ImageSharp.Processing
/// </summary> /// </summary>
public static class ProcessingExtensions public static class ProcessingExtensions
{ {
public static void Mutate(this Image source, Action<IImageProcessingContext> operation) 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> /// <summary>

Loading…
Cancel
Save