Browse Source

Adding mask to web

Former-commit-id: 8c6e97ecedbaf295fe2596f1c4f39879440b7d82
Former-commit-id: b4940ff77158bb37cb8c3072ea62b99e719ecb10
pull/17/head
James South 11 years ago
parent
commit
b9eabddecf
  1. BIN
      src/ImageProcessor.UnitTests/Images/masks/mask.png
  2. 7
      src/ImageProcessor.Web/Configuration/Resources/processing.config
  3. 14
      src/ImageProcessor.Web/Helpers/ImageHelpers.cs
  4. 1
      src/ImageProcessor.Web/ImageProcessor.Web.csproj
  5. 185
      src/ImageProcessor.Web/Processors/Mask.cs
  6. 4
      src/TestWebsites/MVC/Web.config

BIN
src/ImageProcessor.UnitTests/Images/masks/mask.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

7
src/ImageProcessor.Web/Configuration/Resources/processing.config

@ -12,7 +12,7 @@
<plugin name="EntropyCrop" type="ImageProcessor.Web.Processors.EntropyCrop, ImageProcessor.Web"/>
<plugin name="Filter" type="ImageProcessor.Web.Processors.Filter, ImageProcessor.Web"/>
<plugin name="Flip" type="ImageProcessor.Web.Processors.Flip, ImageProcessor.Web"/>
<plugin name="Format" type="ImageProcessor.Web.Processors.Format, ImageProcessor.Web"/>
<plugin name="Format" type="ImageProcessor.Web.Processors.Format, ImageProcessor.Web"/>
<plugin name="GaussianBlur" type="ImageProcessor.Web.Processors.GaussianBlur, ImageProcessor.Web">
<settings>
<setting key="MaxSize" value="22"/>
@ -27,6 +27,11 @@
<setting key="MaxThreshold" value="100"/>
</settings>
</plugin>
<plugin name="Mask" type="ImageProcessor.Web.Processors.Mask, ImageProcessor.Web">
<settings>
<setting key="VirtualPath" value="~/images/masks/"/>
</settings>
</plugin>
<plugin name="Meta" type="ImageProcessor.Web.Processors.Meta, ImageProcessor.Web"/>
<plugin name="Pixelate" type="ImageProcessor.Web.Processors.Pixelate, ImageProcessor.Web"/>
<plugin name="Quality" type="ImageProcessor.Web.Processors.Quality, ImageProcessor.Web"/>

14
src/ImageProcessor.Web/Helpers/ImageHelpers.cs

