Browse Source

Updating filter to add comic

Former-commit-id: c7d4ad938e37585084a03d5976f67e8c6ec9cf01
af/merge-core
JimBobSquarePants 14 years ago
parent
commit
5e89ed8291
  1. 1
      src/ImageProcessor/ImageProcessor.csproj
  2. 301
      src/ImageProcessor/Processors/Filter.cs
  3. 4
      src/Test/Test/Test.csproj
  4. 234
      src/Test/Test/Web.config

1
src/ImageProcessor/ImageProcessor.csproj

@ -22,6 +22,7 @@
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<DocumentationFile>bin\Debug\ImageProcessor.XML</DocumentationFile> <DocumentationFile>bin\Debug\ImageProcessor.XML</DocumentationFile>
<AllowUnsafeBlocks>false</AllowUnsafeBlocks>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType> <DebugType>pdbonly</DebugType>

301
src/ImageProcessor/Processors/Filter.cs

@ -7,10 +7,17 @@
namespace ImageProcessor.Processors namespace ImageProcessor.Processors
{ {
#region Using #region Using
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging; using System.Drawing.Imaging;
using System.IO;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Web;
using System.Web.Hosting;
#endregion #endregion
/// <summary> /// <summary>
@ -21,7 +28,18 @@ namespace ImageProcessor.Processors
/// <summary> /// <summary>
/// The regular expression to search strings for. /// The regular expression to search strings for.
/// </summary> /// </summary>
private static readonly Regex QueryRegex = new Regex(@"filter=(lomograph|polaroid|blackwhite|sepia|greyscale)", RegexOptions.Compiled); private static readonly Regex QueryRegex = new Regex(@"filter=(lomograph|polaroid|blackwhite|sepia|greyscale|gotham|invert|hisatch|losatch|comic)", RegexOptions.Compiled);
/// <summary>
/// Enumurates Argb colour channels.
/// </summary>
private enum ChannelArgb
{
Blue = 0,
Green = 1,
Red = 2,
Alpha = 3
}
#region IGraphicsProcessor Members #region IGraphicsProcessor Members
/// <summary> /// <summary>
@ -141,7 +159,7 @@ namespace ImageProcessor.Processors
switch ((string)this.DynamicParameter) switch ((string)this.DynamicParameter)
{ {
case "polaroid": case "polaroid":
colorMatrix = ColorMatrixes.Poloroid; colorMatrix = ColorMatrixes.Polaroid;
break; break;
case "lomograph": case "lomograph":
colorMatrix = ColorMatrixes.Lomograph; colorMatrix = ColorMatrixes.Lomograph;
@ -155,6 +173,21 @@ namespace ImageProcessor.Processors
case "greyscale": case "greyscale":
colorMatrix = ColorMatrixes.GreyScale; colorMatrix = ColorMatrixes.GreyScale;
break; break;
case "gotham":
colorMatrix = ColorMatrixes.Gotham;
break;
case "invert":
colorMatrix = ColorMatrixes.Invert;
break;
case "hisatch":
colorMatrix = ColorMatrixes.HiSatch;
break;
case "losatch":
colorMatrix = ColorMatrixes.LoSatch;
break;
case "comic":
colorMatrix = ColorMatrixes.LoSatch;
break;
} }
using (Graphics graphics = Graphics.FromImage(newImage)) using (Graphics graphics = Graphics.FromImage(newImage))
@ -168,7 +201,110 @@ namespace ImageProcessor.Processors
Rectangle rectangle = new Rectangle(0, 0, image.Width, image.Height); Rectangle rectangle = new Rectangle(0, 0, image.Width, image.Height);
graphics.DrawImage(image, rectangle, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, attributes); if (this.DynamicParameter == "comic")
{
// Set the attributes to LoSatch and draw the image.
graphics.DrawImage(image, rectangle, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, attributes);
// Create a bitmap for overlaying.
Bitmap hisatchBitmap = new Bitmap(rectangle.Width, rectangle.Height, PixelFormat.Format32bppPArgb);
// Set the color matrix
attributes.SetColorMatrix(ColorMatrixes.HiSatch);
// Draw the image with the hisatch colormatrix.
using (var g = Graphics.FromImage(hisatchBitmap))
{
g.DrawImage(image, rectangle, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, attributes);
}
// We need to create a new image now with the hi saturation colormatrix and a pattern mask to paint it
// onto the other image with.
Bitmap patternBitmap = new Bitmap(rectangle.Width, rectangle.Height, PixelFormat.Format32bppPArgb);
// Create the pattern mask.
using (var g = Graphics.FromImage(patternBitmap))
{
g.Clear(Color.Black);
g.SmoothingMode = SmoothingMode.HighQuality;
for (var y = 0; y < image.Height; y += 10)
{
for (var x = 0; x < image.Width; x += 6)
{
g.FillEllipse(Brushes.White, x, y, 4, 4);
g.FillEllipse(Brushes.White, x + 3, y + 5, 4, 4);
}
}
}
// Transfer the alpha channel from the mask to the hi sturation image.
TransferOneArgbChannelFromOneBitmapToAnother(patternBitmap, hisatchBitmap, ChannelArgb.Blue, ChannelArgb.Alpha);
// Overlay the image.
graphics.DrawImage(hisatchBitmap, 0, 0);
// Dispose of the other images
hisatchBitmap.Dispose();
patternBitmap.Dispose();
}
else
{
graphics.DrawImage(image, rectangle, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, attributes);
// Polaroid requires an extra tweak.
if (this.DynamicParameter == "polaroid")
{
using (GraphicsPath path = new GraphicsPath())
{
path.AddEllipse(rectangle);
using (PathGradientBrush brush = new PathGradientBrush(path))
{
// Fill a rectangle with an elliptical gradient brush that goes from orange to transparent.
// This has the effect of painting the far corners transparent and fading in to orange on the
// way in to the centre.
brush.WrapMode = WrapMode.Tile;
brush.CenterColor = Color.FromArgb(70, 255, 153, 102);
brush.SurroundColors = new Color[] { Color.FromArgb(0, 0, 0, 0) };
Blend blend = new Blend
{
Positions = new float[] { 0.0f, 0.2f, 0.4f, 0.6f, 0.8f, 1.0F },
Factors = new float[] { 0.0f, 0.5f, 1f, 1f, 1.0f, 1.0f }
};
brush.Blend = blend;
Region oldClip = graphics.Clip;
graphics.Clip = new Region(rectangle);
graphics.FillRectangle(brush, rectangle);
graphics.Clip = oldClip;
}
}
}
// Gotham requires an extra tweak.
if (this.DynamicParameter == "gotham")
{
using (GraphicsPath path = new GraphicsPath())
{
path.AddRectangle(rectangle);
// Paint a burgundy rectangle with a transparency of ~30% over the image.
// Paint a blue rectangle with a transparency of 20% over the image.
using (SolidBrush brush = new SolidBrush(Color.FromArgb(77, 43, 4, 18)))
{
Region oldClip = graphics.Clip;
graphics.Clip = new Region(rectangle);
graphics.FillRectangle(brush, rectangle);
// Fill the blue.
brush.Color = Color.FromArgb(51, 12, 22, 88);
graphics.FillRectangle(brush, rectangle);
graphics.Clip = oldClip;
}
}
}
}
} }
} }
@ -188,6 +324,71 @@ namespace ImageProcessor.Processors
} }
#endregion #endregion
/// <summary>
/// Transfers a single ARGB channel from one image to another.
/// </summary>
/// <param name="source">
/// The source.
/// </param>
/// <param name="destination">
/// The destination.
/// </param>
/// <param name="sourceChannel">
/// The source channel.
/// </param>
/// <param name="destinationChannel">
/// The destination channel.
/// </param>
private static void TransferOneArgbChannelFromOneBitmapToAnother(Bitmap source, Bitmap destination, ChannelArgb sourceChannel, ChannelArgb destinationChannel)
{
if (source.Size != destination.Size)
{
throw new ArgumentException();
}
Rectangle rectangle = new Rectangle(Point.Empty, source.Size);
// Lockbits the source.
BitmapData bitmapDataSource = source.LockBits(rectangle, ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
// Declare an array to hold the bytes of the bitmap.
int bytes = bitmapDataSource.Stride * bitmapDataSource.Height;
// Allocate a buffer for the source image
byte[] sourceRgbValues = new byte[bytes];
// Copy the RGB values into the array.
System.Runtime.InteropServices.Marshal.Copy(bitmapDataSource.Scan0, sourceRgbValues, 0, bytes);
// Unlockbits the source.
source.UnlockBits(bitmapDataSource);
// Lockbits the destination.
BitmapData bitmapDataDestination = destination.LockBits(rectangle, ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
// Allocate a buffer for image
byte[] destinationRgbValues = new byte[bytes];
// Copy the RGB values into the array.
System.Runtime.InteropServices.Marshal.Copy(bitmapDataDestination.Scan0, destinationRgbValues, 0, bytes);
int s = (int)sourceChannel;
int d = (int)destinationChannel;
for (int i = rectangle.Height * rectangle.Width; i > 0; i--)
{
destinationRgbValues[d] = sourceRgbValues[s];
d += 4;
s += 4;
}
// Copy the RGB values back to the bitmap
System.Runtime.InteropServices.Marshal.Copy(destinationRgbValues, 0, bitmapDataDestination.Scan0, bytes);
// Unlock bits the destination.
destination.UnlockBits(bitmapDataDestination);
}
/// <summary> /// <summary>
/// A list of available color matrices to apply to an image. /// A list of available color matrices to apply to an image.
/// </summary> /// </summary>
@ -232,20 +433,20 @@ namespace ImageProcessor.Processors
} }
/// <summary> /// <summary>
/// Gets Poloroid. /// Gets Polaroid.
/// </summary> /// </summary>
internal static ColorMatrix Poloroid internal static ColorMatrix Polaroid
{ {
get get
{ {
return new ColorMatrix( return new ColorMatrix(
new float[][] new float[][]
{ {
new float[] { 1.438f, -0.062f, -0.062f, 0, 0 }, new float[] { 1.638f, -0.062f, -0.262f, 0, 0 },
new float[] { -0.122f, 1.378f, -0.122f, 0, 0 }, new float[] { -0.122f, 1.378f, -0.122f, 0, 0 },
new float[] { -0.016f, -0.016f, 1.483f, 0, 0 }, new float[] { 1.016f, -0.016f, 1.383f, 0, 0 },
new float[] { 0, 0, 0, 1, 0 }, new float[] { 0, 0, 0, 1, 0 },
new float[] { -0.03f, 0.05f, -0.02f, 0, 1 } new float[] { 0.06f, -0.05f, -0.05f, 0, 1 }
}); });
} }
} }
@ -260,11 +461,11 @@ namespace ImageProcessor.Processors
return new ColorMatrix( return new ColorMatrix(
new float[][] new float[][]
{ {
new float[] { 1.25f, 0, 0, 0, 0 }, new float[] { 1.50f, 0, 0, 0, 0 },
new float[] { 0, 1.25f, 0, 0, 0 }, new float[] { 0, 1.45f, 0, 0, 0 },
new float[] { 0, 0, 0.94f, 0, 0 }, new float[] { 0, 0, 1.09f, 0, 0 },
new float[] { 0, 0, 0, 1, 0 }, new float[] { 0, 0, 0, 1, 0 },
new float[] { 0, 0, 0, 0, 1 } new float[] { -0.10f, 0.05f, -0.08f, 0, 1 }
}); });
} }
} }
@ -287,6 +488,82 @@ namespace ImageProcessor.Processors
}); });
} }
} }
/// <summary>
/// Gets Gotham.
/// </summary>
internal static ColorMatrix Gotham
{
get
{
return new ColorMatrix(
new float[][]
{
new float[] { .9f, .9f, .9f, 0, 0 },
new float[] { .9f, .9f, .9f, 0, 0 },
new float[] { .9f, .9f, .9f, 0, 0 },
new float[] { 0, 0, 0, 1, 0 },
new float[] { -.5f, -.5f, -.45f, 0, 1 }
});
}
}
/// <summary>
/// Gets Invert.
/// </summary>
internal static ColorMatrix Invert
{
get
{
return new ColorMatrix(
new float[][]
{
new float[] { -1, 0, 0, 0, 0 },
new float[] { 0, -1, 0, 0, 0 },
new float[] { 0, 0, -1, 0, 0 },
new float[] { 0, 0, 0, 1, 0 },
new float[] { 1, 1, 1, 0, 1 }
});
}
}
/// <summary>
/// Gets HiSatch.
/// </summary>
internal static ColorMatrix HiSatch
{
get
{
return new ColorMatrix(
new float[][]
{
new float[] { 3, -1, -1, 0, 0 },
new float[] { -1, 3, -1, 0, 0 },
new float[] { -1, -1, 3, 0, 0 },
new float[] { 0, 0, 0, 1, 0 },
new float[] { 0, 0, 0, 0, 1 }
});
}
}
/// <summary>
/// Gets LoSatch.
/// </summary>
internal static ColorMatrix LoSatch
{
get
{
return new ColorMatrix(
new float[][]
{
new float[] { 1, 0, 0, 0, 0 },
new float[] { 0, 1, 0, 0, 0 },
new float[] { 0, 0, 1, 0, 0 },
new float[] { 0, 0, 0, 1, 0 },
new float[] { .25f, .25f, .25f, 0, 1 }
});
}
}
} }
} }
} }

