diff --git a/src/Orchard.Web/Modules/Orchard.MediaProcessing/Orchard.MediaProcessing.csproj b/src/Orchard.Web/Modules/Orchard.MediaProcessing/Orchard.MediaProcessing.csproj
index eba93aabd..c70eb9caa 100644
--- a/src/Orchard.Web/Modules/Orchard.MediaProcessing/Orchard.MediaProcessing.csproj
+++ b/src/Orchard.Web/Modules/Orchard.MediaProcessing/Orchard.MediaProcessing.csproj
@@ -112,9 +112,7 @@
-
-
-
+
diff --git a/src/Orchard.Web/Modules/Orchard.MediaProcessing/Providers/Filters/ConstrainFilter.cs b/src/Orchard.Web/Modules/Orchard.MediaProcessing/Providers/Filters/ConstrainFilter.cs
deleted file mode 100644
index 5a8d5b6ac..000000000
--- a/src/Orchard.Web/Modules/Orchard.MediaProcessing/Providers/Filters/ConstrainFilter.cs
+++ /dev/null
@@ -1,97 +0,0 @@
-using System;
-using System.Web.Mvc;
-using ImageResizer;
-using Orchard.DisplayManagement;
-using Orchard.Forms.Services;
-using Orchard.Localization;
-using Orchard.MediaProcessing.Descriptors.Filter;
-using Orchard.MediaProcessing.Services;
-
-namespace Orchard.MediaProcessing.Providers.Filters {
- public class ConstrainFilter : IImageFilterProvider {
- public ConstrainFilter() {
- T = NullLocalizer.Instance;
- }
-
- public Localizer T { get; set; }
-
- public void Describe(DescribeFilterContext describe) {
- describe.For("Transform", T("Transform"), T("Transform"))
- .Element("Constrain", T("Constrain"), T("Constrains the dimensions of an image either by with of by height"),
- ApplyFilter,
- DisplayFilter,
- "ContrainImageFilter"
- );
- }
-
- public void ApplyFilter(FilterContext context) {
- var value = (int)context.State.Value;
- var axis = (string)context.State.Axis;
-
-
-
- var settings = new ResizeSettings {
- Mode = FitMode.Max
- };
-
- switch (axis) {
- case "width":
- settings.Width = value;
- break;
- case "height":
- settings.Height = value;
- break;
- }
-
-
- context.Media = result;
- }
-
- public LocalizedString DisplayFilter(FilterContext context) {
- var value = (int)context.State.Value;
- var axis = (string)context.State.Axis;
-
- return axis == "height"
- ? T("Constrain to {0}px high", value)
- : T("Constrain to {0}px wide", value);
- }
- }
-
- public class ConstrainFilterFilterForms : IFormProvider {
- protected dynamic Shape { get; set; }
- public Localizer T { get; set; }
-
- public ConstrainFilterFilterForms(
- IShapeFactory shapeFactory) {
- Shape = shapeFactory;
- T = NullLocalizer.Instance;
- }
-
- public void Describe(DescribeContext context) {
- Func form =
- shape => {
- var f = Shape.Form(
- Id: "ContrainImageFilter",
- _Axis: Shape.SelectList(
- Id: "axis", Name: "Axis",
- Title: T("Axis"),
- Size: 1,
- Multiple: false
- ),
- _Height: Shape.Textbox(
- Id: "value", Name: "Value",
- Title: T("Value"),
- Description: T("The value in pixel the selected axis should be constrained to. Mandatory."),
- Classes: new[] {"text-small"})
- );
-
- f._Axis.Add(new SelectListItem { Value = "height", Text = T("Height").Text });
- f._Axis.Add(new SelectListItem { Value = "width", Text = T("Width").Text });
-
- return f;
- };
-
- context.Form("ContrainImageFilter", form);
- }
- }
-}
\ No newline at end of file
diff --git a/src/Orchard.Web/Modules/Orchard.MediaProcessing/Providers/Filters/CropFilter.cs b/src/Orchard.Web/Modules/Orchard.MediaProcessing/Providers/Filters/CropFilter.cs
deleted file mode 100644
index c0fbb6c3d..000000000
--- a/src/Orchard.Web/Modules/Orchard.MediaProcessing/Providers/Filters/CropFilter.cs
+++ /dev/null
@@ -1,89 +0,0 @@
-using System;
-using System.Drawing;
-using Orchard.DisplayManagement;
-using Orchard.Forms.Services;
-using Orchard.Localization;
-using Orchard.MediaProcessing.Descriptors.Filter;
-using Orchard.MediaProcessing.Services;
-
-namespace Orchard.MediaProcessing.Providers.Filters {
- public class CropFilter : IImageFilterProvider {
- public CropFilter() {
- T = NullLocalizer.Instance;
- }
-
- public Localizer T { get; set; }
-
- public void Describe(DescribeFilterContext describe) {
- describe.For("Transform", T("Transform"), T("Transform"))
- .Element("Crop", T("Crop"), T("Crops to a fixed height and width"),
- ApplyFilter,
- DisplayFilter,
- "CropFilter"
- );
- }
-
- public void ApplyFilter(FilterContext context) {
- var newHeight = int.Parse(context.State.Height);
- newHeight = newHeight > 0 ? newHeight : context.Media.Height;
- var heightFactor = (float) context.Media.Height/newHeight;
-
- var newWidth = int.Parse(context.State.Width);
- newWidth = newWidth > 0 ? newWidth : context.Media.Width;
- var widthFactor = context.Media.Width/newWidth;
-
- if (widthFactor != heightFactor) {
- if (widthFactor > heightFactor) {
- newHeight = Convert.ToInt32(context.Media.Height/widthFactor);
- }
- else {
- newWidth = Convert.ToInt32(context.Media.Width/heightFactor);
- }
- }
-
- var newImage = new Bitmap(newWidth, newHeight);
- using (var graphics = Graphics.FromImage(newImage)) {
- graphics.DrawImage(context.Media, 0, 0, new Rectangle(0, 0, newWidth, newHeight), GraphicsUnit.Pixel);
- }
-
- context.Media = newImage;
- }
-
- public LocalizedString DisplayFilter(FilterContext context) {
- return T("Crop to {0}px high x {1}px wide", context.State.Height, context.State.Width);
- }
- }
-
- public class CropFilterForms : IFormProvider {
- protected dynamic Shape { get; set; }
- public Localizer T { get; set; }
-
- public CropFilterForms(
- IShapeFactory shapeFactory) {
- Shape = shapeFactory;
- T = NullLocalizer.Instance;
- }
-
- public void Describe(DescribeContext context) {
- Func form =
- shape => {
- var f = Shape.Form(
- Id: "ImageCropFilter",
- _Height: Shape.Textbox(
- Id: "height", Name: "Height",
- Title: T("Height"),
- Description: T("The height in pixels, 0 to allow any value."),
- Classes: new[] {"text-small"}),
- _Width: Shape.Textbox(
- Id: "width", Name: "Width",
- Title: T("Width"),
- Description: T("The width in pixels, 0 to allow any value."),
- Classes: new[] {"text-small"}));
-
- return f;
- };
-
- context.Form("CropFilter", form);
- }
- }
-}
\ No newline at end of file
diff --git a/src/Orchard.Web/Modules/Orchard.MediaProcessing/Providers/Filters/FormatFilter.cs b/src/Orchard.Web/Modules/Orchard.MediaProcessing/Providers/Filters/FormatFilter.cs
new file mode 100644
index 000000000..46fa9412e
--- /dev/null
+++ b/src/Orchard.Web/Modules/Orchard.MediaProcessing/Providers/Filters/FormatFilter.cs
@@ -0,0 +1,92 @@
+using System;
+using System.IO;
+using System.Web.Mvc;
+using ImageResizer;
+using Orchard.DisplayManagement;
+using Orchard.Forms.Services;
+using Orchard.Localization;
+using Orchard.MediaProcessing.Descriptors.Filter;
+using Orchard.MediaProcessing.Services;
+
+namespace Orchard.MediaProcessing.Providers.Filters {
+ public class FormatFilter : IImageFilterProvider {
+ public FormatFilter() {
+ T = NullLocalizer.Instance;
+ }
+
+ public Localizer T { get; set; }
+
+ public void Describe(DescribeFilterContext describe) {
+ describe.For("Transform", T("Transform"), T("Transform"))
+ .Element("Format", T("Format"), T("Change the format of the image."),
+ ApplyFilter,
+ DisplayFilter,
+ "FormatFilter"
+ );
+ }
+
+ public void ApplyFilter(FilterContext context) {
+ string format = context.State.Format;
+ int quality = context.State.Quality;
+
+ var settings = new ResizeSettings {
+ Quality = quality,
+ Format = format
+ };
+
+ var result = new MemoryStream();
+ if (context.Media.CanSeek) {
+ context.Media.Seek(0, SeekOrigin.Begin);
+ }
+
+ ImageBuilder.Current.Build(context.Media, result, settings);
+
+ context.FilePath = Path.ChangeExtension(context.FilePath, format);
+ context.Media = result;
+ }
+
+ public LocalizedString DisplayFilter(FilterContext context) {
+ return T("Format the image to {0}", (string)context.State.Format);
+ }
+ }
+
+ public class FormatFilterForms : IFormProvider {
+ protected dynamic Shape { get; set; }
+ public Localizer T { get; set; }
+
+ public FormatFilterForms(
+ IShapeFactory shapeFactory) {
+ Shape = shapeFactory;
+ T = NullLocalizer.Instance;
+ }
+
+ public void Describe(DescribeContext context) {
+ Func form =
+ shape => {
+ var f = Shape.Form(
+ Id: "FormatFilter",
+ _Format: Shape.SelectList(
+ Id: "format", Name: "Format",
+ Title: T("Format"),
+ Description: T("The target format of the image."),
+ Size: 1,
+ Multiple: false),
+ _Quality: Shape.Textbox(
+ Id: "quality", Name: "Quality",
+ Title: T("Quality"),
+ Value: 90,
+ Description: T("JPeg compression quality, from 0 to 100."),
+ Classes: new[] { "text-small" })
+ );
+
+ f._Format.Add(new SelectListItem { Value = "jpg", Text = T("Jpeg").Text });
+ f._Format.Add(new SelectListItem { Value = "gif", Text = T("Gif").Text });
+ f._Format.Add(new SelectListItem { Value = "png", Text = T("Png").Text });
+
+ return f;
+ };
+
+ context.Form("FormatFilter", form);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Orchard.Web/Modules/Orchard.MediaProcessing/Providers/Filters/ImageFormatFilter.cs b/src/Orchard.Web/Modules/Orchard.MediaProcessing/Providers/Filters/ImageFormatFilter.cs
deleted file mode 100644
index f52b5795d..000000000
--- a/src/Orchard.Web/Modules/Orchard.MediaProcessing/Providers/Filters/ImageFormatFilter.cs
+++ /dev/null
@@ -1,92 +0,0 @@
-using System;
-using System.Drawing.Imaging;
-using System.IO;
-using System.Web.Mvc;
-using Orchard.DisplayManagement;
-using Orchard.Forms.Services;
-using Orchard.Localization;
-using Orchard.MediaProcessing.Descriptors.Filter;
-using Orchard.MediaProcessing.Services;
-
-namespace Orchard.MediaProcessing.Providers.Filters {
- public class ImageFormatFilter : IImageFilterProvider {
- public ImageFormatFilter() {
- T = NullLocalizer.Instance;
- }
-
- public Localizer T { get; set; }
-
- public void Describe(DescribeFilterContext describe) {
- describe.For("Transform", T("Transform"), T("Transform"))
- .Element("ImageFormat", T("ImageFormat"), T("Changes the image file format"),
- ApplyFilter,
- DisplayFilter,
- "ImageFormatFilter"
- );
- }
-
- public void ApplyFilter(FilterContext context) {
- context.Format = ImageFormatConverter.ToImageFormat((ImageFormats)Enum.Parse(typeof (ImageFormats), (string)context.State.ImageFormat));
- context.FilePath = Path.ChangeExtension(context.FilePath, context.Format.ToString().ToLower());
- }
-
- public LocalizedString DisplayFilter(FilterContext context) {
- return T("Convert to {0}", context.State.ImageFormat.ToString());
- }
- }
-
- public class ImageFormatFilterForms : IFormProvider {
- protected dynamic Shape { get; set; }
- public Localizer T { get; set; }
-
- public ImageFormatFilterForms(
- IShapeFactory shapeFactory) {
- Shape = shapeFactory;
- T = NullLocalizer.Instance;
- }
-
- public void Describe(DescribeContext context) {
- Func form =
- shape => {
- var f = Shape.Form(
- Id: "ImageFormatFilter",
- _ImageFormat: Shape.SelectList(
- Id: "imageformat",
- Name: "ImageFormat"
- ));
-
- foreach (var item in Enum.GetValues(typeof (ImageFormats))) {
- var name = Enum.GetName(typeof (ImageFormats), item);
- f._ImageFormat.Add(new SelectListItem {Value = item.ToString(), Text = name});
- }
-
- return f;
- };
-
- context.Form("ImageFormatFilter", form);
- }
- }
-
- public enum ImageFormats {
- Bmp,
- Gif,
- Jpeg,
- Png
- }
-
- public class ImageFormatConverter {
- public static ImageFormat ToImageFormat(ImageFormats format) {
- switch (format) {
- case ImageFormats.Bmp:
- return ImageFormat.Bmp;
- case ImageFormats.Gif:
- return ImageFormat.Gif;
- case ImageFormats.Jpeg:
- return ImageFormat.Jpeg;
- case ImageFormats.Png:
- return ImageFormat.Png;
- }
- return ImageFormat.Jpeg;
- }
- }
-}
\ No newline at end of file
diff --git a/src/Orchard.Web/Modules/Orchard.MediaProcessing/Providers/Filters/ResizeFilter.cs b/src/Orchard.Web/Modules/Orchard.MediaProcessing/Providers/Filters/ResizeFilter.cs
index 29e7cfd56..a097ea98b 100644
--- a/src/Orchard.Web/Modules/Orchard.MediaProcessing/Providers/Filters/ResizeFilter.cs
+++ b/src/Orchard.Web/Modules/Orchard.MediaProcessing/Providers/Filters/ResizeFilter.cs
@@ -1,7 +1,7 @@
using System;
using System.Drawing;
-using System.Drawing.Drawing2D;
using System.IO;
+using System.Web.Mvc;
using ImageResizer;
using Orchard.DisplayManagement;
using Orchard.Forms.Services;
@@ -29,6 +29,9 @@ namespace Orchard.MediaProcessing.Providers.Filters {
public void ApplyFilter(FilterContext context) {
int witdh = context.State.Width;
int height = context.State.Height;
+ string mode = context.State.Mode;
+ string alignment = context.State.Alignment;
+ string padcolor = context.State.PadColor;
var settings = new ResizeSettings {
Mode = FitMode.Max,
@@ -36,13 +39,45 @@ namespace Orchard.MediaProcessing.Providers.Filters {
Width = witdh
};
+ switch (mode) {
+ case "max": settings.Mode = FitMode.Max; break;
+ case "pad": settings.Mode = FitMode.Pad; break;
+ case "crop": settings.Mode = FitMode.Crop; break;
+ case "stretch": settings.Mode = FitMode.Stretch; break;
+ }
+
+ switch (alignment) {
+ case "topleft": settings.Anchor = ContentAlignment.TopLeft; break;
+ case "topcenter": settings.Anchor = ContentAlignment.TopCenter; break;
+ case "topright": settings.Anchor = ContentAlignment.TopRight; break;
+ case "middleleft": settings.Anchor = ContentAlignment.MiddleLeft; break;
+ case "middlecenter": settings.Anchor = ContentAlignment.MiddleCenter; break;
+ case "middleright": settings.Anchor = ContentAlignment.MiddleRight; break;
+ case "bottomleft": settings.Anchor = ContentAlignment.BottomLeft; break;
+ case "bottomcenter": settings.Anchor = ContentAlignment.BottomCenter; break;
+ case "bottomright": settings.Anchor = ContentAlignment.BottomRight; break;
+ }
+
+ if (!String.IsNullOrWhiteSpace(padcolor)) {
+ if (padcolor.StartsWith("#")) {
+ ColorTranslator.FromHtml(padcolor);
+ }
+ else {
+ settings.PaddingColor = Color.FromName(padcolor);
+ }
+
+ }
+
var result = new MemoryStream();
+ if (context.Media.CanSeek) {
+ context.Media.Seek(0, SeekOrigin.Begin);
+ }
ImageBuilder.Current.Build(context.Media, result, settings);
context.Media = result;
}
public LocalizedString DisplayFilter(FilterContext context) {
- return T("Resize to {0}px high x {1}px wide", context.State.Height, context.State.Width);
+ return T((string)context.State.Mode + " to {0}px high x {1}px wide", context.State.Height, context.State.Width);
}
}
@@ -64,14 +99,50 @@ namespace Orchard.MediaProcessing.Providers.Filters {
_Width: Shape.Textbox(
Id: "width", Name: "Width",
Title: T("Width"),
- Description: T("The width in pixels, 0 to allow any value."),
+ Value: 0,
+ Description: T("The width in pixels."),
Classes: new[] {"text-small"}),
_Height: Shape.Textbox(
Id: "height", Name: "Height",
Title: T("Height"),
- Description: T("The height in pixels, 0 to allow any value."),
+ Value: 0,
+ Description: T("The height in pixels."),
+ Classes: new[] {"text-small"}),
+ _Mode: Shape.SelectList(
+ Id: "mode", Name: "Mode",
+ Title: T("Mode"),
+ Description: T("How the image should be resized.
Max: adjusts to the max given width or left, keeping image ratio.
Pad: adds a padding so that the target image is exactly of width and height.
Crop: removes part of the image to fit with given height and width.
Stretch: stretches the image to fit within height and width."),
+ Size: 1,
+ Multiple: false),
+ _Alignment: Shape.SelectList(
+ Id: "alignment", Name: "Alignment",
+ Title: T("Alignment"),
+ Description: T("Select the alignment for Crop and Pad modes."),
+ Size: 1,
+ Multiple: false),
+ _PadColor: Shape.Textbox(
+ Id: "padcolor", Name: "PadColor",
+ Title: T("Pad Color"),
+ Value: "#ffffff",
+ Description: T("The background color to use to pad the image. Named color or hex value."),
Classes: new[] {"text-small"})
- );
+ );
+
+ f._Mode.Add(new SelectListItem { Value = "max", Text = T("Max").Text });
+ f._Mode.Add(new SelectListItem { Value = "pad", Text = T("Pad").Text });
+ f._Mode.Add(new SelectListItem { Value = "crop", Text = T("Crop").Text });
+ f._Mode.Add(new SelectListItem { Value = "stretch", Text = T("Stretch").Text });
+
+ f._Alignment.Add(new SelectListItem { Value = "topleft", Text = T("Top Left").Text });
+ f._Alignment.Add(new SelectListItem { Value = "topcenter", Text = T("Top Center").Text });
+ f._Alignment.Add(new SelectListItem { Value = "topright", Text = T("Top Right").Text });
+ f._Alignment.Add(new SelectListItem { Value = "middleleft", Text = T("Middle Left").Text });
+ f._Alignment.Add(new SelectListItem { Value = "middlecenter", Text = T("Middle Center").Text });
+ f._Alignment.Add(new SelectListItem { Value = "middleright", Text = T("Middle Right").Text });
+ f._Alignment.Add(new SelectListItem { Value = "bottomleft", Text = T("Bottom Left").Text });
+ f._Alignment.Add(new SelectListItem { Value = "bottomcenter", Text = T("Bottom Center").Text });
+ f._Alignment.Add(new SelectListItem { Value = "bottomright", Text = T("Bottom Right").Text });
+
return f;
};
diff --git a/src/Orchard.Web/Modules/Orchard.MediaProcessing/Services/ImageProcessingFileNameProvider.cs b/src/Orchard.Web/Modules/Orchard.MediaProcessing/Services/ImageProcessingFileNameProvider.cs
index 1895eaee2..39c32c7a9 100644
--- a/src/Orchard.Web/Modules/Orchard.MediaProcessing/Services/ImageProcessingFileNameProvider.cs
+++ b/src/Orchard.Web/Modules/Orchard.MediaProcessing/Services/ImageProcessingFileNameProvider.cs
@@ -1,8 +1,6 @@
using System.Collections.Generic;
-using System.IO;
using System.Linq;
using Orchard.Caching;
-using Orchard.Data;
using Orchard.MediaProcessing.Models;
namespace Orchard.MediaProcessing.Services {
diff --git a/src/Orchard.Web/Modules/Orchard.MediaProcessing/Shapes/MediaShapes.cs b/src/Orchard.Web/Modules/Orchard.MediaProcessing/Shapes/MediaShapes.cs
index a2d17fb07..b4de7c50d 100644
--- a/src/Orchard.Web/Modules/Orchard.MediaProcessing/Shapes/MediaShapes.cs
+++ b/src/Orchard.Web/Modules/Orchard.MediaProcessing/Shapes/MediaShapes.cs
@@ -35,7 +35,8 @@ namespace Orchard.MediaProcessing.Shapes {
[Shape]
public void ImageUrl(dynamic Display, TextWriter Output, string Profile, string Path) {
var filePath = _fileNameProvider.Value.GetFileName(Profile, Path);
- if (string.IsNullOrEmpty(filePath) || _storageProvider.Value.GetFile(filePath) == null) {
+ // todo: regenerate the file if the profile is newer, by getting IStorageFile.
+ if (string.IsNullOrEmpty(filePath) || !_storageProvider.Value.FileExists(filePath)) {
try {
var profilePart = _profileService.Value.GetImageProfileByName(Profile);
if (profilePart == null)
@@ -58,10 +59,12 @@ namespace Orchard.MediaProcessing.Shapes {
var newFile = _storageProvider.Value.OpenOrCreate(filterContext.FilePath);
using (var imageStream = newFile.OpenWrite()) {
using (var sw = new BinaryWriter(imageStream)) {
- filterContext.Media.Seek(0, SeekOrigin.Begin);
+ if (filterContext.Media.CanSeek) {
+ filterContext.Media.Seek(0, SeekOrigin.Begin);
+ }
using (var sr = new BinaryReader(filterContext.Media)) {
int count;
- var buffer = new byte[1024];
+ var buffer = new byte[8192];
while ((count = sr.Read(buffer, 0, buffer.Length)) != 0) {
sw.Write(buffer, 0, count);
}
diff --git a/src/Orchard/FileSystems/Media/FileSystemStorageProvider.cs b/src/Orchard/FileSystems/Media/FileSystemStorageProvider.cs
index 2bba24dce..9364e734c 100644
--- a/src/Orchard/FileSystems/Media/FileSystemStorageProvider.cs
+++ b/src/Orchard/FileSystems/Media/FileSystemStorageProvider.cs
@@ -70,7 +70,7 @@ namespace Orchard.FileSystems.Media {
/// The relative path within the storage provider.
/// True if the file exists; False otherwise.
public bool FileExists(string path) {
- return new FileInfo(MapStorage(path)).Exists;
+ return File.Exists(MapStorage(path));
}
///