mirror of https://github.com/SixLabors/ImageSharp
Browse Source
THIS WON'T BUILD JUST NOW. Former-commit-id: 0392cced86a9ee8dd5f8139fad5c465a83171562af/merge-core
48 changed files with 1659 additions and 526 deletions
@ -0,0 +1,90 @@ |
|||||
|
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
// <copyright file="ParameterParserUtilities.cs" company="James South">
|
||||
|
// Copyright (c) James South.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>
|
||||
|
// <summary>
|
||||
|
// Encapsulates methods to correctly parse querystring parameters.
|
||||
|
// </summary>
|
||||
|
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
|
||||
|
namespace ImageProcessor.Web.Helpers |
||||
|
{ |
||||
|
using System.Drawing; |
||||
|
using System.Globalization; |
||||
|
using System.Text.RegularExpressions; |
||||
|
using ImageProcessor.Core.Common.Extensions; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Encapsulates methods to correctly parse querystring parameters.
|
||||
|
/// </summary>
|
||||
|
public static class ParameterParserUtilities |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// The regular expression to search strings for colors.
|
||||
|
/// </summary>
|
||||
|
private static readonly Regex ColorRegex = new Regex(@"(bgcolor|color)(=|-)(\d+,\d+,\d+,\d+|([0-9a-fA-F]{3}){1,2})", RegexOptions.Compiled); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// The regular expression to search strings for angles.
|
||||
|
/// </summary>
|
||||
|
private static readonly Regex AngleRegex = new Regex(@"(rotate|angle)(=|-)(?:3[0-5][0-9]|[12][0-9]{2}|[1-9][0-9]?)", RegexOptions.Compiled); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Returns the correct <see cref="T:System.Int32"/> containing the angle for the given string.
|
||||
|
/// </summary>
|
||||
|
/// <param name="input">
|
||||
|
/// The input string containing the value to parse.
|
||||
|
/// </param>
|
||||
|
/// <returns>
|
||||
|
/// The correct <see cref="T:System.Int32"/> containing the angle for the given string.
|
||||
|
/// </returns>
|
||||
|
public static int ParseAngle(string input) |
||||
|
{ |
||||
|
foreach (Match match in AngleRegex.Matches(input)) |
||||
|
{ |
||||
|
// Split on angle
|
||||
|
int angle; |
||||
|
string value = match.Value.Split(new[] { '=', '-' })[1]; |
||||
|
int.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out angle); |
||||
|
return angle; |
||||
|
} |
||||
|
|
||||
|
// No rotate - matches the RotateLayer default.
|
||||
|
return 0; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Returns the correct <see cref="T:System.Drawing.Color"/> for the given string.
|
||||
|
/// </summary>
|
||||
|
/// <param name="input">
|
||||
|
/// The input string containing the value to parse.
|
||||
|
/// </param>
|
||||
|
/// <returns>
|
||||
|
/// The correct <see cref="T:System.Drawing.Color"/>
|
||||
|
/// </returns>
|
||||
|
public static Color ParseColor(string input) |
||||
|
{ |
||||
|
foreach (Match match in ColorRegex.Matches(input)) |
||||
|
{ |
||||
|
string value = match.Value.Split(new[] { '=', '-' })[1]; |
||||
|
|
||||
|
if (value.Contains(",")) |
||||
|
{ |
||||
|
int[] split = value.ToPositiveIntegerArray(); |
||||
|
byte red = split[0].ToByte(); |
||||
|
byte green = split[1].ToByte(); |
||||
|
byte blue = split[2].ToByte(); |
||||
|
byte alpha = split[3].ToByte(); |
||||
|
|
||||
|
return Color.FromArgb(alpha, red, green, blue); |
||||
|
} |
||||
|
|
||||
|
// Split on color-hex
|
||||
|
return ColorTranslator.FromHtml("#" + value); |
||||
|
} |
||||
|
|
||||
|
return Color.Transparent; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,88 @@ |
|||||
|
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
// <copyright file="BackgroundColor.cs" company="James South">
|
||||
|
// Copyright (c) James South.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>
|
||||
|
// <summary>
|
||||
|
// Changes the background color of an image.
|
||||
|
// </summary>
|
||||
|
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
|
||||
|
namespace ImageProcessor.Web.Processors |
||||
|
{ |
||||
|
using System.Text.RegularExpressions; |
||||
|
using ImageProcessor.Processors; |
||||
|
using ImageProcessor.Web.Helpers; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Changes the background color of an image.
|
||||
|
/// </summary>
|
||||
|
public class BackgroundColor : IWebGraphicsProcessor |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// The regular expression to search strings for.
|
||||
|
/// </summary>
|
||||
|
private static readonly Regex QueryRegex = new Regex(@"bgcolor(=|-)[^&|,]*", RegexOptions.Compiled); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="BackgroundColor"/> class.
|
||||
|
/// </summary>
|
||||
|
public BackgroundColor() |
||||
|
{ |
||||
|
this.Processor = new ImageProcessor.Processors.BackgroundColor(); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the regular expression to search strings for.
|
||||
|
/// </summary>
|
||||
|
public Regex RegexPattern |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
return QueryRegex; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the order in which this processor is to be used in a chain.
|
||||
|
/// </summary>
|
||||
|
public int SortOrder { get; private set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the associated graphics processor.
|
||||
|
/// </summary>
|
||||
|
public IGraphicsProcessor Processor { get; private set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// The position in the original string where the first character of the captured substring was found.
|
||||
|
/// </summary>
|
||||
|
/// <param name="queryString">The query string to search.</param>
|
||||
|
/// <returns>
|
||||
|
/// The zero-based starting position in the original string where the captured substring was found.
|
||||
|
/// </returns>
|
||||
|
public int MatchRegexIndex(string queryString) |
||||
|
{ |
||||
|
int index = 0; |
||||
|
|
||||
|
// Set the sort order to max to allow filtering.
|
||||
|
this.SortOrder = int.MaxValue; |
||||
|
|
||||
|
foreach (Match match in this.RegexPattern.Matches(queryString)) |
||||
|
{ |
||||
|
if (match.Success) |
||||
|
{ |
||||
|
if (index == 0) |
||||
|
{ |
||||
|
// Set the index on the first instance only.
|
||||
|
this.SortOrder = match.Index; |
||||
|
this.Processor.DynamicParameter = ParameterParserUtilities.ParseColor(match.Value); |
||||
|
} |
||||
|
|
||||
|
index += 1; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return this.SortOrder; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,51 @@ |
|||||
|
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
// <copyright file="IWebGraphicsProcessor.cs" company="James South">
|
||||
|
// Copyright (c) James South.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>
|
||||
|
// <summary>
|
||||
|
// Defines properties and methods for ImageProcessor.Web Plugins.
|
||||
|
// </summary>
|
||||
|
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
|
||||
|
namespace ImageProcessor.Web.Processors |
||||
|
{ |
||||
|
using System.Text.RegularExpressions; |
||||
|
using ImageProcessor.Processors; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Defines properties and methods for ImageProcessor.Web Plugins.
|
||||
|
/// </summary>
|
||||
|
public interface IWebGraphicsProcessor |
||||
|
{ |
||||
|
#region Properties
|
||||
|
/// <summary>
|
||||
|
/// Gets the regular expression to search strings for.
|
||||
|
/// </summary>
|
||||
|
Regex RegexPattern { get; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the order in which this processor is to be used in a chain.
|
||||
|
/// </summary>
|
||||
|
int SortOrder { get; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the associated graphics processor.
|
||||
|
/// </summary>
|
||||
|
IGraphicsProcessor Processor { get; } |
||||
|
#endregion
|
||||
|
|
||||
|
#region Methods
|
||||
|
/// <summary>
|
||||
|
/// The position in the original string where the first character of the captured substring was found.
|
||||
|
/// </summary>
|
||||
|
/// <param name="queryString">
|
||||
|
/// The query string to search.
|
||||
|
/// </param>
|
||||
|
/// <returns>
|
||||
|
/// The zero-based starting position in the original string where the captured substring was found.
|
||||
|
/// </returns>
|
||||
|
int MatchRegexIndex(string queryString); |
||||
|
#endregion
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,96 @@ |
|||||
|
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
// <copyright file="Rotate.cs" company="James South">
|
||||
|
// Copyright (c) James South.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>
|
||||
|
// <summary>
|
||||
|
// Encapsulates methods to rotate an image.
|
||||
|
// </summary>
|
||||
|
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
|
||||
|
namespace ImageProcessor.Web.Processors |
||||
|
{ |
||||
|
using System.Text.RegularExpressions; |
||||
|
using ImageProcessor.Processors; |
||||
|
using ImageProcessor.Web.Helpers; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Encapsulates methods to rotate an image.
|
||||
|
/// </summary>
|
||||
|
public class Rotate : IWebGraphicsProcessor |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// The regular expression to search strings for.
|
||||
|
/// </summary>
|
||||
|
private static readonly Regex QueryRegex = new Regex(@"(rotate|angle)(=|-)[^&|,]*", RegexOptions.Compiled); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="Rotate"/> class.
|
||||
|
/// </summary>
|
||||
|
public Rotate() |
||||
|
{ |
||||
|
this.Processor = new ImageProcessor.Processors.Rotate(); |
||||
|
} |
||||
|
|
||||
|
#region IGraphicsProcessor Members
|
||||
|
/// <summary>
|
||||
|
/// Gets the regular expression to search strings for.
|
||||
|
/// </summary>
|
||||
|
public Regex RegexPattern |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
return QueryRegex; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the order in which this processor is to be used in a chain.
|
||||
|
/// </summary>
|
||||
|
public int SortOrder |
||||
|
{ |
||||
|
get; |
||||
|
private set; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the associated graphics processor.
|
||||
|
/// </summary>
|
||||
|
public IGraphicsProcessor Processor { get; private set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// The position in the original string where the first character of the captured substring was found.
|
||||
|
/// </summary>
|
||||
|
/// <param name="queryString">
|
||||
|
/// The query string to search.
|
||||
|
/// </param>
|
||||
|
/// <returns>
|
||||
|
/// The zero-based starting position in the original string where the captured substring was found.
|
||||
|
/// </returns>
|
||||
|
public int MatchRegexIndex(string queryString) |
||||
|
{ |
||||
|
int index = 0; |
||||
|
|
||||
|
// Set the sort order to max to allow filtering.
|
||||
|
this.SortOrder = int.MaxValue; |
||||
|
|
||||
|
foreach (Match match in this.RegexPattern.Matches(queryString)) |
||||
|
{ |
||||
|
if (match.Success) |
||||
|
{ |
||||
|
if (index == 0) |
||||
|
{ |
||||
|
// Set the index on the first instance only.
|
||||
|
this.SortOrder = match.Index; |
||||
|
this.Processor.DynamicParameter = ParameterParserUtilities.ParseAngle(match.Value); |
||||
|
} |
||||
|
|
||||
|
index += 1; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return this.SortOrder; |
||||
|
} |
||||
|
#endregion
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,24 @@ |
|||||
|
|
||||
|
namespace ImageProcessor.Web.Processors |
||||
|
{ |
||||
|
using System; |
||||
|
using System.Text.RegularExpressions; |
||||
|
using ImageProcessor.Processors; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Encapsulates methods to add rounded corners to an image.
|
||||
|
/// </summary>
|
||||
|
public class RoundedCorners : IWebGraphicsProcessor |
||||
|
{ |
||||
|
public Regex RegexPattern { get; private set; } |
||||
|
|
||||
|
public int SortOrder { get; private set; } |
||||
|
|
||||
|
public IGraphicsProcessor Processor { get; private set; } |
||||
|
|
||||
|
public int MatchRegexIndex(string queryString) |
||||
|
{ |
||||
|
throw new NotImplementedException(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,81 @@ |
|||||
|
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
// <copyright file="ImageProcessorBootstrapper.cs" company="James South">
|
||||
|
// Copyright (c) James South.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>
|
||||
|
// <summary>
|
||||
|
// The image processor bootstrapper.
|
||||
|
// </summary>
|
||||
|
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
|
||||
|
namespace ImageProcessor.Configuration |
||||
|
{ |
||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using ImageProcessor.Core.Common.Exceptions; |
||||
|
using ImageProcessor.Imaging.Formats; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// The image processor bootstrapper.
|
||||
|
/// </summary>
|
||||
|
public class ImageProcessorBootstrapper |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// A new instance Initializes a new instance of the <see cref="ImageProcessorBootstrapper"/> class.
|
||||
|
/// with lazy initialization.
|
||||
|
/// </summary>
|
||||
|
private static readonly Lazy<ImageProcessorBootstrapper> Lazy = |
||||
|
new Lazy<ImageProcessorBootstrapper>(() => new ImageProcessorBootstrapper()); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Prevents a default instance of the <see cref="ImageProcessorBootstrapper"/> class from being created.
|
||||
|
/// </summary>
|
||||
|
private ImageProcessorBootstrapper() |
||||
|
{ |
||||
|
this.LoadSupportedImageFormats(); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the current instance of the <see cref="ImageProcessorBootstrapper"/> class.
|
||||
|
/// </summary>
|
||||
|
public static ImageProcessorBootstrapper Instance |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
return Lazy.Value; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the supported image formats.
|
||||
|
/// </summary>
|
||||
|
public IEnumerable<ISupportedImageFormat> SupportedImageFormats { get; private set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Creates a list, using reflection, of supported image formats that ImageProcessor can run.
|
||||
|
/// </summary>
|
||||
|
private void LoadSupportedImageFormats() |
||||
|
{ |
||||
|
if (this.SupportedImageFormats == null) |
||||
|
{ |
||||
|
try |
||||
|
{ |
||||
|
Type type = typeof(ISupportedImageFormat); |
||||
|
List<Type> availableTypes = AppDomain.CurrentDomain |
||||
|
.GetAssemblies() |
||||
|
.SelectMany(s => s.GetTypes()) |
||||
|
.Where(t => t != null && type.IsAssignableFrom(t) && t.IsClass && !t.IsAbstract) |
||||
|
.ToList(); |
||||
|
|
||||
|
this.SupportedImageFormats = availableTypes |
||||
|
.Select(x => (Activator.CreateInstance(x) as ISupportedImageFormat)).ToList(); |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
throw new ImageFormatException(ex.Message, ex.InnerException); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,39 @@ |
|||||
|
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
// <copyright file="ImageFormatException.cs" company="James South">
|
||||
|
// Copyright (c) James South.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>
|
||||
|
// <summary>
|
||||
|
// The exception that is thrown when loading the supported image format types has failed.
|
||||
|
// </summary>
|
||||
|
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
|
||||
|
namespace ImageProcessor.Core.Common.Exceptions |
||||
|
{ |
||||
|
using System; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// The exception that is thrown when loading the supported image format types has failed.
|
||||
|
/// </summary>
|
||||
|
public sealed class ImageFormatException : Exception |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="ImageFormatException"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="message">The message that describes the error.</param>
|
||||
|
public ImageFormatException(string message) |
||||
|
: base(message) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="ImageFormatException"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="message">The error message that explains the reason for the exception.</param>
|
||||
|
/// <param name="innerException">The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified.</param>
|
||||
|
public ImageFormatException(string message, Exception innerException) |
||||
|
: base(message, innerException) |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,39 @@ |
|||||
|
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
// <copyright file="ImageProcessingException.cs" company="James South">
|
||||
|
// Copyright (c) James South.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>
|
||||
|
// <summary>
|
||||
|
// The exception that is thrown when processing an image has failed.
|
||||
|
// </summary>
|
||||
|
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
|
||||
|
namespace ImageProcessor.Core.Common.Exceptions |
||||
|
{ |
||||
|
using System; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// The exception that is thrown when processing an image has failed.
|
||||
|
/// </summary>
|
||||
|
public sealed class ImageProcessingException : Exception |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="ImageProcessingException"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="message">The message that describes the error.</param>
|
||||
|
public ImageProcessingException(string message) |
||||
|
: base(message) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="ImageProcessingException"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="message">The error message that explains the reason for the exception.</param>
|
||||
|
/// <param name="innerException">The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified.</param>
|
||||
|
public ImageProcessingException(string message, Exception innerException) |
||||
|
: base(message, innerException) |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,65 @@ |
|||||
|
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
// <copyright file="BitmapFormat.cs" company="James South">
|
||||
|
// Copyright (c) James South.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>
|
||||
|
// <summary>
|
||||
|
// Provides the necessary information to support bitmap images.
|
||||
|
// </summary>
|
||||
|
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
|
||||
|
namespace ImageProcessor.Imaging.Formats |
||||
|
{ |
||||
|
using System.Drawing.Imaging; |
||||
|
using System.Text; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Provides the necessary information to support bitmap images.
|
||||
|
/// </summary>
|
||||
|
public class BitmapFormat : FormatBase |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Gets the file header.
|
||||
|
/// </summary>
|
||||
|
public override byte[] FileHeader |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
return Encoding.ASCII.GetBytes("BM"); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the list of file extensions.
|
||||
|
/// </summary>
|
||||
|
public override string[] FileExtensions |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
return new[] { "bmp" }; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the standard identifier used on the Internet to indicate the type of data that a file contains.
|
||||
|
/// </summary>
|
||||
|
public override string MimeType |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
return "image/bmp"; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the <see cref="ImageFormat" />.
|
||||
|
/// </summary>
|
||||
|
public override ImageFormat ImageFormat |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
return ImageFormat.Bmp; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,123 @@ |
|||||
|
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
// <copyright file="FormatBase.cs" company="James South">
|
||||
|
// Copyright (c) James South.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>
|
||||
|
// <summary>
|
||||
|
// The supported format base implement this class when building a supported format.
|
||||
|
// </summary>
|
||||
|
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
|
||||
|
namespace ImageProcessor.Imaging.Formats |
||||
|
{ |
||||
|
using System; |
||||
|
using System.Drawing; |
||||
|
using System.Drawing.Imaging; |
||||
|
using System.IO; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// The supported format base. Implement this class when building a supported format.
|
||||
|
/// </summary>
|
||||
|
public abstract class FormatBase : ISupportedImageFormat |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Gets the file header.
|
||||
|
/// </summary>
|
||||
|
public abstract byte[] FileHeader { get; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the list of file extensions.
|
||||
|
/// </summary>
|
||||
|
public abstract string[] FileExtensions { get; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the standard identifier used on the Internet to indicate the type of data that a file contains.
|
||||
|
/// </summary>
|
||||
|
public abstract string MimeType { get; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the default file extension.
|
||||
|
/// </summary>
|
||||
|
public string DefaultExtension |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
return this.MimeType.Replace("image/", string.Empty); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the file format of the image.
|
||||
|
/// </summary>
|
||||
|
public abstract ImageFormat ImageFormat { get; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets or sets a value indicating whether the image format is indexed.
|
||||
|
/// </summary>
|
||||
|
public bool IsIndexed { get; set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets or sets a value indicating whether the image format is animated.
|
||||
|
/// </summary>
|
||||
|
public bool IsAnimated { get; set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets or sets the quality of output for images.
|
||||
|
/// </summary>
|
||||
|
public int Quality { get; set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Applies the given processor the current image.
|
||||
|
/// </summary>
|
||||
|
/// <param name="processor">The processor delegate.</param>
|
||||
|
/// <param name="factory">The <see cref="ImageFactory" />.</param>
|
||||
|
public virtual void ApplyProcessor(Func<ImageFactory, Image> processor, ImageFactory factory) |
||||
|
{ |
||||
|
processor.Invoke(factory); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Decodes the image to process.
|
||||
|
/// </summary>
|
||||
|
/// <param name="stream">
|
||||
|
/// The <see cref="T:System.IO.stream" /> containing the image information.
|
||||
|
/// </param>
|
||||
|
/// <returns>
|
||||
|
/// The the <see cref="T:System.Drawing.Image" />.
|
||||
|
/// </returns>
|
||||
|
public virtual Image Load(Stream stream) |
||||
|
{ |
||||
|
return Image.FromStream(stream, true); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Saves the current image to the specified output stream.
|
||||
|
/// </summary>
|
||||
|
/// <param name="memoryStream">The <see cref="T:System.IO.MemoryStream" /> to save the image information to.</param>
|
||||
|
/// <param name="image">The <see cref="T:System.Drawing.Image" /> to save.</param>
|
||||
|
/// <returns>
|
||||
|
/// The <see cref="T:System.Drawing.Image" />.
|
||||
|
/// </returns>
|
||||
|
public virtual Image Save(MemoryStream memoryStream, Image image) |
||||
|
{ |
||||
|
image.Save(memoryStream, this.ImageFormat); |
||||
|
memoryStream.Position = 0; |
||||
|
return image; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Saves the current image to the specified file path.
|
||||
|
/// </summary>
|
||||
|
/// <param name="path">The path to save the image to.</param>
|
||||
|
/// <param name="image">The
|
||||
|
/// <see cref="T:System.Drawing.Image" /> to save.</param>
|
||||
|
/// <returns>
|
||||
|
/// The <see cref="T:System.Drawing.Image" />.
|
||||
|
/// </returns>
|
||||
|
public virtual Image Save(string path, Image image) |
||||
|
{ |
||||
|
image.Save(path, this.ImageFormat); |
||||
|
return image; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,88 @@ |
|||||
|
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
// <copyright file="FormatUtilities.cs" company="James South">
|
||||
|
// Copyright (c) James South.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>
|
||||
|
// <summary>
|
||||
|
// Utility methods for working with supported image formats.
|
||||
|
// </summary>
|
||||
|
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
|
||||
|
namespace ImageProcessor.Imaging.Formats |
||||
|
{ |
||||
|
using System.Collections.Generic; |
||||
|
using System.Drawing; |
||||
|
using System.Drawing.Imaging; |
||||
|
using System.IO; |
||||
|
using System.Linq; |
||||
|
using ImageProcessor.Configuration; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Utility methods for working with supported image formats.
|
||||
|
/// </summary>
|
||||
|
public static class FormatUtilities |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Gets the correct <see cref="ISupportedImageFormat"/> from the given stream.
|
||||
|
/// <see cref="http://stackoverflow.com/questions/55869/determine-file-type-of-an-image"/>
|
||||
|
/// </summary>
|
||||
|
/// <param name="stream">
|
||||
|
/// The <see cref="System.IO.Stream"/> to read from.
|
||||
|
/// </param>
|
||||
|
/// <returns>
|
||||
|
/// The <see cref="ISupportedImageFormat"/>.
|
||||
|
/// </returns>
|
||||
|
public static ISupportedImageFormat GetFormat(Stream stream) |
||||
|
{ |
||||
|
IEnumerable<ISupportedImageFormat> supportedImageFormats = |
||||
|
ImageProcessorBootstrapper.Instance.SupportedImageFormats; |
||||
|
|
||||
|
byte[] buffer = new byte[4]; |
||||
|
stream.Read(buffer, 0, buffer.Length); |
||||
|
|
||||
|
// ReSharper disable once LoopCanBeConvertedToQuery
|
||||
|
foreach (ISupportedImageFormat supportedImageFormat in supportedImageFormats) |
||||
|
{ |
||||
|
byte[] header = supportedImageFormat.FileHeader; |
||||
|
if (header.SequenceEqual(buffer.Take(header.Length))) |
||||
|
{ |
||||
|
stream.Position = 0; |
||||
|
return supportedImageFormat; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
stream.Position = 0; |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Returns a value indicating whether the given image is indexed.
|
||||
|
/// </summary>
|
||||
|
/// <param name="image">
|
||||
|
/// The <see cref="System.Drawing.Image"/> to test.
|
||||
|
/// </param>
|
||||
|
/// <returns>
|
||||
|
/// The true if the image is indexed; otherwise, false.
|
||||
|
/// </returns>
|
||||
|
public static bool IsIndexed(Image image) |
||||
|
{ |
||||
|
// Test value of flags using bitwise AND.
|
||||
|
// ReSharper disable once BitwiseOperatorOnEnumWithoutFlags
|
||||
|
return (image.PixelFormat & PixelFormat.Indexed) != 0; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Returns a value indicating whether the given image is indexed.
|
||||
|
/// </summary>
|
||||
|
/// <param name="image">
|
||||
|
/// The <see cref="System.Drawing.Image"/> to test.
|
||||
|
/// </param>
|
||||
|
/// <returns>
|
||||
|
/// The true if the image is animated; otherwise, false.
|
||||
|
/// </returns>
|
||||
|
public static bool IsAnimated(Image image) |
||||
|
{ |
||||
|
return ImageAnimator.CanAnimate(image); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,149 @@ |
|||||
|
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
// <copyright file="GifFormat.cs" company="James South">
|
||||
|
// Copyright (c) James South.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>
|
||||
|
// <summary>
|
||||
|
// Provides the necessary information to support gif images.
|
||||
|
// </summary>
|
||||
|
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
|
||||
|
namespace ImageProcessor.Imaging.Formats |
||||
|
{ |
||||
|
using System; |
||||
|
using System.Drawing; |
||||
|
using System.Drawing.Imaging; |
||||
|
using System.IO; |
||||
|
using System.Text; |
||||
|
using ImageProcessor.Core.Common.Extensions; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Provides the necessary information to support gif images.
|
||||
|
/// </summary>
|
||||
|
public class GifFormat : FormatBase |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Gets the file header.
|
||||
|
/// </summary>
|
||||
|
public override byte[] FileHeader |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
return Encoding.ASCII.GetBytes("GIF"); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the list of file extensions.
|
||||
|
/// </summary>
|
||||
|
public override string[] FileExtensions |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
return new[] { "gif" }; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the standard identifier used on the Internet to indicate the type of data that a file contains.
|
||||
|
/// </summary>
|
||||
|
public override string MimeType |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
return "image/gif"; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the <see cref="ImageFormat" />.
|
||||
|
/// </summary>
|
||||
|
public override ImageFormat ImageFormat |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
return ImageFormat.Gif; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Applies the given processor the current image.
|
||||
|
/// </summary>
|
||||
|
/// <param name="processor">The processor delegate.</param>
|
||||
|
/// <param name="factory">The <see cref="ImageFactory" />.</param>
|
||||
|
public override void ApplyProcessor(Func<ImageFactory, Image> processor, ImageFactory factory) |
||||
|
{ |
||||
|
ImageInfo imageInfo = factory.Image.GetImageInfo(this.ImageFormat); |
||||
|
|
||||
|
if (imageInfo.IsAnimated) |
||||
|
{ |
||||
|
OctreeQuantizer quantizer = new OctreeQuantizer(255, 8); |
||||
|
|
||||
|
// We don't dispose of the memory stream as that is disposed when a new image is created and doing so
|
||||
|
// beforehand will cause an exception.
|
||||
|
MemoryStream stream = new MemoryStream(); |
||||
|
using (GifEncoder encoder = new GifEncoder(stream, null, null, imageInfo.LoopCount)) |
||||
|
{ |
||||
|
foreach (GifFrame frame in imageInfo.GifFrames) |
||||
|
{ |
||||
|
factory.Update(frame.Image); |
||||
|
frame.Image = quantizer.Quantize(processor.Invoke(factory)); |
||||
|
encoder.AddFrame(frame); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
stream.Position = 0; |
||||
|
factory.Update(Image.FromStream(stream)); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
base.ApplyProcessor(processor, factory); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Saves the current image to the specified output stream.
|
||||
|
/// </summary>
|
||||
|
/// <param name="memoryStream">
|
||||
|
/// The <see cref="T:System.IO.MemoryStream" /> to save the image information to.
|
||||
|
/// </param>
|
||||
|
/// <param name="image">The <see cref="T:System.Drawing.Image" /> to save.</param>
|
||||
|
/// <returns>
|
||||
|
/// The <see cref="T:System.Drawing.Image" />.
|
||||
|
/// </returns>
|
||||
|
public override Image Save(MemoryStream memoryStream, Image image) |
||||
|
{ |
||||
|
// TODO: Move this in here. It doesn't need to be anywhere else.
|
||||
|
ImageInfo imageInfo = image.GetImageInfo(this.ImageFormat, false); |
||||
|
|
||||
|
if (!imageInfo.IsAnimated) |
||||
|
{ |
||||
|
image = new OctreeQuantizer(255, 8).Quantize(image); |
||||
|
} |
||||
|
|
||||
|
return base.Save(memoryStream, image); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Saves the current image to the specified file path.
|
||||
|
/// </summary>
|
||||
|
/// <param name="path">The path to save the image to.</param>
|
||||
|
/// <param name="image">The
|
||||
|
/// <see cref="T:System.Drawing.Image" /> to save.</param>
|
||||
|
/// <returns>
|
||||
|
/// The <see cref="T:System.Drawing.Image" />.
|
||||
|
/// </returns>
|
||||
|
public override Image Save(string path, Image image) |
||||
|
{ |
||||
|
// TODO: Move this in here. It doesn't need to be anywhere else.
|
||||
|
ImageInfo imageInfo = image.GetImageInfo(this.ImageFormat, false); |
||||
|
|
||||
|
if (!imageInfo.IsAnimated) |
||||
|
{ |
||||
|
image = new OctreeQuantizer(255, 8).Quantize(image); |
||||
|
} |
||||
|
|
||||
|
return base.Save(path, image); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,113 @@ |
|||||
|
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
// <copyright file="ISupportedImageFormat.cs" company="James South">
|
||||
|
// Copyright (c) James South.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>
|
||||
|
// <summary>
|
||||
|
// The SupportedImageFormat interface providing information about image formats to ImageProcessor.
|
||||
|
// </summary>
|
||||
|
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
|
||||
|
namespace ImageProcessor.Imaging.Formats |
||||
|
{ |
||||
|
using System; |
||||
|
using System.Drawing; |
||||
|
using System.Drawing.Imaging; |
||||
|
using System.IO; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// The SupportedImageFormat interface providing information about image formats to ImageProcessor.
|
||||
|
/// </summary>
|
||||
|
public interface ISupportedImageFormat |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Gets the file header.
|
||||
|
/// </summary>
|
||||
|
byte[] FileHeader { get; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the list of file extensions.
|
||||
|
/// </summary>
|
||||
|
string[] FileExtensions { get; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the standard identifier used on the Internet to indicate the type of data that a file contains.
|
||||
|
/// </summary>
|
||||
|
string MimeType { get; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the default file extension.
|
||||
|
/// </summary>
|
||||
|
string DefaultExtension { get; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the file format of the image.
|
||||
|
/// </summary>
|
||||
|
ImageFormat ImageFormat { get; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets or sets a value indicating whether the image format is indexed.
|
||||
|
/// </summary>
|
||||
|
bool IsIndexed { get; set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets or sets a value indicating whether the image format is animated.
|
||||
|
/// </summary>
|
||||
|
bool IsAnimated { get; set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets or sets the quality of output for images.
|
||||
|
/// </summary>
|
||||
|
int Quality { get; set; } |
||||
|
|
||||
|
#region Methods
|
||||
|
/// <summary>
|
||||
|
/// Applies the given processor the current image.
|
||||
|
/// </summary>
|
||||
|
/// <param name="processor">
|
||||
|
/// The processor delegate.
|
||||
|
/// </param>
|
||||
|
/// <param name="factory">
|
||||
|
/// The <see cref="ImageFactory"/>.
|
||||
|
/// </param>
|
||||
|
void ApplyProcessor(Func<ImageFactory, Image> processor, ImageFactory factory); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Loads the image to process.
|
||||
|
/// </summary>
|
||||
|
/// <param name="stream">
|
||||
|
/// The <see cref="T:System.IO.Stream"/> containing the image information.
|
||||
|
/// </param>
|
||||
|
/// <returns>
|
||||
|
/// The <see cref="T:System.Drawing.Image"/>.
|
||||
|
/// </returns>
|
||||
|
Image Load(Stream stream); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Saves the current image to the specified output stream.
|
||||
|
/// </summary>
|
||||
|
/// <param name="memoryStream">
|
||||
|
/// The <see cref="T:System.IO.MemoryStream"/> to save the image information to.
|
||||
|
/// </param>
|
||||
|
/// <param name="image">
|
||||
|
/// The <see cref="T:System.Drawing.Image"/> to save.
|
||||
|
/// </param>
|
||||
|
/// <returns>
|
||||
|
/// The <see cref="T:System.Drawing.Image"/>.
|
||||
|
/// </returns>
|
||||
|
Image Save(MemoryStream memoryStream, Image image); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Saves the current image to the specified file path.
|
||||
|
/// </summary>
|
||||
|
/// <param name="path">The path to save the image to.</param>
|
||||
|
/// <param name="image">
|
||||
|
/// The <see cref="T:System.Drawing.Image"/> to save.
|
||||
|
/// </param>
|
||||
|
/// <returns>
|
||||
|
/// The <see cref="T:System.Drawing.Image"/>.
|
||||
|
/// </returns>
|
||||
|
Image Save(string path, Image image); |
||||
|
#endregion
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,155 @@ |
|||||
|
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
// <copyright file="JpegFormat.cs" company="James South">
|
||||
|
// Copyright (c) James South.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>
|
||||
|
// <summary>
|
||||
|
// Provides the necessary information to support jpeg images.
|
||||
|
// </summary>
|
||||
|
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
|
||||
|
namespace ImageProcessor.Imaging.Formats |
||||
|
{ |
||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Drawing; |
||||
|
using System.Drawing.Imaging; |
||||
|
using System.IO; |
||||
|
using System.Linq; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Provides the necessary information to support jpeg images.
|
||||
|
/// </summary>
|
||||
|
public sealed class JpegFormat : FormatBase |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Gets the file header.
|
||||
|
/// </summary>
|
||||
|
public override byte[] FileHeader |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
return new byte[] { 255, 216, 255, 224 }; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the list of file extensions.
|
||||
|
/// </summary>
|
||||
|
public override string[] FileExtensions |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
return new[] { "jpeg", "jpg" }; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the standard identifier used on the Internet to indicate the type of data that a file contains.
|
||||
|
/// </summary>
|
||||
|
public override string MimeType |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
return "image/jpeg"; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the <see cref="ImageFormat" />.
|
||||
|
/// </summary>
|
||||
|
public override ImageFormat ImageFormat |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
return ImageFormat.Jpeg; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Applies the given processor the current image.
|
||||
|
/// </summary>
|
||||
|
/// <param name="processor">The processor delegate.</param>
|
||||
|
/// <param name="factory">The <see cref="ImageFactory" />.</param>
|
||||
|
public override void ApplyProcessor(Func<ImageFactory, Image> processor, ImageFactory factory) |
||||
|
{ |
||||
|
base.ApplyProcessor(processor, factory); |
||||
|
|
||||
|
// Set the property item information from any Exif metadata.
|
||||
|
// We do this here so that they can be changed between processor methods.
|
||||
|
if (factory.PreserveExifData) |
||||
|
{ |
||||
|
foreach (KeyValuePair<int, PropertyItem> propertItem in factory.ExifPropertyItems) |
||||
|
{ |
||||
|
try |
||||
|
{ |
||||
|
factory.Image.SetPropertyItem(propertItem.Value); |
||||
|
} |
||||
|
// ReSharper disable once EmptyGeneralCatchClause
|
||||
|
catch |
||||
|
{ |
||||
|
// Do nothing. The image format does not handle EXIF data.
|
||||
|
// TODO: empty catch is fierce code smell.
|
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Saves the current image to the specified output stream.
|
||||
|
/// </summary>
|
||||
|
/// <param name="memoryStream">
|
||||
|
/// The <see cref="T:System.IO.MemoryStream" /> to save the image information to.
|
||||
|
/// </param>
|
||||
|
/// <param name="image">The <see cref="T:System.Drawing.Image" /> to save.</param>
|
||||
|
/// <returns>
|
||||
|
/// The <see cref="T:System.Drawing.Image" />.
|
||||
|
/// </returns>
|
||||
|
public override Image Save(MemoryStream memoryStream, Image image) |
||||
|
{ |
||||
|
// Jpegs can be saved with different settings to include a quality setting for the JPEG compression.
|
||||
|
// This improves output compression and quality.
|
||||
|
using (EncoderParameters encoderParameters = ImageUtils.GetEncodingParameters(this.Quality)) |
||||
|
{ |
||||
|
ImageCodecInfo imageCodecInfo = |
||||
|
ImageCodecInfo.GetImageEncoders() |
||||
|
.FirstOrDefault(ici => ici.MimeType.Equals(this.MimeType, StringComparison.OrdinalIgnoreCase)); |
||||
|
|
||||
|
if (imageCodecInfo != null) |
||||
|
{ |
||||
|
image.Save(memoryStream, imageCodecInfo, encoderParameters); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return image; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Saves the current image to the specified file path.
|
||||
|
/// </summary>
|
||||
|
/// <param name="path">The path to save the image to.</param>
|
||||
|
/// <param name="image">The
|
||||
|
/// <see cref="T:System.Drawing.Image" /> to save.</param>
|
||||
|
/// <returns>
|
||||
|
/// The <see cref="T:System.Drawing.Image" />.
|
||||
|
/// </returns>
|
||||
|
public override Image Save(string path, Image image) |
||||
|
{ |
||||
|
// Jpegs can be saved with different settings to include a quality setting for the JPEG compression.
|
||||
|
// This improves output compression and quality.
|
||||
|
using (EncoderParameters encoderParameters = ImageUtils.GetEncodingParameters(this.Quality)) |
||||
|
{ |
||||
|
ImageCodecInfo imageCodecInfo = |
||||
|
ImageCodecInfo.GetImageEncoders() |
||||
|
.FirstOrDefault(ici => ici.MimeType.Equals(this.MimeType, StringComparison.OrdinalIgnoreCase)); |
||||
|
|
||||
|
if (imageCodecInfo != null) |
||||
|
{ |
||||
|
image.Save(path, imageCodecInfo, encoderParameters); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return image; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,103 @@ |
|||||
|
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
// <copyright file="PngFormat.cs" company="James South">
|
||||
|
// Copyright (c) James South.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>
|
||||
|
// <summary>
|
||||
|
// Provides the necessary information to support png images.
|
||||
|
// </summary>
|
||||
|
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
|
||||
|
namespace ImageProcessor.Imaging.Formats |
||||
|
{ |
||||
|
using System.Drawing; |
||||
|
using System.Drawing.Imaging; |
||||
|
using System.IO; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Provides the necessary information to support png images.
|
||||
|
/// </summary>
|
||||
|
public class PngFormat : FormatBase |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Gets the file header.
|
||||
|
/// </summary>
|
||||
|
public override byte[] FileHeader |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
return new byte[] { 137, 80, 78, 71 }; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the list of file extensions.
|
||||
|
/// </summary>
|
||||
|
public override string[] FileExtensions |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
return new[] { "png" }; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the standard identifier used on the Internet to indicate the type of data that a file contains.
|
||||
|
/// </summary>
|
||||
|
public override string MimeType |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
return "image/png"; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the <see cref="ImageFormat" />.
|
||||
|
/// </summary>
|
||||
|
public override ImageFormat ImageFormat |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
return ImageFormat.Png; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Saves the current image to the specified output stream.
|
||||
|
/// </summary>
|
||||
|
/// <param name="memoryStream">The <see cref="T:System.IO.MemoryStream" /> to save the image information to.</param>
|
||||
|
/// <param name="image">The <see cref="T:System.Drawing.Image" /> to save.</param>
|
||||
|
/// <returns>
|
||||
|
/// The <see cref="T:System.Drawing.Image" />.
|
||||
|
/// </returns>
|
||||
|
public override Image Save(MemoryStream memoryStream, Image image) |
||||
|
{ |
||||
|
if (FormatUtilities.IsIndexed(image)) |
||||
|
{ |
||||
|
image = new OctreeQuantizer(255, 8).Quantize(image); |
||||
|
} |
||||
|
|
||||
|
return base.Save(memoryStream, image); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Saves the current image to the specified file path.
|
||||
|
/// </summary>
|
||||
|
/// <param name="path">The path to save the image to.</param>
|
||||
|
/// <param name="image">The
|
||||
|
/// <see cref="T:System.Drawing.Image" /> to save.</param>
|
||||
|
/// <returns>
|
||||
|
/// The <see cref="T:System.Drawing.Image" />.
|
||||
|
/// </returns>
|
||||
|
public override Image Save(string path, Image image) |
||||
|
{ |
||||
|
if (FormatUtilities.IsIndexed(image)) |
||||
|
{ |
||||
|
image = new OctreeQuantizer(255, 8).Quantize(image); |
||||
|
} |
||||
|
|
||||
|
return base.Save(path, image); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,96 @@ |
|||||
|
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
// <copyright file="TiffFormat.cs" company="James South">
|
||||
|
// Copyright (c) James South.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>
|
||||
|
// <summary>
|
||||
|
// Provides the necessary information to support tiff images.
|
||||
|
// </summary>
|
||||
|
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
|
||||
|
namespace ImageProcessor.Imaging.Formats |
||||
|
{ |
||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Drawing; |
||||
|
using System.Drawing.Imaging; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Provides the necessary information to support tiff images.
|
||||
|
/// </summary>
|
||||
|
public class TiffFormat : FormatBase |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Gets the file header.
|
||||
|
/// </summary>
|
||||
|
public override byte[] FileHeader |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
return new byte[] { 77, 77, 42 }; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the list of file extensions.
|
||||
|
/// </summary>
|
||||
|
public override string[] FileExtensions |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
return new[] { "tif", "tiff" }; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the standard identifier used on the Internet to indicate the type of data that a file contains.
|
||||
|
/// </summary>
|
||||
|
public override string MimeType |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
return "image/tiff"; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the <see cref="ImageFormat" />.
|
||||
|
/// </summary>
|
||||
|
public override ImageFormat ImageFormat |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
return ImageFormat.Tiff; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Applies the given processor the current image.
|
||||
|
/// </summary>
|
||||
|
/// <param name="processor">The processor delegate.</param>
|
||||
|
/// <param name="factory">The <see cref="ImageFactory" />.</param>
|
||||
|
public override void ApplyProcessor(Func<ImageFactory, Image> processor, ImageFactory factory) |
||||
|
{ |
||||
|
base.ApplyProcessor(processor, factory); |
||||
|
|
||||
|
// Set the property item information from any Exif metadata.
|
||||
|
// We do this here so that they can be changed between processor methods.
|
||||
|
if (factory.PreserveExifData) |
||||
|
{ |
||||
|
foreach (KeyValuePair<int, PropertyItem> propertItem in factory.ExifPropertyItems) |
||||
|
{ |
||||
|
try |
||||
|
{ |
||||
|
factory.Image.SetPropertyItem(propertItem.Value); |
||||
|
} |
||||
|
// ReSharper disable once EmptyGeneralCatchClause
|
||||
|
catch |
||||
|
{ |
||||
|
// Do nothing. The image format does not handle EXIF data.
|
||||
|
// TODO: empty catch is fierce code smell.
|
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,74 @@ |
|||||
|
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
// <copyright file="BackgroundColor.cs" company="James South">
|
||||
|
// Copyright (c) James South.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>
|
||||
|
// <summary>
|
||||
|
// Changes the background color of an image.
|
||||
|
// </summary>
|
||||
|
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
|
||||
|
namespace ImageProcessor.Processors |
||||
|
{ |
||||
|
using System.Collections.Generic; |
||||
|
using System.Drawing; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Changes the background color of an image.
|
||||
|
/// </summary>
|
||||
|
public class BackgroundColor : IGraphicsProcessor |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Gets or sets the DynamicParameter.
|
||||
|
/// </summary>
|
||||
|
public dynamic DynamicParameter { get; set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets or sets any additional settings required by the processor.
|
||||
|
/// </summary>
|
||||
|
public Dictionary<string, string> Settings { get; set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Processes the image.
|
||||
|
/// </summary>
|
||||
|
/// <param name="factory">The the current instance of the
|
||||
|
/// <see cref="T:ImageProcessor.ImageFactory" /> class containing
|
||||
|
/// the image to process.</param>
|
||||
|
/// <returns>
|
||||
|
/// The processed image from the current instance of the <see cref="T:ImageProcessor.ImageFactory" /> class.
|
||||
|
/// </returns>
|
||||
|
public Image ProcessImage(ImageFactory factory) |
||||
|
{ |
||||
|
Bitmap newImage = null; |
||||
|
Image image = factory.Image; |
||||
|
|
||||
|
try |
||||
|
{ |
||||
|
Color backgroundColor = this.DynamicParameter; |
||||
|
newImage = new Bitmap(image.Width, image.Height); |
||||
|
|
||||
|
// Make a graphics object from the empty bitmap.
|
||||
|
using (Graphics graphics = Graphics.FromImage(newImage)) |
||||
|
{ |
||||
|
// Fill the background.
|
||||
|
graphics.Clear(backgroundColor); |
||||
|
|
||||
|
// Draw passed in image onto graphics object.
|
||||
|
graphics.DrawImage(image, 0, 0); |
||||
|
} |
||||
|
|
||||
|
image.Dispose(); |
||||
|
image = newImage; |
||||
|
} |
||||
|
catch |
||||
|
{ |
||||
|
if (newImage != null) |
||||
|
{ |
||||
|
newImage.Dispose(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return image; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1 +1 @@ |
|||||
17e154964bfb4da80c1e0aec623cd2486d493b47 |
30ec5c05548fd350f9b7c699715848b9fbfb8ca9 |
||||
@ -1 +1 @@ |
|||||
069f8472ed7b83ea57f4cf511f83396e1a0b8877 |
23a1c81a2d1422076373796e0c47f5d968c56d0b |
||||
Loading…
Reference in new issue