Skip to content

Commit

Permalink
Initial CAIR plugin addition
Browse files Browse the repository at this point in the history
Former-commit-id: e120f457ff05251ec312fc546e70ac3b09febbe9
JimBobSquarePants committed Sep 1, 2014
1 parent dd5d2f6 commit ef21a55
Showing 49 changed files with 1,630 additions and 21 deletions.
8 changes: 7 additions & 1 deletion src/ImageProcessor.Web/Processors/Resize.cs
Original file line number Diff line number Diff line change
@@ -29,7 +29,7 @@ public class Resize : IWebGraphicsProcessor
/// <summary>
/// The regular expression to search strings for.
/// </summary>
private static readonly Regex QueryRegex = new Regex(@"(width|height)=|(width|height)ratio=|mode=|anchor=|center=|upscale=", RegexOptions.Compiled);
private static readonly Regex QueryRegex = new Regex(@"(width|height)=|(width|height)ratio=|mode=(carve)?|anchor=|center=|upscale=", RegexOptions.Compiled);

/// <summary>
/// The regular expression to search strings for the size attribute.
@@ -111,6 +111,12 @@ public int MatchRegexIndex(string queryString)
{
if (match.Success)
{
// We don't want any resize carve requests to interfere.
if (match.Value.ToUpperInvariant().Contains("CARVE"))
{
break;
}

if (index == 0)
{
// Set the index on the first instance only.
17 changes: 17 additions & 0 deletions src/ImageProcessor.sln
Original file line number Diff line number Diff line change
@@ -32,6 +32,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Web.Tests", "Web.Test\Web.T
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test_Website_MVC", "TestWebsites\MVC\Test_Website_MVC.csproj", "{F6A208E9-C18F-43E9-B051-3C6EED30FDAF}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ImageProcessor.Plugins.Cair", "Plugins\ImageProcessor\ImageProcessor.Plugins.Cair\ImageProcessor.Plugins.Cair.csproj", "{C7D1F0DD-CBD6-4127-82B4-51949EFF0BF5}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
All|Any CPU = All|Any CPU
@@ -164,6 +166,21 @@ Global
{F6A208E9-C18F-43E9-B051-3C6EED30FDAF}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{F6A208E9-C18F-43E9-B051-3C6EED30FDAF}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{F6A208E9-C18F-43E9-B051-3C6EED30FDAF}.Release|x86.ActiveCfg = Release|Any CPU
{C7D1F0DD-CBD6-4127-82B4-51949EFF0BF5}.All|Any CPU.ActiveCfg = Release|Any CPU
{C7D1F0DD-CBD6-4127-82B4-51949EFF0BF5}.All|Any CPU.Build.0 = Release|Any CPU
{C7D1F0DD-CBD6-4127-82B4-51949EFF0BF5}.All|Mixed Platforms.ActiveCfg = Release|Any CPU
{C7D1F0DD-CBD6-4127-82B4-51949EFF0BF5}.All|Mixed Platforms.Build.0 = Release|Any CPU
{C7D1F0DD-CBD6-4127-82B4-51949EFF0BF5}.All|x86.ActiveCfg = Release|Any CPU
{C7D1F0DD-CBD6-4127-82B4-51949EFF0BF5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C7D1F0DD-CBD6-4127-82B4-51949EFF0BF5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C7D1F0DD-CBD6-4127-82B4-51949EFF0BF5}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{C7D1F0DD-CBD6-4127-82B4-51949EFF0BF5}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{C7D1F0DD-CBD6-4127-82B4-51949EFF0BF5}.Debug|x86.ActiveCfg = Debug|Any CPU
{C7D1F0DD-CBD6-4127-82B4-51949EFF0BF5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C7D1F0DD-CBD6-4127-82B4-51949EFF0BF5}.Release|Any CPU.Build.0 = Release|Any CPU
{C7D1F0DD-CBD6-4127-82B4-51949EFF0BF5}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{C7D1F0DD-CBD6-4127-82B4-51949EFF0BF5}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{C7D1F0DD-CBD6-4127-82B4-51949EFF0BF5}.Release|x86.ActiveCfg = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
4 changes: 4 additions & 0 deletions src/ImageProcessorConsole/ImageProcessorConsole.csproj
Original file line number Diff line number Diff line change
@@ -56,6 +56,10 @@
<Project>{3B5DD734-FB7A-487D-8CE6-55E7AF9AEA7E}</Project>
<Name>ImageProcessor</Name>
</ProjectReference>
<ProjectReference Include="..\Plugins\ImageProcessor\ImageProcessor.Plugins.Cair\ImageProcessor.Plugins.Cair.csproj">
<Project>{c7d1f0dd-cbd6-4127-82b4-51949eff0bf5}</Project>
<Name>ImageProcessor.Plugins.Cair</Name>
</ProjectReference>
<ProjectReference Include="..\Plugins\ImageProcessor\ImageProcessor.Plugins.WebP\ImageProcessor.Plugins.WebP.csproj">
<Project>{2cf69699-959a-44dc-a281-4e2596c25043}</Project>
<Name>ImageProcessor.Plugins.WebP</Name>
12 changes: 8 additions & 4 deletions src/ImageProcessorConsole/Program.cs
Original file line number Diff line number Diff line change
@@ -16,6 +16,7 @@ namespace ImageProcessorConsole
using System.IO;
using System.Linq;
using ImageProcessor;
using ImageProcessor.Plugins.Cair;

/// <summary>
/// The program.
@@ -40,8 +41,8 @@ public static void Main(string[] args)
di.Create();
}

//IEnumerable<FileInfo> files = GetFilesByExtensions(di, ".jpg");
IEnumerable<FileInfo> files = GetFilesByExtensions(di, ".gif", ".webp", ".bmp", ".jpg", ".png");
IEnumerable<FileInfo> files = GetFilesByExtensions(di, ".jpg");
//IEnumerable<FileInfo> files = GetFilesByExtensions(di, ".gif", ".webp", ".bmp", ".jpg", ".png");

foreach (FileInfo fileInfo in files)
{
@@ -52,11 +53,14 @@ public static void Main(string[] args)
{
using (ImageFactory imageFactory = new ImageFactory(true))
{
Size size = new Size(200, 200);
Size size = new Size(800, 0);

// Load, resize, set the format and quality and save an image.
imageFactory.Load(inStream)
.Constrain(size)
//.BackgroundColor(Color.White)
//.Resize(new Size((int)(size.Width * 1.1), 0))
.ContentAwareResize(size)
//.Constrain(size)
.Save(Path.GetFullPath(Path.Combine(Path.GetDirectoryName(path), @"..\..\images\output", fileInfo.Name)));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
7f6786517fa67c9dfccac831e8491e4d08866d24
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
7eb554b7681119b1170b70f1c1c2fc0de28a60ac
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
8d39e89104598b85035a2c29592b847edcfdb8ac
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ff6cd6bf1cd388e8933071ec36880c33d1bc08f2
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
68e14cae5c31c58b8b66d26bca6eb67c79ecd203
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
c679b986c1ccbd9f6f8d72d7e4717f380b923a75
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
6b1252209f60025427722f765dbbc271d125114e
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
66b1f9f5ef7ca628ca4a44de9188e11e4af17229
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
414f5a48bd8d020beae85c2dee480cb5d22ec9b7
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
a2cccdee0f806b2d41bfcdbb2dc9a1fe3d8656c6
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
99704952050f56a69f591220bb9f0f2014215c7f
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
98c3f8fce4fdd9eebafe12431c8e014fd39d243f
Original file line number Diff line number Diff line change
@@ -1 +1 @@
30ec5c05548fd350f9b7c699715848b9fbfb8ca9
e41022eb5fe724ba5fe2b7aeda29a1f4b6878484
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
33f7e25da5675197f18bb2fa2c9fe5fa366e84ec
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
f24f17627804b11d823240d49c91ec17fb7fd55d
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
def19dd7469cf2eba1f595e7263d9d48fda85825
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
8cf61b55acca1a3d1a69177ddc439685ee0ba192
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
629284a6f834f5d1cf185e3603a50c484dd9121a
Original file line number Diff line number Diff line change
@@ -1 +1 @@
fdc62fc2d056ab885eb9e8fd12b9155ee86d7c43
f5681324d193a42492647f4952057c2b72026096
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3d652e0628f2042e7aca0751384ba21f1182ef5f
4 changes: 2 additions & 2 deletions src/ImageProcessorConsole/images/output/circle.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
d8d3354b684cad79d9a46f92ed3a58747a808ad1
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1c48519b2675b9dd90e8e95d6421148b25b8c317
Original file line number Diff line number Diff line change
@@ -1 +1 @@
23a1c81a2d1422076373796e0c47f5d968c56d0b
b65d9e937cad7ddd02ff0d01a3be2f09c55e63e8
3 changes: 3 additions & 0 deletions src/ImageProcessorConsole/images/output/night-bridge.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 0 additions & 3 deletions src/ImageProcessorConsole/images/output/rotate.jpg

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
a0aa8338f74f3539c2531f43fa9027a3ce0a39fb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
04f6093d3345a4c8b48333c32972753dd0949730
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
f7b1543810ada7598773d6ee31bc7c0c20afaa9f
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
2d5b165c27545a3860d8a6b35f8ac4438f57593a
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="CairBootstrapper.cs" company="James South">
// Copyright (c) James South.
// Licensed under the Apache License, Version 2.0.
// </copyright>
// <summary>
// Defines the CairBootstrapper type.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace ImageProcessor.Plugins.Cair
{
using System;
using System.IO;
using System.Reflection;

using ImageProcessor.Configuration;

/// <summary>
/// The cair bootstrapper.
/// </summary>
internal static class CairBootstrapper
{
/// <summary>
/// Initializes static members of the <see cref="CairBootstrapper"/> class.
/// </summary>
static CairBootstrapper()
{
RegisterCairExecutable();
}

/// <summary>
/// Gets the cair path.
/// </summary>
public static string CairPath { get; private set; }

/// <summary>
/// Gets the cair image path.
/// </summary>
public static string CairImagePath { get; private set; }

/// <summary>
/// Registers the embedded CAIR executable.
/// </summary>
public static void RegisterCairExecutable()
{
// None of the tools used here are called using dllimport so we don't go through the normal registration channel.
string folder = ImageProcessorBootstrapper.Instance.NativeBinaryFactory.Is64BitEnvironment ? "x64" : "x86";
Assembly assembly = Assembly.GetExecutingAssembly();
string targetBasePath = new Uri(assembly.Location).LocalPath;
string multithreaderTargetPath = Path.GetFullPath(Path.Combine(targetBasePath, "..\\" + folder + "\\" + "pthreadVSE2.dll"));

// Set the global variable.
CairPath = Path.GetFullPath(Path.Combine(targetBasePath, "..\\" + folder + "\\" + "CAIR.exe"));
CairImagePath = Path.GetFullPath(Path.Combine(targetBasePath, "..\\" + folder + "\\" + "cairimages\\"));

// Get the resources and copy them across.
const string CairResourcePath = "ImageProcessor.Plugins.Cair.Resources.Unmanaged.x86.CAIR.exe";
const string MultithreaderResourcePath = "ImageProcessor.Plugins.Cair.Resources.Unmanaged.x86.pthreadVSE2.dll";

// Write the two files out to the bin folder.
// Copy out the threading binary.
using (Stream resourceStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(MultithreaderResourcePath))
{
if (resourceStream != null)
{
// ReSharper disable once AssignNullToNotNullAttribute
DirectoryInfo threaderDirectoryInfo = new DirectoryInfo(Path.GetDirectoryName(multithreaderTargetPath));
if (!threaderDirectoryInfo.Exists)
{
threaderDirectoryInfo.Create();
}

using (FileStream fileStream = File.OpenWrite(multithreaderTargetPath))
{
resourceStream.CopyTo(fileStream);
}
}
}

// Copy out the cair executable.
using (Stream resourceStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(CairResourcePath))
{
if (resourceStream != null)
{
// ReSharper disable once AssignNullToNotNullAttribute
DirectoryInfo cairDirectoryInfo = new DirectoryInfo(Path.GetDirectoryName(CairPath));
if (!cairDirectoryInfo.Exists)
{
cairDirectoryInfo.Create();
}

using (FileStream fileStream = File.OpenWrite(CairPath))
{
resourceStream.CopyTo(fileStream);
}
}
}

// Lastly create the image folder for storing temporary images.
// ReSharper disable once AssignNullToNotNullAttribute
DirectoryInfo directoryInfo = new DirectoryInfo(Path.GetDirectoryName(CairImagePath));
if (!directoryInfo.Exists)
{
directoryInfo.Create();
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="ImageFactoryExtensions.cs" company="James South">
// Copyright (c) James South.
// Licensed under the Apache License, Version 2.0.
// </copyright>
// <summary>
// Extends the ImageFactory class to provide a fluent API.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace ImageProcessor.Plugins.Cair
{
using System.Collections.Generic;
using System.Drawing;

using ImageProcessor.Plugins.Cair.Imaging;
using ImageProcessor.Plugins.Cair.Processors;

/// <summary>
/// Extends the ImageFactory class to provide a fluent API.
/// </summary>
public static class ImageFactoryExtensions
{
/// <summary>
/// Resizes the current image to the given dimensions using Content Aware Resizing.
/// </summary>
/// <param name="factory">
/// The current instance of the <see cref="T:ImageProcessor.ImageFactory"/> class
/// that this method extends.
/// </param>
/// <param name="size">
/// The <see cref="T:System.Drawing.Size"/> containing the width and height to set the image to.
/// </param>
/// <returns>
/// The current instance of the <see cref="T:ImageProcessor.ImageFactory"/> class.
/// </returns>
public static ImageFactory ContentAwareResize(this ImageFactory factory, Size size)
{
if (factory.ShouldProcess)
{
int width = size.Width;
int height = size.Height;

ContentAwareResizeLayer resizeLayer = new ContentAwareResizeLayer(new Size(width, height));
return factory.ContentAwareResize(resizeLayer);
}

return factory;
}

/// <summary>
/// Resizes the current image to the given dimensions using Content Aware Resizing.
/// </summary>
/// <param name="factory">
/// The current instance of the <see cref="T:ImageProcessor.ImageFactory"/> class
/// that this method extends.
/// </param>
/// <param name="layer">
/// The <see cref="ContentAwareResizeLayer"/> containing the properties required to resize the image.
/// </param>
/// <returns>
/// The current instance of the <see cref="T:ImageProcessor.ImageFactory"/> class.
/// </returns>
public static ImageFactory ContentAwareResize(this ImageFactory factory, ContentAwareResizeLayer layer)
{
if (factory.ShouldProcess)
{
Dictionary<string, string> resizeSettings = new Dictionary<string, string> { { "MaxWidth", layer.Size.Width.ToString("G") }, { "MaxHeight", layer.Size.Height.ToString("G") } };

ContentAwareResize resize = new ContentAwareResize { DynamicParameter = layer, Settings = resizeSettings };
factory.CurrentImageFormat.ApplyProcessor(resize.ProcessImage, factory);
}

return factory;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{C7D1F0DD-CBD6-4127-82B4-51949EFF0BF5}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>ImageProcessor.Plugins.Cair</RootNamespace>
<AssemblyName>ImageProcessor.Plugins.Cair</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="CairBootstrapper.cs" />
<Compile Include="ImageFactoryExtensions.cs" />
<Compile Include="Imaging\ContentAwareResizeConvolutionType.cs" />
<Compile Include="Imaging\ContentAwareResizeLayer.cs" />
<Compile Include="Imaging\EnergyFunction.cs" />
<Compile Include="Processors\ContentAwareResize.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\ImageProcessor\ImageProcessor.csproj">
<Project>{3b5dd734-fb7a-487d-8ce6-55e7af9aea7e}</Project>
<Name>ImageProcessor</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Resources\Unmanaged\x86\CAIR.exe" />
<None Include="Resources\Unmanaged\x86\GPL.txt" />
<EmbeddedResource Include="Resources\Unmanaged\x86\pthreadVSE2.dll" />
<None Include="Resources\Unmanaged\x86\ReadMe.txt" />
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="ContentAwareResizeConvolutionType.cs" company="James South">
// Copyright (c) James South.
// Licensed under the Apache License, Version 2.0.
// </copyright>
// <summary>
// Provides enumeration of the content aware resize convolution types.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace ImageProcessor.Plugins.Cair.Imaging
{
/// <summary>
/// Provides enumeration of the content aware resize convolution types.
/// </summary>
public enum ContentAwareResizeConvolutionType
{
/// <summary>
/// The Prewitt kernel convolution type.
/// </summary>
Prewitt = 0,

/// <summary>
/// The V1 kernel convolution type.
/// </summary>
V1 = 1,

/// <summary>
/// The VSquare kernel convolution type.
/// </summary>
VSquare = 2,

/// <summary>
/// The Sobel kernel convolution type.
/// </summary>
Sobel = 3,

/// <summary>
/// The Laplacian kernel convolution type.
/// </summary>
Laplacian = 4
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="ContentAwareResizeLayer.cs" company="James South">
// Copyright (c) James South.
// Licensed under the Apache License, Version 2.0.
// </copyright>
// <summary>
// Encapsulates the properties required to resize an image using content aware resizing.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace ImageProcessor.Plugins.Cair.Imaging
{
using System.Drawing;

/// <summary>
/// Encapsulates the properties required to resize an image using content aware resizing.
/// </summary>
public class ContentAwareResizeLayer
{
/// <summary>
/// The convolution type to apply to the layer.
/// </summary>
private ContentAwareResizeConvolutionType convolutionType = ContentAwareResizeConvolutionType.Prewitt;

/// <summary>
/// The energy function to apply to the layer.
/// </summary>
private EnergyFunction energyFunction = EnergyFunction.Forward;

/// <summary>
/// Whether to assign multiple threads to the resizing method.
/// </summary>
private bool parallelize = true;

/// <summary>
/// Whether to pre-scale the image to reduce errors in the output.
/// </summary>
private bool prescale = true;

/// <summary>
/// The timeout in milliseconds to attempt to resize for.
/// </summary>
private int timeout = 60000;

/// <summary>
/// Initializes a new instance of the <see cref="ContentAwareResizeLayer"/> class.
/// </summary>
/// <param name="size">
/// The <see cref="T:System.Drawing.Size"/> containing the width and height to set the image to.
/// </param>
public ContentAwareResizeLayer(Size size)
{
this.Size = size;
}

/// <summary>
/// Gets or sets the size.
/// </summary>
public Size Size { get; set; }

/// <summary>
/// Gets or sets the content aware resize convolution type (Default ContentAwareResizeConvolutionType.Prewitt).
/// </summary>
public ContentAwareResizeConvolutionType ConvolutionType
{
get
{
return this.convolutionType;
}

set
{
this.convolutionType = value;
}
}

/// <summary>
/// Gets or sets the energy function (Default EnergyFunction.Forward).
/// </summary>
public EnergyFunction EnergyFunction
{
get
{
return this.energyFunction;
}

set
{
this.energyFunction = value;
}
}

/// <summary>
/// Gets or sets a value indicating whether to assign multiple threads to the resizing method.
/// (Default true)
/// </summary>
public bool Parallelize
{
get
{
return this.parallelize;
}

set
{
this.parallelize = value;
}
}

/// <summary>
/// Gets or sets a value indicating whether to pre-scale the image to reduce errors in the output.
/// (Default true)
/// </summary>
public bool PreScale
{
get
{
return this.prescale;
}

set
{
this.prescale = value;
}
}

/// <summary>
/// Gets or sets the timeout in milliseconds to attempt to resize for (Default 60000).
/// </summary>
public int Timeout
{
get
{
return this.timeout;
}

set
{
this.timeout = value;
}
}

/// <summary>
/// Returns a value that indicates whether the specified object is an
/// <see cref="ContentAwareResizeLayer"/> object that is equivalent to
/// this <see cref="ContentAwareResizeLayer"/> object.
/// </summary>
/// <param name="obj">
/// The object to test.
/// </param>
/// <returns>
/// True if the given object is an <see cref="ContentAwareResizeLayer"/> object that is equivalent to
/// this <see cref="ContentAwareResizeLayer"/> object; otherwise, false.
/// </returns>
public override bool Equals(object obj)
{
ContentAwareResizeLayer resizeLayer = obj as ContentAwareResizeLayer;

if (resizeLayer == null)
{
return false;
}

return this.Size == resizeLayer.Size
&& this.ConvolutionType == resizeLayer.ConvolutionType;
}

/// <summary>
/// Returns a hash code value that represents this object.
/// </summary>
/// <returns>
/// A hash code that represents this object.
/// </returns>
public override int GetHashCode()
{
return this.Size.GetHashCode() + this.ConvolutionType.GetHashCode();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="EnergyFunction.cs" company="James South">
// Copyright (c) James South.
// Licensed under the Apache License, Version 2.0.
// </copyright>
// <summary>
// Enumerates the energy functions available to the resize method.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace ImageProcessor.Plugins.Cair.Imaging
{
/// <summary>
/// Enumerates the energy functions available to the resize method.
/// </summary>
public enum EnergyFunction
{
/// <summary>
/// The standard energy function.
/// </summary>
Backward = 0,

/// <summary>
/// The forward energy function. A look-ahead is performed to reduce jagged edges
/// caused by removing areas of low energy.
/// </summary>
Forward = 1
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,239 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="ContentAwareResize.cs" company="James South">
// Copyright (c) James South.
// Licensed under the Apache License, Version 2.0.
// </copyright>
// <summary>
// Resizes an image to the given dimensions using content aware resizing.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace ImageProcessor.Plugins.Cair.Processors
{
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.Globalization;
using System.IO;

using ImageProcessor.Common.Exceptions;
using ImageProcessor.Imaging;
using ImageProcessor.Plugins.Cair.Imaging;
using ImageProcessor.Processors;

/// <summary>
/// Resizes an image to the given dimensions using content aware resizing.
/// </summary>
public class ContentAwareResize : IGraphicsProcessor
{
/// <summary>
/// Initializes a new instance of the <see cref="ContentAwareResize"/> class.
/// </summary>
public ContentAwareResize()
{
this.Settings = new Dictionary<string, string>();
}

/// <summary>
/// Gets or sets 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 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 System.Drawing.Image ProcessImage(ImageFactory factory)
{
string fileName = Guid.NewGuid().ToString();

// Use bmp's as the temporary files since they are lossless and support transparency.
string sourcePath = Path.Combine(CairBootstrapper.CairImagePath, fileName + ".bmp");
string resizedPath = Path.Combine(CairBootstrapper.CairImagePath, fileName + "-r.bmp");

// Gather the parameters.
int width = this.DynamicParameter.Size.Width ?? 0;
int height = this.DynamicParameter.Size.Height ?? 0;
ContentAwareResizeConvolutionType convolutionType = this.DynamicParameter.ConvolutionType;
EnergyFunction energyFunction = this.DynamicParameter.EnergyFunction;
bool prescale = this.DynamicParameter.PreScale;
bool parallelize = this.DynamicParameter.Parallelize;
int timeout = this.DynamicParameter.Timeout ?? 60000;

int defaultMaxWidth;
int defaultMaxHeight;

int.TryParse(this.Settings["MaxWidth"], NumberStyles.Any, CultureInfo.InvariantCulture, out defaultMaxWidth);
int.TryParse(this.Settings["MaxHeight"], NumberStyles.Any, CultureInfo.InvariantCulture, out defaultMaxHeight);

Bitmap newImage = null;
Image image = factory.Image;

try
{
int sourceWidth = image.Width;
int sourceHeight = image.Height;

// Fractional variants for preserving aspect ratio.
double percentHeight = Math.Abs(height / (double)sourceHeight);
double percentWidth = Math.Abs(width / (double)sourceWidth);

int maxWidth = defaultMaxWidth > 0 ? defaultMaxWidth : int.MaxValue;
int maxHeight = defaultMaxHeight > 0 ? defaultMaxHeight : int.MaxValue;

// If height or width is not passed we assume that the standard ratio is to be kept.
if (height == 0)
{
height = (int)Math.Ceiling(sourceHeight * percentWidth);
}

if (width == 0)
{
width = (int)Math.Ceiling(sourceWidth * percentHeight);
}

if (width > 0 && height > 0 && width <= maxWidth && height <= maxHeight)
{
if (prescale)
{
if (width < image.Width || height < image.Height)
{
int preWidth = Math.Min(image.Width, width + 50); //(int)Math.Ceiling(width * 1.25));
ResizeLayer layer = new ResizeLayer(new Size(preWidth, 0));
Dictionary<string, string> resizeSettings = new Dictionary<string, string>
{
{
"MaxWidth", image.Width.ToString("G")
},
{
"MaxHeight", image.Height.ToString("G")
}
};
Resize resize = new Resize { DynamicParameter = layer, Settings = resizeSettings };
image = resize.ProcessImage(factory);
}
}

// Save the temporary bitmap.
image.Save(sourcePath, ImageFormat.Bmp);

// Process the image using the CAIR executable.
string arguments = string.Format(
" -I \"{0}\" -O \"{1}\" -C {2} -X {3} -Y {4} -E {5} -T {6}",
sourcePath,
resizedPath,
(int)convolutionType,
width,
height,
(int)energyFunction,
parallelize ? Math.Min(4, Environment.ProcessorCount) : 1);

bool success = this.ProcessCairImage(arguments, timeout);

if (!success)
{
throw new ImageProcessingException(
"Error processing image with " + this.GetType().Name + " due to timeout.");
}

// Assign the new image.
newImage = new Bitmap(resizedPath);
newImage.MakeTransparent();

// Reassign the image.
image.Dispose();
image = newImage;
}
}
catch (Exception ex)
{
if (newImage != null)
{
newImage.Dispose();
}

throw new ImageProcessingException("Error processing image with " + this.GetType().Name, ex);
}
finally
{
FileInfo sourceFileInfo = new FileInfo(sourcePath);
if (sourceFileInfo.Exists)
{
sourceFileInfo.Delete();
}

FileInfo resizedFileInfo = new FileInfo(resizedPath);
if (resizedFileInfo.Exists)
{
resizedFileInfo.Delete();
}
}

return image;
}

/// <summary>
/// The process cair image.
/// </summary>
/// <param name="arguments">
/// The arguments.
/// </param>
/// <param name="timeout">
/// The time in milliseconds to attempt to resize the image for.
/// </param>
/// <returns>
/// The <see cref="bool"/>.
/// </returns>
private bool ProcessCairImage(string arguments, int timeout)
{
// Set up and start a new process to resize the image.
ProcessStartInfo start = new ProcessStartInfo(CairBootstrapper.CairPath, arguments)
{
WindowStyle = ProcessWindowStyle.Hidden,
UseShellExecute = false,
RedirectStandardInput = true,
RedirectStandardError = true,
RedirectStandardOutput = true,
CreateNoWindow = true,
};

using (Process process = Process.Start(start))
{
if (process != null)
{
bool result = process.WaitForExit(timeout);

if (!result)
{
process.Kill();
}

return result;
}
}

return false;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("ImageProcessor.Plugins.Cair")]
[assembly: AssemblyDescription("Adds Content Aware Image Resizing to ImageProcessor")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ImageProcessor.Plugins.Cair")]
[assembly: AssemblyCopyright("Copyright James South © 2014")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]

// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("e0e88a19-d3ea-4f9c-ab3d-8c871359dc59")]

// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
83a4594cf9aeb54e509a1cd04528e414eb673161

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,282 @@
User's ReadMe v2.18

CAIR - Content Aware Image Resizer
Copyright (C) 2008 Joseph Auman (brain.recall@gmail.com)

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA

+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+

CAIR is an image resizing library that is based on the works of Shai Avidan and
Ariel Shamir. It is a high-performance multi-threaded library written in C++.
It is intended to be multi-platform and multi-architecture.


I am looking into implementing Poisson image reconstruction, which is mentioned
in the paper, to be used in CAIR_HD(). See the paper on the subject here:
http://research.microsoft.com/vision/cambridge/papers/perez_siggraph03.pdf
However, I�m having a bit of difficulty understanding the method and how I can
apply it to seam removal. If you know something about digital image processing
and are willing to help, please email me at brain.recall@gmail.com


Compiling CAIR is not difficult. A Makefile for Linux is included to demonstrate.
Compiling under Visual Studio is a bit different, since the pthread DLL library
and object library must be included for the linker. I suggest Google to see how
it's done. Whenever possible, I *highly* suggest using the Intel C++ compiler,
which gives about a 10% speed boost when all the optimization options are
turned on. It's freely available for the Linux platform, but Windows and Mac
license are in the $600 range outside of the 30 day trial.

+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+

In this file I'm going to present each file and its functions. This is going to
targeted at "users" of the library (those actually making a GUI with it). Further
detail can be gained by reading the source code (don't worry, I take *some* pride
in my comments, but pthread experience would be helpful).


CAIR_CML.h
=================================================================================
The CAIR Matrix Library. A template class used to hold the image information
in CAIR. The CML requires a size when creating the object. See main.cpp for
some examples in declaring and interfacing with the CML_Matrix.

- Depends on: nothing outside of the STL

- Types defined:
-- CML_byte - An unsigned char used for each color channel.
-- CML_RGBA - Structure for a 32 bit color pixel.
- Each channel is a CML_byte, named as: red, green, blue, alpha
-- CML_color - A color matrix, replaces CML_Matrix<CML_RGBA>; use for images.
-- CML_int - An integer matrix, replaces CML_Matrix<int>; use for weights.

- Methods (the important ones, at least):
-- CML_Matrix( int x, int y )
--- Simple constructor. Requires the intended size of the matrix (can be changed
later, so dummy values of (1,1) could be used).
-- void Fill( T value )
--- Sets all elements of the matrix to the given value.
-- operator()( int x, int y )
--- Accessor and assignment methods, used to set and get matrix values.
--- These have no bounds checking.
-- int Width()
--- Returns the width of the matrix.
-- int Height()
--- Returns the height of the matrix.
-- void Transpose( CML_Matrix<T> * Source )
--- Rotates Source on edge, storing the result into the matrix.
-- T Get( int x, int y )
--- Accessor function with full bounds checking. Out-of-bound accesses will be
constrained back into the matrix.
-- void D_Resize( int x, int y )
--- Destructively resize the matrix to the given values.
-- void Resize_Width( int x )
--- Careful with this one. Performs non-destructive "resizing" but only in the x
direction. Essentially only changes what Width() will report. Enlarging should
be done only after a Reserve(), for performance reasons.
-- void Shift_Row( int x, int y, int shift )
--- Shift the elements of a row, starting the (x,y) element. Shift determines
amount of shift and direction. Negative will shift left, positive for right.



CAIR.h
=================================================================================
The CAIR function declarations.

Depends on: CAIR_CML.h
Types defined:
-- CAIR_NUM_THREADS - The number of default threads that will be used for Grayscale, Edge, and Add/Remove operations.
-- CAIR_direction - An enumeration for CAIR_Removal() with the values of AUTO,
VERTICAL, and HORIZONTAL. AUTO lets CAIR_Remvoal() determine
the best direction to remove seams. VERTICAL and HORIZONTAL
force the function to remove from their respective directions.
-- CAIR_convolution - An enumeration for all CAIR operations. It defines the available
convolution kernels. They include:
Prewitt: An X-Y kernel for decent edge detection.
Sobel: Works very much like Prewitt.
V1: Only the X-component of the Prewitt. More of an object detector
than strictly edges. Works well under some cases.
V_SQUARE: The result of V1 squared. This provides some of the
best object detection, thus some of the best operation.
Laplacian: A second-order edge detector. Nothing spectacular.
-- CAIR_energy - An enumeration for all CAIR energy algorithms.
Backward: The traditional energy algorithm.
Forward: The new energy algorithm that determines future edge changes and tries
to redirect seams away from potential artifacts. Comes at a slight performance hit.

Functions:
- void CAIR_Threads( int thread_count )
-- thread_count: the number of threads that the Grayscale/Edge/Add/Remove operations should use. Minimum of two.

- bool CAIR( CML_color * Source,
CML_int * S_Weights,
int goal_x,
int goal_y,
CAIR_convolution conv,
CAIR_energy ener,
CML_int * D_Weights,
CML_color * Dest,
bool (*CAIR_callback)(float) )
-- Source: pointer to the source image
-- S_Weights: pointer to the weights of the image, must be the same size as Source
The weights allow for linear protection and removal of desired portions of an
image. The values of the weights should not exceed -2,000,000 to 2,000,000 to
avoid integer overflows. Generally, I found a -10,000 to 10,000 range to be
adequate. Large values will protect pixel, while small values will make it
more likely to be removed first. ALWAYS use negative values for removal. When
no preference is given to a pixel, leave its value to zero. (I suggest Fill()'ing
the weight matrix with 0 before use, since the memory is not initialized when
allocated.)
-- goal_x: the desired width of the Dest image
-- goal_y: the desired height of the Dest image
-- conv: The possible convolution kernels to use. See the above discussion.
It is important to note that if using V_SQUARE the weights must be at least an order
of magnitude larger for similar operation. add_weight needs to be several orders of
magnitude larger to avoid some stretching. This is because V_SQUARE produces larger
edge values, and thus large energy values.
-- ener: The possible energy algorithms to use. See the above discussion.
-- D_Weights: pointer to the Destination Weights (contents will be destroyed)
-- Dest: pointer to the Destination image (contents will be destroyed)
-- CAIR_callback: a function pointer to a status/callback system. The function is expected
to take a float of the percent complete (from 0 to 1) and is to return a false if the
resize is to be canceled, or true otherwise. If the resize is canceled, CAIR() will return
a false, leaving Dest and D_Weights in an unknown state. Set to NULL if not used.
-- RETURNS: true if the resize ran to completion, false if it was canceled by CAIR_callback.

- void CAIR_Grayscale( CML_color * Source, CML_color * Dest )
-- Source: pointer to the source image
-- Dest: The grayscale of Source image. The gray value will be computed, then applied
to the three color channels to give the grayscale equivalent.
- void CAIR_Edge( CML_color * Source, CAIR_convolution conv, CML_color * Dest )
-- Source: pointer to the source image
-- conv: The edge detection kernel.
-- Dest: The dge detection of the source image. Values larger than a CML_byte
(255 in decimal) will be clipped down to 255.

- CAIR_V_Energy( CML_color * Source, CAIR_convolution conv, CAIR_energy ener, CML_color * Dest ) and CAIR_H_Energy( CML_color * Source, CAIR_convolution conv, CAIR_energy ener, CML_color * Dest )
-- Source: pointer to the source image
-- conv: The edge detection kernel.
-- ener: The energy algorithm.
-- Dest: The grayscale equivalent of the energy map of the source image. All values
are scaled down realtive to the largest value. Weights are assumed all zero,
since when they are not they dominate the image and produce uninteresting results.

- bool CAIR_Removal( CML_color * Source,
CML_int * S_Weights,
CAIR_direction choice,
int max_attempts,
CAIR_convolution conv,
CAIR_energy ener,
CML_int * D_Weights,
CML_color * Dest,
bool (*CAIR_callback)(float) )
-- EXPERIMENTAL
-- S_Weights: pointer to the given weights of the image
-- choice: How the algorithm will remove the seams. In AUTO mode, it will count the
negative rows (for horizontal removal) and the negative columns (for vertical removal)
and then removes the least amount in that direction. Other settings will cause it to
remove in thier respective directions. After the removal, it is expanded back out to
its origional dimensions.
-- max_attempts: The number of retries the algorithm will do to remove remaining negative
weights. Sometimes the algorithm may not remove everything in one pass, and this attempts
to give the algorithm another chance at it. There are situations, however, where the
algorithm will not be able to remove the requested portions due to other areas makred
for protection with a high weight.
-- conv: The edge detection kernel.
-- ener: The energy algorithm.
-- D_Weights: pointer to the destination weights
-- Dest: pointer to the destination image
-- CAIR_callback: a function pointer to a status/callback system
-- RETURNS: true if the resize ran to completion, false if it was canceled by CAIR_callback.

- bool CAIR_HD( CML_color * Source,
CML_int * S_Weights,
int goal_x,
int goal_y,
CAIR_convolution conv,
CAIR_energy ener,
CML_int * D_Weights,
CML_color * Dest,
bool (*CAIR_callback)(float) )
-- See CAIR() for the same paramaters.
-- CAIR_HD() is designed for quality, not speed. At each itteration, CAIR_HD()
determines which direction produces the least energy path for removal. It then
removes that path. CAIR_HD() can enlarge, but currently employs standard CAIR()
to perform it.

CAIR.cpp
=================================================================================
The CAIR function definitions. Nothing really important to the user, except its
dependencies.

Depends on: CAIR_CML.h, CAIR.h, pthread.h
Types defined: none visible
Functions: none visible



main.cpp
=================================================================================
An example application that uses CAIR (mostly for testing by me). Functions to
read the source on are BMP_to_CML() and CML_to_BMP() to get an example on how to
convert to and from the CML.

- Depends on: CAIR_CML.h, CAIR.h, EasyBMP.h
Types defined: none
Functions: nothing really important


+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
Content Amplification

This is described in the paper, but I'll mention it here as well. This method
allows an object in the image to appear larger. Do this as following:
1) Enlarge an image using a standard linear technique by about 10% or so (more
than 25% might cause some artifacts).
2) Optional: Set a large weight for the desired object.
3) Seam carve the enlarged image back down to the origional size.

+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+


Other Links:
http://brain.recall.googlepages.com/cair
http://c-a-i-r.wiki.sourceforge.net/
http://sourceforge.net/projects/c-a-i-r/
http://code.google.com/p/seam-carving-gui/
http://www.faculty.idc.ac.il/arik/papers/imret.pdf
http://www.faculty.idc.ac.il/arik/papers/vidRet.pdf

Special Thanks:
Ariel Shamir
Shai Avidan
Michael Rubinstein
Ramin Sabet
Brett Taylor
Gabe Rudy
Jean-Baptiste (Jib)
David Phillip Oster
Matt Newell
Klaus Nordby
Alexandre Prokoudine
Peter Berrington

Further questions on CAIR can be directed to the source code, or my email.

Sincerely,
Brain_ReCall aka Joe Auman
brain.recall@gmail.com
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
af74faa46395cff6167217e471d0e9d8108bc829
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<StyleCopSettings Version="105">
<GlobalSettings>
<CollectionProperty Name="RecognizedWords">
<Value>cair</Value>
<Value>laplacian</Value>
<Value>sobel</Value>
</CollectionProperty>
</GlobalSettings>
</StyleCopSettings>
Original file line number Diff line number Diff line change
@@ -29,14 +29,15 @@ static NativeMethods()
{
string folder = ImageProcessorBootstrapper.Instance.NativeBinaryFactory.Is64BitEnvironment ? "x64" : "x86";
string name = string.Format("ImageProcessor.Plugins.WebP.Resources.Unmanaged.{0}.libwebp.dll", folder);
Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(name);

using (MemoryStream memoryStream = new MemoryStream())
using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(name))
{
if (stream != null)
using (MemoryStream memoryStream = new MemoryStream())
{
stream.CopyTo(memoryStream);
ImageProcessorBootstrapper.Instance.NativeBinaryFactory.RegisterNativeBinary("libwebp.dll", memoryStream.ToArray());
if (stream != null)
{
stream.CopyTo(memoryStream);
ImageProcessorBootstrapper.Instance.NativeBinaryFactory.RegisterNativeBinary("libwebp.dll", memoryStream.ToArray());
}
}
}
}
Original file line number Diff line number Diff line change
@@ -32,5 +32,5 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyVersion("1.0.1.0")]
[assembly: AssemblyFileVersion("1.0.1.0")]

0 comments on commit ef21a55

Please sign in to comment.