4
src/Test/Test/Test.csproj

@ -122,7 +122,9 @@
<Content Include="Scripts\jquery.validate.min.js" /> <Content Include="Scripts\jquery.validate.min.js" />
<Content Include="Scripts\modernizr-1.7.js" /> <Content Include="Scripts\modernizr-1.7.js" />
<Content Include="Scripts\modernizr-1.7.min.js" /> <Content Include="Scripts\modernizr-1.7.min.js" />
<Content Include="Web.config" /> <Content Include="Web.config">
<SubType>Designer</SubType>
</Content>
<Content Include="Web.Debug.config"> <Content Include="Web.Debug.config">
<DependentUpon>Web.config</DependentUpon> <DependentUpon>Web.config</DependentUpon>
</Content> </Content>

234
src/Test/Test/Web.config

@ -1,117 +1,117 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<!-- <!--
For more information on how to configure your ASP.NET application, please visit For more information on how to configure your ASP.NET application, please visit
http://go.microsoft.com/fwlink/?LinkId=152368 http://go.microsoft.com/fwlink/?LinkId=152368
--> -->
<configuration> <configuration>
<!-- Configuration section-handler declaration area. --> <!-- Configuration section-handler declaration area. -->
<configSections> <configSections>
<sectionGroup name="imageProcessor"> <sectionGroup name="imageProcessor">
<section name="security" requirePermission="false" type="ImageProcessor.Web.Config.ImageSecuritySection, ImageProcessor.Web"/> <section name="security" requirePermission="false" type="ImageProcessor.Web.Config.ImageSecuritySection, ImageProcessor.Web"/>
<section name="processing" requirePermission="false" type="ImageProcessor.Web.Config.ImageProcessingSection, ImageProcessor.Web" /> <section name="processing" requirePermission="false" type="ImageProcessor.Web.Config.ImageProcessingSection, ImageProcessor.Web" />
<section name="cache" requirePermission="false" type="ImageProcessor.Web.Config.ImageCacheSection, ImageProcessor.Web" /> <section name="cache" requirePermission="false" type="ImageProcessor.Web.Config.ImageCacheSection, ImageProcessor.Web" />
</sectionGroup> </sectionGroup>
</configSections> </configSections>
<connectionStrings> <connectionStrings>
<add name="ApplicationServices" <add name="ApplicationServices"
connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true" connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true"
providerName="System.Data.SqlClient" /> providerName="System.Data.SqlClient" />
</connectionStrings> </connectionStrings>
<appSettings> <appSettings>
<add key="webpages:Version" value="1.0.0.0"/> <add key="webpages:Version" value="1.0.0.0"/>
<add key="ClientValidationEnabled" value="true"/> <add key="ClientValidationEnabled" value="true"/>
<add key="UnobtrusiveJavaScriptEnabled" value="true"/> <add key="UnobtrusiveJavaScriptEnabled" value="true"/>
</appSettings> </appSettings>
<system.web> <system.web>
<compilation debug="true" targetFramework="4.0"> <compilation debug="true" targetFramework="4.0">
<assemblies> <assemblies>
<add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> <add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.Helpers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> <add assembly="System.Web.Helpers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> <add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> <add assembly="System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.WebPages, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> <add assembly="System.Web.WebPages, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
</assemblies> </assemblies>
</compilation> </compilation>
<authentication mode="Forms"> <authentication mode="Forms">
<forms loginUrl="~/Account/LogOn" timeout="2880" /> <forms loginUrl="~/Account/LogOn" timeout="2880" />
</authentication> </authentication>
<membership> <membership>
<providers> <providers>
<clear/> <clear/>
<add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="ApplicationServices" <add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="ApplicationServices"
enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false"
maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10"
applicationName="/" /> applicationName="/" />
</providers> </providers>
</membership> </membership>
<profile> <profile>
<providers> <providers>
<clear/> <clear/>
<add name="AspNetSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="ApplicationServices" applicationName="/" /> <add name="AspNetSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="ApplicationServices" applicationName="/" />
</providers> </providers>
</profile> </profile>
<roleManager enabled="false"> <roleManager enabled="false">
<providers> <providers>
<clear/> <clear/>
<add name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider" connectionStringName="ApplicationServices" applicationName="/" /> <add name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider" connectionStringName="ApplicationServices" applicationName="/" />
<add name="AspNetWindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider" applicationName="/" /> <add name="AspNetWindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider" applicationName="/" />
</providers> </providers>
</roleManager> </roleManager>
<pages> <pages>
<namespaces> <namespaces>
<add namespace="System.Web.Helpers" /> <add namespace="System.Web.Helpers" />
<add namespace="System.Web.Mvc" /> <add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" /> <add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" /> <add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Routing" /> <add namespace="System.Web.Routing" />
<add namespace="System.Web.WebPages"/> <add namespace="System.Web.WebPages"/>
</namespaces> </namespaces>
</pages> </pages>
<httpModules> <httpModules>
<add name="ImageProcessorModule" type="ImageProcessor.Web.HttpModules.ImageProcessingModule, ImageProcessor.Web"/> <add name="ImageProcessorModule" type="ImageProcessor.Web.HttpModules.ImageProcessingModule, ImageProcessor.Web"/>
</httpModules> </httpModules>
<!--Set the trust level.--> <!--Set the trust level.-->
<trust level="Medium"/> <!--<trust level="Medium"/>-->
</system.web> </system.web>
<system.webServer> <system.webServer>
<validation validateIntegratedModeConfiguration="false"/> <validation validateIntegratedModeConfiguration="false"/>
<modules runAllManagedModulesForAllRequests="true"/> <modules runAllManagedModulesForAllRequests="true"/>
</system.webServer> </system.webServer>
<runtime> <runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly> <dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" /> <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="3.0.0.0" /> <bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly> </dependentAssembly>
</assemblyBinding> </assemblyBinding>
</runtime> </runtime>
<imageProcessor> <imageProcessor>
<security allowRemoteDownloads="true" timeout="300000" maxBytes="524288" remotePrefix="/remote.axd"> <security allowRemoteDownloads="true" timeout="300000" maxBytes="524288" remotePrefix="/remote.axd">
<whiteList> <whiteList>
<add url="http://images.mymovies.net"/> <add url="http://images.mymovies.net"/>
</whiteList> </whiteList>
</security> </security>
<cache virtualPath="~/cache" maxDays="7" /> <cache virtualPath="~/cache" maxDays="7" />
<processing> <processing>
<plugins> <plugins>
<plugin name ="Resize"> <plugin name ="Resize">
<settings> <settings>
<setting key="MaxWidth" value="1024"/> <setting key="MaxWidth" value="1024"/>
<setting key="MaxHeight" value="768"/> <setting key="MaxHeight" value="768"/>
</settings> </settings>
</plugin> </plugin>
</plugins> </plugins>
</processing> </processing>
</imageProcessor> </imageProcessor>
</configuration> </configuration>

Loading…
Cancel
Save