diff --git a/src/Plugins/ImageProcessor/ImageProcessor.Plugins.Cair/CairBootstrapper.cs b/src/Plugins/ImageProcessor/ImageProcessor.Plugins.Cair/CairBootstrapper.cs index 60a9eb0ce..2baf4fa70 100644 --- a/src/Plugins/ImageProcessor/ImageProcessor.Plugins.Cair/CairBootstrapper.cs +++ b/src/Plugins/ImageProcessor/ImageProcessor.Plugins.Cair/CairBootstrapper.cs @@ -32,12 +32,12 @@ namespace ImageProcessor.Plugins.Cair /// /// Gets the cair path. /// - public static string CairPath { get; private set; } + public static string CairExecutablePath { get; private set; } /// - /// Gets the cair image path. + /// Gets the cair base path. /// - public static string CairImagePath { get; private set; } + public static string CairPath { get; private set; } /// /// Registers the embedded CAIR executable. @@ -47,12 +47,17 @@ namespace ImageProcessor.Plugins.Cair // 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")); + CairPath = Path.GetFullPath(Path.Combine(new Uri(assembly.Location).LocalPath, "..\\" + folder + "\\imageprocessor.cair\\")); + CairExecutablePath = Path.Combine(CairPath, "CAIR.exe"); + string multithreaderTargetPath = Path.Combine(CairPath, "pthreadVSE2.dll"); - // Set the global variable. - CairPath = Path.GetFullPath(Path.Combine(targetBasePath, "..\\" + folder + "\\" + "CAIR.exe")); - CairImagePath = Path.GetFullPath(Path.Combine(targetBasePath, "..\\" + folder + "\\" + "cairimages\\")); + // Create the folder for storing temporary images. + // ReSharper disable once AssignNullToNotNullAttribute + DirectoryInfo directoryInfo = new DirectoryInfo(Path.GetDirectoryName(CairPath)); + if (!directoryInfo.Exists) + { + directoryInfo.Create(); + } // Get the resources and copy them across. const string CairResourcePath = "ImageProcessor.Plugins.Cair.Resources.Unmanaged.x86.CAIR.exe"; @@ -64,13 +69,6 @@ namespace ImageProcessor.Plugins.Cair { 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); @@ -83,27 +81,12 @@ namespace ImageProcessor.Plugins.Cair { 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)) + using (FileStream fileStream = File.OpenWrite(CairExecutablePath)) { 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(); - } } } -} +} \ No newline at end of file diff --git a/src/Plugins/ImageProcessor/ImageProcessor.Plugins.Cair/Imaging/ContentAwareResizeLayer.cs b/src/Plugins/ImageProcessor/ImageProcessor.Plugins.Cair/Imaging/ContentAwareResizeLayer.cs index d81b29907..c7a48a30e 100644 --- a/src/Plugins/ImageProcessor/ImageProcessor.Plugins.Cair/Imaging/ContentAwareResizeLayer.cs +++ b/src/Plugins/ImageProcessor/ImageProcessor.Plugins.Cair/Imaging/ContentAwareResizeLayer.cs @@ -20,7 +20,7 @@ namespace ImageProcessor.Plugins.Cair.Imaging /// /// The convolution type to apply to the layer. /// - private ContentAwareResizeConvolutionType convolutionType = ContentAwareResizeConvolutionType.Prewitt; + private ConvolutionType convolutionType = ConvolutionType.Prewitt; /// /// The energy function to apply to the layer. @@ -28,14 +28,14 @@ namespace ImageProcessor.Plugins.Cair.Imaging private EnergyFunction energyFunction = EnergyFunction.Forward; /// - /// Whether to assign multiple threads to the resizing method. + /// The expected output type. /// - private bool parallelize = true; + private OutputType outputType = OutputType.Cair; /// - /// Whether to pre-scale the image to reduce errors in the output. + /// Whether to assign multiple threads to the resizing method. /// - private bool prescale = true; + private bool parallelize = true; /// /// The timeout in milliseconds to attempt to resize for. @@ -61,7 +61,7 @@ namespace ImageProcessor.Plugins.Cair.Imaging /// /// Gets or sets the content aware resize convolution type (Default ContentAwareResizeConvolutionType.Prewitt). /// - public ContentAwareResizeConvolutionType ConvolutionType + public ConvolutionType ConvolutionType { get { @@ -91,36 +91,35 @@ namespace ImageProcessor.Plugins.Cair.Imaging } /// - /// Gets or sets a value indicating whether to assign multiple threads to the resizing method. - /// (Default true) + /// Gets or sets the expected output type. /// - public bool Parallelize + public OutputType OutputType { get { - return this.parallelize; + return this.outputType; } set { - this.parallelize = value; + this.outputType = value; } } /// - /// Gets or sets a value indicating whether to pre-scale the image to reduce errors in the output. + /// Gets or sets a value indicating whether to assign multiple threads to the resizing method. /// (Default true) /// - public bool PreScale + public bool Parallelize { get { - return this.prescale; + return this.parallelize; } set { - this.prescale = value; + this.parallelize = value; } } @@ -162,7 +161,11 @@ namespace ImageProcessor.Plugins.Cair.Imaging } return this.Size == resizeLayer.Size - && this.ConvolutionType == resizeLayer.ConvolutionType; + && this.ConvolutionType == resizeLayer.ConvolutionType + && this.EnergyFunction == resizeLayer.EnergyFunction + && this.OutputType == resizeLayer.OutputType + && this.Parallelize == resizeLayer.Parallelize + && this.Timeout == resizeLayer.Timeout; } /// @@ -173,7 +176,12 @@ namespace ImageProcessor.Plugins.Cair.Imaging /// public override int GetHashCode() { - return this.Size.GetHashCode() + this.ConvolutionType.GetHashCode(); + return this.Size.GetHashCode() + + this.ConvolutionType.GetHashCode() + + this.EnergyFunction.GetHashCode() + + this.OutputType.GetHashCode() + + this.Parallelize.GetHashCode() + + this.Timeout.GetHashCode(); } } } diff --git a/src/Plugins/ImageProcessor/ImageProcessor.Plugins.Cair/Imaging/ContentAwareResizeConvolutionType.cs b/src/Plugins/ImageProcessor/ImageProcessor.Plugins.Cair/Imaging/ConvolutionType.cs similarity index 89% rename from src/Plugins/ImageProcessor/ImageProcessor.Plugins.Cair/Imaging/ContentAwareResizeConvolutionType.cs rename to src/Plugins/ImageProcessor/ImageProcessor.Plugins.Cair/Imaging/ConvolutionType.cs index 143b0fd3c..b9e0aa26a 100644 --- a/src/Plugins/ImageProcessor/ImageProcessor.Plugins.Cair/Imaging/ContentAwareResizeConvolutionType.cs +++ b/src/Plugins/ImageProcessor/ImageProcessor.Plugins.Cair/Imaging/ConvolutionType.cs @@ -1,5 +1,5 @@ // -------------------------------------------------------------------------------------------------------------------- -// +// // Copyright (c) James South. // Licensed under the Apache License, Version 2.0. // @@ -13,7 +13,7 @@ namespace ImageProcessor.Plugins.Cair.Imaging /// /// Provides enumeration of the content aware resize convolution types. /// - public enum ContentAwareResizeConvolutionType + public enum ConvolutionType { /// /// The Prewitt kernel convolution type. diff --git a/src/Plugins/ImageProcessor/ImageProcessor.Plugins.Cair/Imaging/OutputType.cs b/src/Plugins/ImageProcessor/ImageProcessor.Plugins.Cair/Imaging/OutputType.cs new file mode 100644 index 000000000..168776c6f --- /dev/null +++ b/src/Plugins/ImageProcessor/ImageProcessor.Plugins.Cair/Imaging/OutputType.cs @@ -0,0 +1,53 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// Copyright (c) James South. +// Licensed under the Apache License, Version 2.0. +// +// +// Enumerates the output type to produce. +// +// -------------------------------------------------------------------------------------------------------------------- + +namespace ImageProcessor.Plugins.Cair.Imaging +{ + /// + /// Enumerates the output type to produce. + /// + public enum OutputType + { + /// + /// Output the result as a carved image. The default action. + /// + Cair = 0, + + /// + /// Output the result as a greyscale image. + /// + Grayscale = 1, + + /// + /// Output the result highlighting the detected edges. + /// + Edge = 2, + + /// + /// Output the result highlighting the vertical energy patterns. + /// + VerticalEnergy = 3, + + /// + /// Output the result highlighting the vertical energy patterns. + /// + HorizontalEnergy = 4, + + /// + /// Appears to do nothing. + /// + Removal = 5, + + /// + /// Output the result as a carved image with the focus on high quality output over speed. + /// + CairHighDefinition = 6 + } +} diff --git a/src/Plugins/ImageProcessor/ImageProcessor.Plugins.Cair/Processors/ContentAwareResize.cs b/src/Plugins/ImageProcessor/ImageProcessor.Plugins.Cair/Processors/ContentAwareResize.cs index c85f5b660..533b86fe1 100644 --- a/src/Plugins/ImageProcessor/ImageProcessor.Plugins.Cair/Processors/ContentAwareResize.cs +++ b/src/Plugins/ImageProcessor/ImageProcessor.Plugins.Cair/Processors/ContentAwareResize.cs @@ -69,17 +69,17 @@ namespace ImageProcessor.Plugins.Cair.Processors 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"); + string sourcePath = Path.Combine(CairBootstrapper.CairPath, fileName + ".bmp"); + string resizedPath = Path.Combine(CairBootstrapper.CairPath, 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; + ContentAwareResizeLayer layer = (ContentAwareResizeLayer)this.DynamicParameter; + int width = layer.Size.Width; + int height = layer.Size.Height; + ConvolutionType convolutionType = layer.ConvolutionType; + EnergyFunction energyFunction = layer.EnergyFunction; + bool parallelize = layer.Parallelize; + int timeout = layer.Timeout > 0 ? layer.Timeout : 60000; int defaultMaxWidth; int defaultMaxHeight; @@ -115,26 +115,6 @@ namespace ImageProcessor.Plugins.Cair.Processors 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 resizeSettings = new Dictionary - { - { - "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); @@ -208,7 +188,7 @@ namespace ImageProcessor.Plugins.Cair.Processors 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) + ProcessStartInfo start = new ProcessStartInfo(CairBootstrapper.CairExecutablePath, arguments) { WindowStyle = ProcessWindowStyle.Hidden, UseShellExecute = false,