@ -24,7 +24,13 @@ namespace ImageProcessor.Web.Helpers
/// <summary>
/// The regex pattern.
/// </summary>
private static readonly string ExtensionRegexPattern = BuildExtensionRegexPattern();
public static readonly string ExtensionRegexPattern = BuildExtensionRegexPattern();
/// <summary>
/// The exclude regex for matching things to ignore when parsing image extensions.
/// I'd like to make something more extensible than this.
/// </summary>
private static readonly Regex ExcludeRegex = new Regex(@"mask=[\w+-]+.", RegexOptions.IgnoreCase);
/// <summary>
/// The image format regex.
@ -57,6 +63,12 @@ namespace ImageProcessor.Web.Helpers
/// </returns>
public static string GetExtension(string input)
{
// First filter out any troublesome elements.
foreach (Match exlude in ExcludeRegex.Matches(input))
{
input = input.Replace(exlude.Value, string.Empty);
}
Match match = FormatRegex.Match(input);
if (match.Success)

1
src/ImageProcessor.Web/ImageProcessor.Web.csproj

@ -48,6 +48,7 @@
<Compile Include="Caching\CachedImage.cs" />
<Compile Include="Processors\DetectEdges.cs" />
<Compile Include="Processors\EntropyCrop.cs" />
<Compile Include="Processors\Mask.cs" />
<Compile Include="Processors\Pixelate.cs" />
<Compile Include="Services\IImageService.cs" />
<Compile Include="Caching\MemCache.cs" />

185
src/ImageProcessor.Web/Processors/Mask.cs

@ -0,0 +1,185 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="Mask.cs" company="James South">
// Copyright (c) James South.
// Licensed under the Apache License, Version 2.0.
// </copyright>
// <summary>
// Applies a mask to the given image. If the mask is not the same size as the image
// it will be centered against the image.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace ImageProcessor.Web.Processors
{
using System;
using System.Drawing;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Web.Hosting;
using ImageProcessor.Processors;
using ImageProcessor.Web.Extensions;
using ImageProcessor.Web.Helpers;
/// <summary>
/// Applies a mask to the given image. If the mask is not the same size as the image
/// it will be centered against the image.
/// </summary>
public class Mask : IWebGraphicsProcessor
{
/// <summary>
/// The regular expression to search strings for.
/// </summary>
private static readonly Regex QueryRegex = new Regex(@"(mask=|maskposition=)[^&]+", RegexOptions.Compiled);
/// <summary>
/// The mask image regex.
/// </summary>
private static readonly Regex PixelRegex = new Regex(@"mask=[\w+-]+." + ImageHelpers.ExtensionRegexPattern);
/// <summary>
/// The point regex.
/// </summary>
private static readonly Regex PointRegex = new Regex(@"maskposition=\d+,\d+", RegexOptions.Compiled);
/// <summary>
/// Initializes a new instance of the <see cref="Mask"/> class.
/// </summary>
public Mask()
{
this.Processor = new ImageProcessor.Processors.Mask();
}
/// <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;
// First merge the matches so we can parse .
StringBuilder stringBuilder = new StringBuilder();
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;
}
stringBuilder.Append(match.Value);
index += 1;
}
}
if (this.SortOrder < int.MaxValue)
{
// Match syntax
string toParse = stringBuilder.ToString();
Image image = this.ParseImage(toParse);
Point? rectangle = this.ParsePoint(toParse);
this.Processor.DynamicParameter = new Tuple<Image, Point?>(image, rectangle);
}
return this.SortOrder;
}
/// <summary>
/// Returns the correct size of pixels.
/// </summary>
/// <param name="input">
/// The input containing the value to parse.
/// </param>
/// <returns>
/// The <see cref="int"/> representing the pixel size.
/// </returns>
public Image ParseImage(string input)
{
Image image = null;
// Correctly parse the path.
string path;
this.Processor.Settings.TryGetValue("VirtualPath", out path);
if (!string.IsNullOrWhiteSpace(path) && path.StartsWith("~/"))
{
Match match = PixelRegex.Match(input);
if (match.Success)
{
string imagePath = HostingEnvironment.MapPath(path);
if (imagePath != null)
{
imagePath = Path.Combine(imagePath, match.Value.Split('=')[1]);
using (ImageFactory factory = new ImageFactory())
{
factory.Load(imagePath);
image = new Bitmap(factory.Image);
}
}
}
}
return image;
}
/// <summary>
/// Returns the correct <see cref="Nullable{Point}"/> for the given string.
/// </summary>
/// <param name="input">
/// The input string containing the value to parse.
/// </param>
/// <returns>
/// The correct <see cref="Nullable{Point}"/>
/// </returns>
private Point? ParsePoint(string input)
{
int[] dimensions = { };
foreach (Match match in PointRegex.Matches(input))
{
dimensions = match.Value.ToPositiveIntegerArray();
}
if (dimensions.Length == 2)
{
return new Point(dimensions[0], dimensions[1]);
}
return null;
}
}
}

4
src/TestWebsites/MVC/Web.config

@ -5,7 +5,7 @@
-->
<configuration>
<configSections>
<!--<configSections>
<sectionGroup name="imageProcessor">
<section name="security" requirePermission="false" type="ImageProcessor.Web.Configuration.ImageSecuritySection, ImageProcessor.Web" />
<section name="processing" requirePermission="false" type="ImageProcessor.Web.Configuration.ImageProcessingSection, ImageProcessor.Web" />
@ -16,7 +16,7 @@
<security configSource="config\imageprocessor\security.config" />
<cache configSource="config\imageprocessor\cache.config" />
<processing configSource="config\imageprocessor\processing.config" />
</imageProcessor>
</imageProcessor>-->
<appSettings>
<add key="webpages:Version" value="2.0.0.0" />
<add key="webpages:Enabled" value="false" />

Loading…
Cancel
Save