mirror of https://github.com/SixLabors/ImageSharp
52 changed files with 1631 additions and 22 deletions
@ -0,0 +1 @@ |
|||
7f6786517fa67c9dfccac831e8491e4d08866d24 |
|||
@ -0,0 +1 @@ |
|||
7eb554b7681119b1170b70f1c1c2fc0de28a60ac |
|||
@ -0,0 +1 @@ |
|||
8d39e89104598b85035a2c29592b847edcfdb8ac |
|||
@ -0,0 +1 @@ |
|||
ff6cd6bf1cd388e8933071ec36880c33d1bc08f2 |
|||
@ -0,0 +1 @@ |
|||
68e14cae5c31c58b8b66d26bca6eb67c79ecd203 |
|||
@ -0,0 +1 @@ |
|||
c679b986c1ccbd9f6f8d72d7e4717f380b923a75 |
|||
@ -0,0 +1 @@ |
|||
6b1252209f60025427722f765dbbc271d125114e |
|||
@ -0,0 +1 @@ |
|||
66b1f9f5ef7ca628ca4a44de9188e11e4af17229 |
|||
@ -0,0 +1 @@ |
|||
414f5a48bd8d020beae85c2dee480cb5d22ec9b7 |
|||
@ -0,0 +1 @@ |
|||
a2cccdee0f806b2d41bfcdbb2dc9a1fe3d8656c6 |
|||
@ -0,0 +1 @@ |
|||
99704952050f56a69f591220bb9f0f2014215c7f |
|||
@ -0,0 +1 @@ |
|||
98c3f8fce4fdd9eebafe12431c8e014fd39d243f |
|||
@ -1 +1 @@ |
|||
30ec5c05548fd350f9b7c699715848b9fbfb8ca9 |
|||
e41022eb5fe724ba5fe2b7aeda29a1f4b6878484 |
|||
@ -0,0 +1 @@ |
|||
33f7e25da5675197f18bb2fa2c9fe5fa366e84ec |
|||
@ -0,0 +1 @@ |
|||
f24f17627804b11d823240d49c91ec17fb7fd55d |
|||
@ -0,0 +1 @@ |
|||
def19dd7469cf2eba1f595e7263d9d48fda85825 |
|||
@ -0,0 +1 @@ |
|||
8cf61b55acca1a3d1a69177ddc439685ee0ba192 |
|||
@ -0,0 +1 @@ |
|||
629284a6f834f5d1cf185e3603a50c484dd9121a |
|||
@ -1 +1 @@ |
|||
fdc62fc2d056ab885eb9e8fd12b9155ee86d7c43 |
|||
f5681324d193a42492647f4952057c2b72026096 |
|||
@ -0,0 +1 @@ |
|||
3d652e0628f2042e7aca0751384ba21f1182ef5f |
|||
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 4.9 KiB |
@ -0,0 +1 @@ |
|||
d8d3354b684cad79d9a46f92ed3a58747a808ad1 |
|||
@ -0,0 +1 @@ |
|||
1c48519b2675b9dd90e8e95d6421148b25b8c317 |
|||
@ -1 +1 @@ |
|||
23a1c81a2d1422076373796e0c47f5d968c56d0b |
|||
b65d9e937cad7ddd02ff0d01a3be2f09c55e63e8 |
|||
|
After Width: | Height: | Size: 55 KiB |
|
Before Width: | Height: | Size: 18 KiB |
@ -0,0 +1 @@ |
|||
a0aa8338f74f3539c2531f43fa9027a3ce0a39fb |
|||
@ -0,0 +1 @@ |
|||
04f6093d3345a4c8b48333c32972753dd0949730 |
|||
@ -0,0 +1 @@ |
|||
f7b1543810ada7598773d6ee31bc7c0c20afaa9f |
|||
@ -0,0 +1 @@ |
|||
2d5b165c27545a3860d8a6b35f8ac4438f57593a |
|||
@ -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(); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -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; |
|||
} |
|||
} |
|||
} |
|||
@ -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> |
|||
@ -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 |
|||
} |
|||
} |
|||
@ -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(); |
|||
} |
|||
} |
|||
} |
|||
@ -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 |
|||
} |
|||
} |
|||
@ -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; |
|||
} |
|||
} |
|||
} |
|||
@ -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")] |
|||
@ -0,0 +1 @@ |
|||
83a4594cf9aeb54e509a1cd04528e414eb673161 |
|||
@ -0,0 +1,473 @@ |
|||
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 |
|||
|
|||
|
|||
GNU LESSER GENERAL PUBLIC LICENSE |
|||
Version 2.1, February 1999 |
|||
|
|||
Copyright (C) 1991, 1999 Free Software Foundation, Inc. |
|||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
|||
Everyone is permitted to copy and distribute verbatim copies |
|||
of this license document, but changing it is not allowed. |
|||
|
|||
[This is the first released version of the Lesser GPL. It also counts |
|||
as the successor of the GNU Library Public License, version 2, hence |
|||
the version number 2.1.] |
|||
|
|||
Preamble |
|||
|
|||
The licenses for most software are designed to take away your |
|||
freedom to share and change it. By contrast, the GNU General Public |
|||
Licenses are intended to guarantee your freedom to share and change |
|||
free software--to make sure the software is free for all its users. |
|||
|
|||
This license, the Lesser General Public License, applies to some |
|||
specially designated software packages--typically libraries--of the |
|||
Free Software Foundation and other authors who decide to use it. You |
|||
can use it too, but we suggest you first think carefully about whether |
|||
this license or the ordinary General Public License is the better |
|||
strategy to use in any particular case, based on the explanations below. |
|||
|
|||
When we speak of free software, we are referring to freedom of use, |
|||
not price. Our General Public Licenses are designed to make sure that |
|||
you have the freedom to distribute copies of free software (and charge |
|||
for this service if you wish); that you receive source code or can get |
|||
it if you want it; that you can change the software and use pieces of |
|||
it in new free programs; and that you are informed that you can do |
|||
these things. |
|||
|
|||
To protect your rights, we need to make restrictions that forbid |
|||
distributors to deny you these rights or to ask you to surrender these |
|||
rights. These restrictions translate to certain responsibilities for |
|||
you if you distribute copies of the library or if you modify it. |
|||
|
|||
For example, if you distribute copies of the library, whether gratis |
|||
or for a fee, you must give the recipients all the rights that we gave |
|||
you. You must make sure that they, too, receive or can get the source |
|||
code. If you link other code with the library, you must provide |
|||
complete object files to the recipients, so that they can relink them |
|||
with the library after making changes to the library and recompiling |
|||
it. And you must show them these terms so they know their rights. |
|||
|
|||
We protect your rights with a two-step method: (1) we copyright the |
|||
library, and (2) we offer you this license, which gives you legal |
|||
permission to copy, distribute and/or modify the library. |
|||
|
|||
To protect each distributor, we want to make it very clear that |
|||
there is no warranty for the free library. Also, if the library is |
|||
modified by someone else and passed on, the recipients should know |
|||
that what they have is not the original version, so that the original |
|||
author's reputation will not be affected by problems that might be |
|||
introduced by others. |
|||
|
|||
Finally, software patents pose a constant threat to the existence of |
|||
any free program. We wish to make sure that a company cannot |
|||
effectively restrict the users of a free program by obtaining a |
|||
restrictive license from a patent holder. Therefore, we insist that |
|||
any patent license obtained for a version of the library must be |
|||
consistent with the full freedom of use specified in this license. |
|||
|
|||
Most GNU software, including some libraries, is covered by the |
|||
ordinary GNU General Public License. This license, the GNU Lesser |
|||
General Public License, applies to certain designated libraries, and |
|||
is quite different from the ordinary General Public License. We use |
|||
this license for certain libraries in order to permit linking those |
|||
libraries into non-free programs. |
|||
|
|||
When a program is linked with a library, whether statically or using |
|||
a shared library, the combination of the two is legally speaking a |
|||
combined work, a derivative of the original library. The ordinary |
|||
General Public License therefore permits such linking only if the |
|||
entire combination fits its criteria of freedom. The Lesser General |
|||
Public License permits more lax criteria for linking other code with |
|||
the library. |
|||
|
|||
We call this license the "Lesser" General Public License because it |
|||
does Less to protect the user's freedom than the ordinary General |
|||
Public License. It also provides other free software developers Less |
|||
of an advantage over competing non-free programs. These disadvantages |
|||
are the reason we use the ordinary General Public License for many |
|||
libraries. However, the Lesser license provides advantages in certain |
|||
special circumstances. |
|||
|
|||
For example, on rare occasions, there may be a special need to |
|||
encourage the widest possible use of a certain library, so that it becomes |
|||
a de-facto standard. To achieve this, non-free programs must be |
|||
allowed to use the library. A more frequent case is that a free |
|||
library does the same job as widely used non-free libraries. In this |
|||
case, there is little to gain by limiting the free library to free |
|||
software only, so we use the Lesser General Public License. |
|||
|
|||
In other cases, permission to use a particular library in non-free |
|||
programs enables a greater number of people to use a large body of |
|||
free software. For example, permission to use the GNU C Library in |
|||
non-free programs enables many more people to use the whole GNU |
|||
operating system, as well as its variant, the GNU/Linux operating |
|||
system. |
|||
|
|||
Although the Lesser General Public License is Less protective of the |
|||
users' freedom, it does ensure that the user of a program that is |
|||
linked with the Library has the freedom and the wherewithal to run |
|||
that program using a modified version of the Library. |
|||
|
|||
The precise terms and conditions for copying, distribution and |
|||
modification follow. Pay close attention to the difference between a |
|||
"work based on the library" and a "work that uses the library". The |
|||
former contains code derived from the library, whereas the latter must |
|||
be combined with the library in order to run. |
|||
|
|||
GNU LESSER GENERAL PUBLIC LICENSE |
|||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION |
|||
|
|||
0. This License Agreement applies to any software library or other |
|||
program which contains a notice placed by the copyright holder or |
|||
other authorized party saying it may be distributed under the terms of |
|||
this Lesser General Public License (also called "this License"). |
|||
Each licensee is addressed as "you". |
|||
|
|||
A "library" means a collection of software functions and/or data |
|||
prepared so as to be conveniently linked with application programs |
|||
(which use some of those functions and data) to form executables. |
|||
|
|||
The "Library", below, refers to any such software library or work |
|||
which has been distributed under these terms. A "work based on the |
|||
Library" means either the Library or any derivative work under |
|||
copyright law: that is to say, a work containing the Library or a |
|||
portion of it, either verbatim or with modifications and/or translated |
|||
straightforwardly into another language. (Hereinafter, translation is |
|||
included without limitation in the term "modification".) |
|||
|
|||
"Source code" for a work means the preferred form of the work for |
|||
making modifications to it. For a library, complete source code means |
|||
all the source code for all modules it contains, plus any associated |
|||
interface definition files, plus the scripts used to control compilation |
|||
and installation of the library. |
|||
|
|||
Activities other than copying, distribution and modification are not |
|||
covered by this License; they are outside its scope. The act of |
|||
running a program using the Library is not restricted, and output from |
|||
such a program is covered only if its contents constitute a work based |
|||
on the Library (independent of the use of the Library in a tool for |
|||
writing it). Whether that is true depends on what the Library does |
|||
and what the program that uses the Library does. |
|||
|
|||
1. You may copy and distribute verbatim copies of the Library's |
|||
complete source code as you receive it, in any medium, provided that |
|||
you conspicuously and appropriately publish on each copy an |
|||
appropriate copyright notice and disclaimer of warranty; keep intact |
|||
all the notices that refer to this License and to the absence of any |
|||
warranty; and distribute a copy of this License along with the |
|||
Library. |
|||
|
|||
You may charge a fee for the physical act of transferring a copy, |
|||
and you may at your option offer warranty protection in exchange for a |
|||
fee. |
|||
|
|||
2. You may modify your copy or copies of the Library or any portion |
|||
of it, thus forming a work based on the Library, and copy and |
|||
distribute such modifications or work under the terms of Section 1 |
|||
above, provided that you also meet all of these conditions: |
|||
|
|||
a) The modified work must itself be a software library. |
|||
|
|||
b) You must cause the files modified to carry prominent notices |
|||
stating that you changed the files and the date of any change. |
|||
|
|||
c) You must cause the whole of the work to be licensed at no |
|||
charge to all third parties under the terms of this License. |
|||
|
|||
d) If a facility in the modified Library refers to a function or a |
|||
table of data to be supplied by an application program that uses |
|||
the facility, other than as an argument passed when the facility |
|||
is invoked, then you must make a good faith effort to ensure that, |
|||
in the event an application does not supply such function or |
|||
table, the facility still operates, and performs whatever part of |
|||
its purpose remains meaningful. |
|||
|
|||
(For example, a function in a library to compute square roots has |
|||
a purpose that is entirely well-defined independent of the |
|||
application. Therefore, Subsection 2d requires that any |
|||
application-supplied function or table used by this function must |
|||
be optional: if the application does not supply it, the square |
|||
root function must still compute square roots.) |
|||
|
|||
These requirements apply to the modified work as a whole. If |
|||
identifiable sections of that work are not derived from the Library, |
|||
and can be reasonably considered independent and separate works in |
|||
themselves, then this License, and its terms, do not apply to those |
|||
sections when you distribute them as separate works. But when you |
|||
distribute the same sections as part of a whole which is a work based |
|||
on the Library, the distribution of the whole must be on the terms of |
|||
this License, whose permissions for other licensees extend to the |
|||
entire whole, and thus to each and every part regardless of who wrote |
|||
it. |
|||
|
|||
Thus, it is not the intent of this section to claim rights or contest |
|||
your rights to work written entirely by you; rather, the intent is to |
|||
exercise the right to control the distribution of derivative or |
|||
collective works based on the Library. |
|||
|
|||
In addition, mere aggregation of another work not based on the Library |
|||
with the Library (or with a work based on the Library) on a volume of |
|||
a storage or distribution medium does not bring the other work under |
|||
the scope of this License. |
|||
|
|||
3. You may opt to apply the terms of the ordinary GNU General Public |
|||
License instead of this License to a given copy of the Library. To do |
|||
this, you must alter all the notices that refer to this License, so |
|||
that they refer to the ordinary GNU General Public License, version 2, |
|||
instead of to this License. (If a newer version than version 2 of the |
|||
ordinary GNU General Public License has appeared, then you can specify |
|||
that version instead if you wish.) Do not make any other change in |
|||
these notices. |
|||
|
|||
Once this change is made in a given copy, it is irreversible for |
|||
that copy, so the ordinary GNU General Public License applies to all |
|||
subsequent copies and derivative works made from that copy. |
|||
|
|||
This option is useful when you wish to copy part of the code of |
|||
the Library into a program that is not a library. |
|||
|
|||
4. You may copy and distribute the Library (or a portion or |
|||
derivative of it, under Section 2) in object code or executable form |
|||
under the terms of Sections 1 and 2 above provided that you accompany |
|||
it with the complete corresponding machine-readable source code, which |
|||
must be distributed under the terms of Sections 1 and 2 above on a |
|||
medium customarily used for software interchange. |
|||
|
|||
If distribution of object code is made by offering access to copy |
|||
from a designated place, then offering equivalent access to copy the |
|||
source code from the same place satisfies the requirement to |
|||
distribute the source code, even though third parties are not |
|||
compelled to copy the source along with the object code. |
|||
|
|||
5. A program that contains no derivative of any portion of the |
|||
Library, but is designed to work with the Library by being compiled or |
|||
linked with it, is called a "work that uses the Library". Such a |
|||
work, in isolation, is not a derivative work of the Library, and |
|||
therefore falls outside the scope of this License. |
|||
|
|||
However, linking a "work that uses the Library" with the Library |
|||
creates an executable that is a derivative of the Library (because it |
|||
contains portions of the Library), rather than a "work that uses the |
|||
library". The executable is therefore covered by this License. |
|||
Section 6 states terms for distribution of such executables. |
|||
|
|||
When a "work that uses the Library" uses material from a header file |
|||
that is part of the Library, the object code for the work may be a |
|||
derivative work of the Library even though the source code is not. |
|||
Whether this is true is especially significant if the work can be |
|||
linked without the Library, or if the work is itself a library. The |
|||
threshold for this to be true is not precisely defined by law. |
|||
|
|||
If such an object file uses only numerical parameters, data |
|||
structure layouts and accessors, and small macros and small inline |
|||
functions (ten lines or less in length), then the use of the object |
|||
file is unrestricted, regardless of whether it is legally a derivative |
|||
work. (Executables containing this object code plus portions of the |
|||
Library will still fall under Section 6.) |
|||
|
|||
Otherwise, if the work is a derivative of the Library, you may |
|||
distribute the object code for the work under the terms of Section 6. |
|||
Any executables containing that work also fall under Section 6, |
|||
whether or not they are linked directly with the Library itself. |
|||
|
|||
6. As an exception to the Sections above, you may also combine or |
|||
link a "work that uses the Library" with the Library to produce a |
|||
work containing portions of the Library, and distribute that work |
|||
under terms of your choice, provided that the terms permit |
|||
modification of the work for the customer's own use and reverse |
|||
engineering for debugging such modifications. |
|||
|
|||
You must give prominent notice with each copy of the work that the |
|||
Library is used in it and that the Library and its use are covered by |
|||
this License. You must supply a copy of this License. If the work |
|||
during execution displays copyright notices, you must include the |
|||
copyright notice for the Library among them, as well as a reference |
|||
directing the user to the copy of this License. Also, you must do one |
|||
of these things: |
|||
|
|||
a) Accompany the work with the complete corresponding |
|||
machine-readable source code for the Library including whatever |
|||
changes were used in the work (which must be distributed under |
|||
Sections 1 and 2 above); and, if the work is an executable linked |
|||
with the Library, with the complete machine-readable "work that |
|||
uses the Library", as object code and/or source code, so that the |
|||
user can modify the Library and then relink to produce a modified |
|||
executable containing the modified Library. (It is understood |
|||
that the user who changes the contents of definitions files in the |
|||
Library will not necessarily be able to recompile the application |
|||
to use the modified definitions.) |
|||
|
|||
b) Use a suitable shared library mechanism for linking with the |
|||
Library. A suitable mechanism is one that (1) uses at run time a |
|||
copy of the library already present on the user's computer system, |
|||
rather than copying library functions into the executable, and (2) |
|||
will operate properly with a modified version of the library, if |
|||
the user installs one, as long as the modified version is |
|||
interface-compatible with the version that the work was made with. |
|||
|
|||
c) Accompany the work with a written offer, valid for at |
|||
least three years, to give the same user the materials |
|||
specified in Subsection 6a, above, for a charge no more |
|||
than the cost of performing this distribution. |
|||
|
|||
d) If distribution of the work is made by offering access to copy |
|||
from a designated place, offer equivalent access to copy the above |
|||
specified materials from the same place. |
|||
|
|||
e) Verify that the user has already received a copy of these |
|||
materials or that you have already sent this user a copy. |
|||
|
|||
For an executable, the required form of the "work that uses the |
|||
Library" must include any data and utility programs needed for |
|||
reproducing the executable from it. However, as a special exception, |
|||
the materials to be distributed need not include anything that is |
|||
normally distributed (in either source or binary form) with the major |
|||
components (compiler, kernel, and so on) of the operating system on |
|||
which the executable runs, unless that component itself accompanies |
|||
the executable. |
|||
|
|||
It may happen that this requirement contradicts the license |
|||
restrictions of other proprietary libraries that do not normally |
|||
accompany the operating system. Such a contradiction means you cannot |
|||
use both them and the Library together in an executable that you |
|||
distribute. |
|||
|
|||
7. You may place library facilities that are a work based on the |
|||
Library side-by-side in a single library together with other library |
|||
facilities not covered by this License, and distribute such a combined |
|||
library, provided that the separate distribution of the work based on |
|||
the Library and of the other library facilities is otherwise |
|||
permitted, and provided that you do these two things: |
|||
|
|||
a) Accompany the combined library with a copy of the same work |
|||
based on the Library, uncombined with any other library |
|||
facilities. This must be distributed under the terms of the |
|||
Sections above. |
|||
|
|||
b) Give prominent notice with the combined library of the fact |
|||
that part of it is a work based on the Library, and explaining |
|||
where to find the accompanying uncombined form of the same work. |
|||
|
|||
8. You may not copy, modify, sublicense, link with, or distribute |
|||
the Library except as expressly provided under this License. Any |
|||
attempt otherwise to copy, modify, sublicense, link with, or |
|||
distribute the Library is void, and will automatically terminate your |
|||
rights under this License. However, parties who have received copies, |
|||
or rights, from you under this License will not have their licenses |
|||
terminated so long as such parties remain in full compliance. |
|||
|
|||
9. You are not required to accept this License, since you have not |
|||
signed it. However, nothing else grants you permission to modify or |
|||
distribute the Library or its derivative works. These actions are |
|||
prohibited by law if you do not accept this License. Therefore, by |
|||
modifying or distributing the Library (or any work based on the |
|||
Library), you indicate your acceptance of this License to do so, and |
|||
all its terms and conditions for copying, distributing or modifying |
|||
the Library or works based on it. |
|||
|
|||
10. Each time you redistribute the Library (or any work based on the |
|||
Library), the recipient automatically receives a license from the |
|||
original licensor to copy, distribute, link with or modify the Library |
|||
subject to these terms and conditions. You may not impose any further |
|||
restrictions on the recipients' exercise of the rights granted herein. |
|||
You are not responsible for enforcing compliance by third parties with |
|||
this License. |
|||
|
|||
11. If, as a consequence of a court judgment or allegation of patent |
|||
infringement or for any other reason (not limited to patent issues), |
|||
conditions are imposed on you (whether by court order, agreement or |
|||
otherwise) that contradict the conditions of this License, they do not |
|||
excuse you from the conditions of this License. If you cannot |
|||
distribute so as to satisfy simultaneously your obligations under this |
|||
License and any other pertinent obligations, then as a consequence you |
|||
may not distribute the Library at all. For example, if a patent |
|||
license would not permit royalty-free redistribution of the Library by |
|||
all those who receive copies directly or indirectly through you, then |
|||
the only way you could satisfy both it and this License would be to |
|||
refrain entirely from distribution of the Library. |
|||
|
|||
If any portion of this section is held invalid or unenforceable under any |
|||
particular circumstance, the balance of the section is intended to apply, |
|||
and the section as a whole is intended to apply in other circumstances. |
|||
|
|||
It is not the purpose of this section to induce you to infringe any |
|||
patents or other property right claims or to contest validity of any |
|||
such claims; this section has the sole purpose of protecting the |
|||
integrity of the free software distribution system which is |
|||
implemented by public license practices. Many people have made |
|||
generous contributions to the wide range of software distributed |
|||
through that system in reliance on consistent application of that |
|||
system; it is up to the author/donor to decide if he or she is willing |
|||
to distribute software through any other system and a licensee cannot |
|||
impose that choice. |
|||
|
|||
This section is intended to make thoroughly clear what is believed to |
|||
be a consequence of the rest of this License. |
|||
|
|||
12. If the distribution and/or use of the Library is restricted in |
|||
certain countries either by patents or by copyrighted interfaces, the |
|||
original copyright holder who places the Library under this License may add |
|||
an explicit geographical distribution limitation excluding those countries, |
|||
so that distribution is permitted only in or among countries not thus |
|||
excluded. In such case, this License incorporates the limitation as if |
|||
written in the body of this License. |
|||
|
|||
13. The Free Software Foundation may publish revised and/or new |
|||
versions of the Lesser General Public License from time to time. |
|||
Such new versions will be similar in spirit to the present version, |
|||
but may differ in detail to address new problems or concerns. |
|||
|
|||
Each version is given a distinguishing version number. If the Library |
|||
specifies a version number of this License which applies to it and |
|||
"any later version", you have the option of following the terms and |
|||
conditions either of that version or of any later version published by |
|||
the Free Software Foundation. If the Library does not specify a |
|||
license version number, you may choose any version ever published by |
|||
the Free Software Foundation. |
|||
|
|||
14. If you wish to incorporate parts of the Library into other free |
|||
programs whose distribution conditions are incompatible with these, |
|||
write to the author to ask for permission. For software which is |
|||
copyrighted by the Free Software Foundation, write to the Free |
|||
Software Foundation; we sometimes make exceptions for this. Our |
|||
decision will be guided by the two goals of preserving the free status |
|||
of all derivatives of our free software and of promoting the sharing |
|||
and reuse of software generally. |
|||
|
|||
NO WARRANTY |
|||
|
|||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO |
|||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. |
|||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR |
|||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY |
|||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE |
|||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
|||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE |
|||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME |
|||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. |
|||
|
|||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN |
|||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY |
|||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU |
|||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR |
|||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE |
|||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING |
|||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A |
|||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF |
|||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH |
|||
DAMAGES. |
|||
|
|||
END OF TERMS AND CONDITIONS |
|||
@ -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 |
|||
@ -0,0 +1 @@ |
|||
af74faa46395cff6167217e471d0e9d8108bc829 |
|||
@ -0,0 +1,9 @@ |
|||
<StyleCopSettings Version="105"> |
|||
<GlobalSettings> |
|||
<CollectionProperty Name="RecognizedWords"> |
|||
<Value>cair</Value> |
|||
<Value>laplacian</Value> |
|||
<Value>sobel</Value> |
|||
</CollectionProperty> |
|||
</GlobalSettings> |
|||
</StyleCopSettings> |
|||
Loading…
Reference in new issue