mirror of https://github.com/SixLabors/ImageSharp
107 changed files with 633 additions and 591 deletions
@ -0,0 +1,72 @@ |
|||||
|
// <copyright file="DefaultInternalImageProcessorApplicator.cs" company="James Jackson-South">
|
||||
|
// Copyright (c) James Jackson-South and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>
|
||||
|
|
||||
|
namespace ImageSharp |
||||
|
{ |
||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using ImageSharp.PixelFormats; |
||||
|
using ImageSharp.Processing; |
||||
|
using SixLabors.Primitives; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// The static collection of all the default image formats
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TPixel">The pixel format</typeparam>
|
||||
|
internal class DefaultInternalImageProcessorApplicator<TPixel> : IInternalImageProcessorApplicator<TPixel> |
||||
|
where TPixel : struct, IPixel<TPixel> |
||||
|
{ |
||||
|
private readonly bool mutate; |
||||
|
private readonly Image<TPixel> source; |
||||
|
private Image<TPixel> destination; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="DefaultInternalImageProcessorApplicator{TPixel}"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="source">The image.</param>
|
||||
|
/// <param name="mutate">The mutate.</param>
|
||||
|
public DefaultInternalImageProcessorApplicator(Image<TPixel> source, bool mutate) |
||||
|
{ |
||||
|
this.mutate = mutate; |
||||
|
this.source = source; |
||||
|
if (this.mutate) |
||||
|
{ |
||||
|
this.destination = source; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public Image<TPixel> Apply() |
||||
|
{ |
||||
|
if (!this.mutate && this.destination == null) |
||||
|
{ |
||||
|
// ensure we have cloned it if we are not mutating as we might have failed to register any Processors
|
||||
|
this.destination = this.source.Clone(); |
||||
|
} |
||||
|
|
||||
|
return this.destination; |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public IImageProcessorApplicator<TPixel> ApplyProcessor(IImageProcessor<TPixel> processor, Rectangle rectangle) |
||||
|
{ |
||||
|
if (!this.mutate && this.destination == null) |
||||
|
{ |
||||
|
// TODO check if the processor implements a special interface and if it does then allow it to take
|
||||
|
// over and crereate the clone on behalf ImageOperations class.
|
||||
|
this.destination = this.source.Clone(); |
||||
|
} |
||||
|
|
||||
|
processor.Apply(this.destination, rectangle); |
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public IImageProcessorApplicator<TPixel> ApplyProcessor(IImageProcessor<TPixel> processor) |
||||
|
{ |
||||
|
return this.ApplyProcessor(processor, this.source.Bounds()); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,153 @@ |
|||||
|
// <copyright file="ImageBase{TPixel}.cs" company="James Jackson-South">
|
||||
|
// Copyright (c) James Jackson-South and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>
|
||||
|
|
||||
|
namespace ImageSharp |
||||
|
{ |
||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.IO; |
||||
|
using System.Text; |
||||
|
using ImageSharp.Formats; |
||||
|
using ImageSharp.PixelFormats; |
||||
|
using SixLabors.Primitives; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Extension methods over Image{TPixel}
|
||||
|
/// </summary>
|
||||
|
public static partial class ImageExtensions |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Gets the bounds of the image.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TPixel">The Pixel format.</typeparam>
|
||||
|
/// <param name="source">The source image</param>
|
||||
|
/// <returns>Returns the bounds of the image</returns>
|
||||
|
public static Rectangle Bounds<TPixel>(this ImageBase<TPixel> source) |
||||
|
where TPixel : struct, IPixel<TPixel> |
||||
|
=> new Rectangle(0, 0, source.Width, source.Height); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the size of the image.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TPixel">The Pixel format.</typeparam>
|
||||
|
/// <param name="source">The source image</param>
|
||||
|
/// <returns>Returns the bounds of the image</returns>
|
||||
|
public static Size Size<TPixel>(this ImageBase<TPixel> source) |
||||
|
where TPixel : struct, IPixel<TPixel> |
||||
|
=> new Size(source.Width, source.Height); |
||||
|
|
||||
|
#if !NETSTANDARD1_1
|
||||
|
/// <summary>
|
||||
|
/// Saves 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>
|
||||
|
public static void Save<TPixel>(this Image<TPixel> source, string filePath) |
||||
|
where TPixel : struct, IPixel<TPixel> |
||||
|
{ |
||||
|
Guard.NotNullOrEmpty(filePath, nameof(filePath)); |
||||
|
|
||||
|
string ext = Path.GetExtension(filePath).Trim('.'); |
||||
|
IImageFormat format = source.Configuration.FindFormatByFileExtensions(ext); |
||||
|
if (format == null) |
||||
|
{ |
||||
|
var stringBuilder = new StringBuilder(); |
||||
|
stringBuilder.AppendLine($"Can't find a format that is associated with the file extention '{ext}'. Registered formats with there extensions include:"); |
||||
|
foreach (IImageFormat fmt in source.Configuration.ImageFormats) |
||||
|
{ |
||||
|
stringBuilder.AppendLine($" - {fmt.Name} : {string.Join(", ", fmt.FileExtensions)}"); |
||||
|
} |
||||
|
|
||||
|
throw new NotSupportedException(stringBuilder.ToString()); |
||||
|
} |
||||
|
|
||||
|
IImageEncoder encoder = source.Configuration.FindEncoder(format); |
||||
|
|
||||
|
if (encoder == null) |
||||
|
{ |
||||
|
var stringBuilder = new StringBuilder(); |
||||
|
stringBuilder.AppendLine($"Can't find encoder for file extention '{ext}' using image format '{format.Name}'. Registered encoders include:"); |
||||
|
foreach (KeyValuePair<IImageFormat, IImageEncoder> enc in source.Configuration.ImageEncoders) |
||||
|
{ |
||||
|
stringBuilder.AppendLine($" - {enc.Key} : {enc.Value.GetType().Name}"); |
||||
|
} |
||||
|
|
||||
|
throw new NotSupportedException(stringBuilder.ToString()); |
||||
|
} |
||||
|
|
||||
|
source.Save(filePath, encoder); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Saves 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>
|
||||
|
/// <exception cref="System.ArgumentNullException">Thrown if the encoder is null.</exception>
|
||||
|
public static void Save<TPixel>(this Image<TPixel> source, string filePath, IImageEncoder encoder) |
||||
|
where TPixel : struct, IPixel<TPixel> |
||||
|
{ |
||||
|
Guard.NotNull(encoder, nameof(encoder)); |
||||
|
using (Stream fs = source.Configuration.FileSystem.Create(filePath)) |
||||
|
{ |
||||
|
source.Save(fs, encoder); |
||||
|
} |
||||
|
} |
||||
|
#endif
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Saves 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 to.</param>
|
||||
|
/// <exception cref="System.ArgumentNullException">Thrown if the stream is null.</exception>
|
||||
|
public static void Save<TPixel>(this Image<TPixel> source, Stream stream, IImageFormat format) |
||||
|
where TPixel : struct, IPixel<TPixel> |
||||
|
{ |
||||
|
Guard.NotNull(format, nameof(format)); |
||||
|
IImageEncoder encoder = source.Configuration.FindEncoder(format); |
||||
|
|
||||
|
if (encoder == null) |
||||
|
{ |
||||
|
var stringBuilder = new StringBuilder(); |
||||
|
stringBuilder.AppendLine("Can't find encoder for provided mime type. Available encoded:"); |
||||
|
|
||||
|
foreach (KeyValuePair<IImageFormat, IImageEncoder> val in source.Configuration.ImageEncoders) |
||||
|
{ |
||||
|
stringBuilder.AppendLine($" - {val.Key.Name} : {val.Value.GetType().Name}"); |
||||
|
} |
||||
|
|
||||
|
throw new NotSupportedException(stringBuilder.ToString()); |
||||
|
} |
||||
|
|
||||
|
source.Save(stream, encoder); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Returns a Base64 encoded string from the given image.
|
||||
|
/// </summary>
|
||||
|
/// <example><see href="data:image/gif;base64,R0lGODlhAQABAIABAEdJRgAAACwAAAAAAQABAAACAkQBAA=="/></example>
|
||||
|
/// <typeparam name="TPixel">The Pixel format.</typeparam>
|
||||
|
/// <param name="source">The source image</param>
|
||||
|
/// <param name="format">The format.</param>
|
||||
|
/// <returns>The <see cref="string"/></returns>
|
||||
|
public static string ToBase64String<TPixel>(this Image<TPixel> source, IImageFormat format) |
||||
|
where TPixel : struct, IPixel<TPixel> |
||||
|
{ |
||||
|
using (var stream = new MemoryStream()) |
||||
|
{ |
||||
|
source.Save(stream, format); |
||||
|
stream.Flush(); |
||||
|
return $"data:{format.DefaultMimeType};base64,{Convert.ToBase64String(stream.ToArray())}"; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,32 +0,0 @@ |
|||||
// <copyright file="ImageProcessingExtensions.cs" company="James Jackson-South">
|
|
||||
// Copyright (c) James Jackson-South and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
// </copyright>
|
|
||||
|
|
||||
namespace ImageSharp |
|
||||
{ |
|
||||
using ImageSharp.PixelFormats; |
|
||||
|
|
||||
using ImageSharp.Processing; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Extension methods for the <see cref="Image{TPixel}"/> type.
|
|
||||
/// </summary>
|
|
||||
public static partial class ImageExtensions |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Applies the processor to the image.
|
|
||||
/// <remarks>This method does not resize the target image.</remarks>
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|
||||
/// <param name="source">The image this method extends.</param>
|
|
||||
/// <param name="processor">The processor to apply to the image.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|
||||
public static IImageOperations<TPixel> Apply<TPixel>(this IImageOperations<TPixel> source, IImageProcessor<TPixel> processor) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
{ |
|
||||
source.ApplyProcessor(processor); |
|
||||
return source; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,62 +0,0 @@ |
|||||
// <copyright file="IImageFormat.cs" company="James Jackson-South">
|
|
||||
// Copyright (c) James Jackson-South and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
// </copyright>
|
|
||||
|
|
||||
namespace ImageSharp |
|
||||
{ |
|
||||
using System.Collections.Generic; |
|
||||
using ImageSharp.PixelFormats; |
|
||||
using ImageSharp.Processing; |
|
||||
using SixLabors.Primitives; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// The static collection of all the default image formats
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The pixel format</typeparam>
|
|
||||
internal class ImageOperations<TPixel> : IImageOperations<TPixel> |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
{ |
|
||||
private readonly Image<TPixel> image; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Initializes a new instance of the <see cref="ImageOperations{TPixel}"/> class.
|
|
||||
/// </summary>
|
|
||||
/// <param name="image">The image.</param>
|
|
||||
public ImageOperations(Image<TPixel> image) |
|
||||
{ |
|
||||
this.image = image; |
|
||||
} |
|
||||
|
|
||||
/// <inheritdoc/>
|
|
||||
public IImageOperations<TPixel> ApplyProcessor(IImageProcessor<TPixel> processor, Rectangle rectangle) |
|
||||
{ |
|
||||
// TODO : make this queue, and allow special processors managage the cloing operation for 'generate'
|
|
||||
// to allow things like resize to not need to retain an extra copy of image data in memory, and to
|
|
||||
// prevent an pixel copy operation
|
|
||||
this.image.ApplyProcessor(processor, rectangle); |
|
||||
return this; |
|
||||
} |
|
||||
|
|
||||
/// <inheritdoc/>
|
|
||||
public IImageOperations<TPixel> ApplyProcessor(IImageProcessor<TPixel> processor) |
|
||||
{ |
|
||||
return this.ApplyProcessor(processor, this.image.Bounds); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Applies a bluck colelctino of pressorce at once
|
|
||||
/// </summary>
|
|
||||
/// <param name="processors">Processors to apply</param>
|
|
||||
/// <returns>this </returns>
|
|
||||
public IImageOperations<TPixel> ApplyProcessors(IEnumerable<IImageProcessor<TPixel>> processors) |
|
||||
{ |
|
||||
foreach (var processor in processors) |
|
||||
{ |
|
||||
return this.ApplyProcessor(processor); |
|
||||
} |
|
||||
|
|
||||
return this; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue