diff --git a/src/Umbraco.Core/Models/ImageUrlGenerationOptions.cs b/src/Umbraco.Core/Models/ImageUrlGenerationOptions.cs index 9e8d3f3a00..f87657c33d 100644 --- a/src/Umbraco.Core/Models/ImageUrlGenerationOptions.cs +++ b/src/Umbraco.Core/Models/ImageUrlGenerationOptions.cs @@ -1,8 +1,17 @@ namespace Umbraco.Core.Models { + /// + /// These are options that are passed to the IImageUrlGenerator implementation to determine + /// the propery URL that is needed + /// public class ImageUrlGenerationOptions { - public string ImageUrl { get; set; } + public ImageUrlGenerationOptions (string imageUrl) + { + ImageUrl = imageUrl; + } + + public string ImageUrl { get; } public int? Width { get; set; } public int? Height { get; set; } public decimal? WidthRatio { get; set; } @@ -18,18 +27,40 @@ public bool UpScale { get; set; } = true; public string AnimationProcessMode { get; set; } + /// + /// The focal point position, in whatever units the registered IImageUrlGenerator uses, + /// typically a percentage of the total image from 0.0 to 1.0. + /// public class FocalPointPosition { - public decimal Left { get; set; } - public decimal Top { get; set; } + public FocalPointPosition (decimal top, decimal left) + { + Left = left; + Top = top; + } + + public decimal Left { get; } + public decimal Top { get; } } + /// + /// The bounds of the crop within the original image, in whatever units the registered + /// IImageUrlGenerator uses, typically a percentage between 0 and 100. + /// public class CropCoordinates { - public decimal X1 { get; set; } - public decimal Y1 { get; set; } - public decimal X2 { get; set; } - public decimal Y2 { get; set; } + public CropCoordinates (decimal x1, decimal y1, decimal x2, decimal y2) + { + X1 = x1; + Y1 = y1; + X2 = x2; + Y2 = y2; + } + + public decimal X1 { get; } + public decimal Y1 { get; } + public decimal X2 { get; } + public decimal Y2 { get; } } } } diff --git a/src/Umbraco.Core/Models/UserExtensions.cs b/src/Umbraco.Core/Models/UserExtensions.cs index f11a8efe46..5be66bac47 100644 --- a/src/Umbraco.Core/Models/UserExtensions.cs +++ b/src/Umbraco.Core/Models/UserExtensions.cs @@ -109,11 +109,11 @@ namespace Umbraco.Core.Models var urlGenerator = Current.ImageUrlGenerator; return new[] { - urlGenerator.GetImageUrl(new ImageUrlGenerationOptions { ImageUrl = avatarUrl, ImageCropMode = "crop", Width = 30, Height = 30 }), - urlGenerator.GetImageUrl(new ImageUrlGenerationOptions { ImageUrl = avatarUrl, ImageCropMode = "crop", Width = 60, Height = 60 }), - urlGenerator.GetImageUrl(new ImageUrlGenerationOptions { ImageUrl = avatarUrl, ImageCropMode = "crop", Width = 90, Height = 90 }), - urlGenerator.GetImageUrl(new ImageUrlGenerationOptions { ImageUrl = avatarUrl, ImageCropMode = "crop", Width = 150, Height = 150 }), - urlGenerator.GetImageUrl(new ImageUrlGenerationOptions { ImageUrl = avatarUrl, ImageCropMode = "crop", Width = 300, Height = 300 }) + urlGenerator.GetImageUrl(new ImageUrlGenerationOptions(avatarUrl) { ImageCropMode = "crop", Width = 30, Height = 30 }), + urlGenerator.GetImageUrl(new ImageUrlGenerationOptions(avatarUrl) { ImageCropMode = "crop", Width = 60, Height = 60 }), + urlGenerator.GetImageUrl(new ImageUrlGenerationOptions(avatarUrl) { ImageCropMode = "crop", Width = 90, Height = 90 }), + urlGenerator.GetImageUrl(new ImageUrlGenerationOptions(avatarUrl) { ImageCropMode = "crop", Width = 150, Height = 150 }), + urlGenerator.GetImageUrl(new ImageUrlGenerationOptions(avatarUrl) { ImageCropMode = "crop", Width = 300, Height = 300 }) }; } diff --git a/src/Umbraco.Core/PropertyEditors/ValueConverters/ImageCropperValue.cs b/src/Umbraco.Core/PropertyEditors/ValueConverters/ImageCropperValue.cs index 70eb7e0477..ab217d3870 100644 --- a/src/Umbraco.Core/PropertyEditors/ValueConverters/ImageCropperValue.cs +++ b/src/Umbraco.Core/PropertyEditors/ValueConverters/ImageCropperValue.cs @@ -67,15 +67,15 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters || crop != null && crop.Coordinates == null && HasFocalPoint() || defaultCrop && HasFocalPoint()) { - return new ImageUrlGenerationOptions { ImageUrl = url, FocalPoint = new ImageUrlGenerationOptions.FocalPointPosition { Left = FocalPoint.Left, Top = FocalPoint.Top } }; + return new ImageUrlGenerationOptions(url) { FocalPoint = new ImageUrlGenerationOptions.FocalPointPosition(FocalPoint.Top, FocalPoint.Left) }; } else if (crop != null && crop.Coordinates != null && preferFocalPoint == false) { - return new ImageUrlGenerationOptions { ImageUrl = url, Crop = new ImageUrlGenerationOptions.CropCoordinates { X1 = crop.Coordinates.X1, X2 = crop.Coordinates.X2, Y1 = crop.Coordinates.Y1, Y2 = crop.Coordinates.Y2 } }; + return new ImageUrlGenerationOptions(url) { Crop = new ImageUrlGenerationOptions.CropCoordinates(crop.Coordinates.X1, crop.Coordinates.Y1, crop.Coordinates.X2, crop.Coordinates.Y2) }; } else { - return new ImageUrlGenerationOptions { ImageUrl = url, DefaultCrop = true }; + return new ImageUrlGenerationOptions(url) { DefaultCrop = true }; } } diff --git a/src/Umbraco.Tests/Models/ImageProcessorImageUrlGeneratorTest.cs b/src/Umbraco.Tests/Models/ImageProcessorImageUrlGeneratorTest.cs index ffbb0db946..30ead90de9 100644 --- a/src/Umbraco.Tests/Models/ImageProcessorImageUrlGeneratorTest.cs +++ b/src/Umbraco.Tests/Models/ImageProcessorImageUrlGeneratorTest.cs @@ -27,36 +27,36 @@ namespace Umbraco.Tests.Models public class ImageProcessorImageUrlGeneratorTest { private const string MediaPath = "/media/1005/img_0671.jpg"; - private static readonly ImageUrlGenerationOptions.CropCoordinates Crop = new ImageUrlGenerationOptions.CropCoordinates { X1 = 0.58729977382575338m, Y1 = 0.055768992440203169m, X2 = 0m, Y2 = 0.32457553600198386m }; - private static readonly ImageUrlGenerationOptions.FocalPointPosition Focus1 = new ImageUrlGenerationOptions.FocalPointPosition { Top = 0.80827067669172936m, Left = 0.96m }; - private static readonly ImageUrlGenerationOptions.FocalPointPosition Focus2 = new ImageUrlGenerationOptions.FocalPointPosition { Top = 0.41m, Left = 0.4275m }; + private static readonly ImageUrlGenerationOptions.CropCoordinates Crop = new ImageUrlGenerationOptions.CropCoordinates(0.58729977382575338m, 0.055768992440203169m, 0m, 0.32457553600198386m); + private static readonly ImageUrlGenerationOptions.FocalPointPosition Focus1 = new ImageUrlGenerationOptions.FocalPointPosition(0.80827067669172936m, 0.96m); + private static readonly ImageUrlGenerationOptions.FocalPointPosition Focus2 = new ImageUrlGenerationOptions.FocalPointPosition(0.41m, 0.4275m); private static readonly ImageProcessorImageUrlGenerator Generator = new ImageProcessorImageUrlGenerator(); [Test] public void GetCropUrl_CropAliasTest() { - var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions { ImageUrl = MediaPath, Crop = Crop, Width = 100, Height = 100 }); + var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions(MediaPath) { Crop = Crop, Width = 100, Height = 100 }); Assert.AreEqual(MediaPath + "?crop=0.58729977382575338,0.055768992440203169,0,0.32457553600198386&cropmode=percentage&width=100&height=100", urlString); } [Test] public void GetCropUrl_WidthHeightTest() { - var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions { ImageUrl = MediaPath, FocalPoint = Focus1, Width = 200, Height = 300 }); + var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions(MediaPath) { FocalPoint = Focus1, Width = 200, Height = 300 }); Assert.AreEqual(MediaPath + "?center=0.80827067669172936,0.96&mode=crop&width=200&height=300", urlString); } [Test] public void GetCropUrl_FocalPointTest() { - var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions { ImageUrl = MediaPath, FocalPoint = Focus1, Width = 100, Height = 100 }); + var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions(MediaPath) { FocalPoint = Focus1, Width = 100, Height = 100 }); Assert.AreEqual(MediaPath + "?center=0.80827067669172936,0.96&mode=crop&width=100&height=100", urlString); } [Test] public void GetCropUrlFurtherOptionsTest() { - var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions { ImageUrl = MediaPath, FocalPoint = Focus1, Width = 200, Height = 300, FurtherOptions = "&filter=comic&roundedcorners=radius-26|bgcolor-fff" }); + var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions(MediaPath) { FocalPoint = Focus1, Width = 200, Height = 300, FurtherOptions = "&filter=comic&roundedcorners=radius-26|bgcolor-fff" }); Assert.AreEqual(MediaPath + "?center=0.80827067669172936,0.96&mode=crop&width=200&height=300&filter=comic&roundedcorners=radius-26|bgcolor-fff", urlString); } @@ -76,7 +76,7 @@ namespace Umbraco.Tests.Models [Test] public void GetCropUrlEmptyTest() { - var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions()); + var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions(null)); Assert.AreEqual("?mode=crop", urlString); } @@ -86,7 +86,7 @@ namespace Umbraco.Tests.Models [Test] public void GetBaseCropUrlFromModelTest() { - var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions { Crop = Crop, Width = 100, Height = 100 }); + var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions(null) { Crop = Crop, Width = 100, Height = 100 }); Assert.AreEqual("?crop=0.58729977382575338,0.055768992440203169,0,0.32457553600198386&cropmode=percentage&width=100&height=100", urlString); } @@ -96,7 +96,7 @@ namespace Umbraco.Tests.Models [Test] public void GetCropUrl_CropAliasHeightRatioModeTest() { - var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions { ImageUrl = MediaPath, Crop = Crop, Width = 100, HeightRatio = 1 }); + var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions(MediaPath) { Crop = Crop, Width = 100, HeightRatio = 1 }); Assert.AreEqual(MediaPath + "?crop=0.58729977382575338,0.055768992440203169,0,0.32457553600198386&cropmode=percentage&heightratio=1&width=100", urlString); } @@ -106,7 +106,7 @@ namespace Umbraco.Tests.Models [Test] public void GetCropUrl_WidthHeightRatioModeTest() { - var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions { ImageUrl = MediaPath, FocalPoint = Focus1, Width = 300, HeightRatio = 0.5m }); + var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions(MediaPath) { FocalPoint = Focus1, Width = 300, HeightRatio = 0.5m }); Assert.AreEqual(MediaPath + "?center=0.80827067669172936,0.96&mode=crop&heightratio=0.5&width=300", urlString); } @@ -116,7 +116,7 @@ namespace Umbraco.Tests.Models [Test] public void GetCropUrl_HeightWidthRatioModeTest() { - var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions { ImageUrl = MediaPath, FocalPoint = Focus1, Height = 150, WidthRatio = 2 }); + var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions(MediaPath) { FocalPoint = Focus1, Height = 150, WidthRatio = 2 }); Assert.AreEqual(MediaPath + "?center=0.80827067669172936,0.96&mode=crop&widthratio=2&height=150", urlString); } @@ -126,11 +126,11 @@ namespace Umbraco.Tests.Models [Test] public void GetCropUrl_SpecifiedCropModeTest() { - var urlStringMin = Generator.GetImageUrl(new ImageUrlGenerationOptions { ImageUrl = MediaPath, ImageCropMode = "Min", Width = 300, Height = 150 }); - var urlStringBoxPad = Generator.GetImageUrl(new ImageUrlGenerationOptions { ImageUrl = MediaPath, ImageCropMode = "BoxPad", Width = 300, Height = 150 }); - var urlStringPad = Generator.GetImageUrl(new ImageUrlGenerationOptions { ImageUrl = MediaPath, ImageCropMode = "Pad", Width = 300, Height = 150 }); - var urlStringMax = Generator.GetImageUrl(new ImageUrlGenerationOptions { ImageUrl = MediaPath, ImageCropMode = "Max", Width = 300, Height = 150 }); - var urlStringStretch = Generator.GetImageUrl(new ImageUrlGenerationOptions { ImageUrl = MediaPath, ImageCropMode = "Stretch", Width = 300, Height = 150 }); + var urlStringMin = Generator.GetImageUrl(new ImageUrlGenerationOptions(MediaPath) { ImageCropMode = "Min", Width = 300, Height = 150 }); + var urlStringBoxPad = Generator.GetImageUrl(new ImageUrlGenerationOptions(MediaPath) { ImageCropMode = "BoxPad", Width = 300, Height = 150 }); + var urlStringPad = Generator.GetImageUrl(new ImageUrlGenerationOptions(MediaPath) { ImageCropMode = "Pad", Width = 300, Height = 150 }); + var urlStringMax = Generator.GetImageUrl(new ImageUrlGenerationOptions(MediaPath) { ImageCropMode = "Max", Width = 300, Height = 150 }); + var urlStringStretch = Generator.GetImageUrl(new ImageUrlGenerationOptions(MediaPath) { ImageCropMode = "Stretch", Width = 300, Height = 150 }); Assert.AreEqual(MediaPath + "?mode=min&width=300&height=150", urlStringMin); Assert.AreEqual(MediaPath + "?mode=boxpad&width=300&height=150", urlStringBoxPad); @@ -145,7 +145,7 @@ namespace Umbraco.Tests.Models [Test] public void GetCropUrl_UploadTypeTest() { - var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions { ImageUrl = MediaPath, ImageCropMode = "Crop", ImageCropAnchor = "Center", Width = 100, Height = 270 }); + var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions(MediaPath) { ImageCropMode = "Crop", ImageCropAnchor = "Center", Width = 100, Height = 270 }); Assert.AreEqual(MediaPath + "?mode=crop&anchor=center&width=100&height=270", urlString); } @@ -155,7 +155,7 @@ namespace Umbraco.Tests.Models [Test] public void GetCropUrl_PreferFocalPointCenter() { - var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions { ImageUrl = MediaPath, DefaultCrop = true, Width = 300, Height = 150 }); + var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions(MediaPath) { DefaultCrop = true, Width = 300, Height = 150 }); Assert.AreEqual(MediaPath + "?anchor=center&mode=crop&width=300&height=150", urlString); } @@ -165,7 +165,7 @@ namespace Umbraco.Tests.Models [Test] public void GetCropUrl_PreDefinedCropNoCoordinatesWithWidth() { - var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions { ImageUrl = MediaPath, DefaultCrop = true, Width = 200, HeightRatio = 0.5962962962962962962962962963m }); + var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions(MediaPath) { DefaultCrop = true, Width = 200, HeightRatio = 0.5962962962962962962962962963m }); Assert.AreEqual(MediaPath + "?anchor=center&mode=crop&heightratio=0.5962962962962962962962962963&width=200", urlString); } @@ -175,7 +175,7 @@ namespace Umbraco.Tests.Models [Test] public void GetCropUrl_PreDefinedCropNoCoordinatesWithWidthAndFocalPoint() { - var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions { ImageUrl = MediaPath, FocalPoint = Focus2, Width = 200, HeightRatio = 0.5962962962962962962962962963m }); + var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions(MediaPath) { FocalPoint = Focus2, Width = 200, HeightRatio = 0.5962962962962962962962962963m }); Assert.AreEqual(MediaPath + "?center=0.41,0.4275&mode=crop&heightratio=0.5962962962962962962962962963&width=200", urlString); } @@ -185,7 +185,7 @@ namespace Umbraco.Tests.Models [Test] public void GetCropUrl_PreDefinedCropNoCoordinatesWithWidthAndFocalPointIgnore() { - var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions { ImageUrl = MediaPath, FocalPoint = Focus2, Width = 270, Height = 161 }); + var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions(MediaPath) { FocalPoint = Focus2, Width = 270, Height = 161 }); Assert.AreEqual(MediaPath + "?center=0.41,0.4275&mode=crop&width=270&height=161", urlString); } @@ -195,7 +195,7 @@ namespace Umbraco.Tests.Models [Test] public void GetCropUrl_PreDefinedCropNoCoordinatesWithHeight() { - var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions { ImageUrl = MediaPath, DefaultCrop = true, Height = 200, WidthRatio = 1.6770186335403726708074534161m }); + var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions(MediaPath) { DefaultCrop = true, Height = 200, WidthRatio = 1.6770186335403726708074534161m }); Assert.AreEqual(MediaPath + "?anchor=center&mode=crop&widthratio=1.6770186335403726708074534161&height=200", urlString); } @@ -205,7 +205,7 @@ namespace Umbraco.Tests.Models [Test] public void GetCropUrl_WidthOnlyParameter() { - var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions { ImageUrl = MediaPath, DefaultCrop = true, Width = 200 }); + var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions(MediaPath) { DefaultCrop = true, Width = 200 }); Assert.AreEqual(MediaPath + "?anchor=center&mode=crop&width=200", urlString); } @@ -215,7 +215,7 @@ namespace Umbraco.Tests.Models [Test] public void GetCropUrl_HeightOnlyParameter() { - var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions { ImageUrl = MediaPath, DefaultCrop = true, Height = 200 }); + var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions(MediaPath) { DefaultCrop = true, Height = 200 }); Assert.AreEqual(MediaPath + "?anchor=center&mode=crop&height=200", urlString); } @@ -225,7 +225,7 @@ namespace Umbraco.Tests.Models [Test] public void GetCropUrl_BackgroundColorParameter() { - var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions { ImageUrl = MediaPath, ImageCropMode = "Pad", Width = 400, Height = 400, FurtherOptions = "&bgcolor=fff" }); + var urlString = Generator.GetImageUrl(new ImageUrlGenerationOptions(MediaPath) { ImageCropMode = "Pad", Width = 400, Height = 400, FurtherOptions = "&bgcolor=fff" }); Assert.AreEqual(MediaPath + "?mode=pad&width=400&height=400&bgcolor=fff", urlString); } } diff --git a/src/Umbraco.Web/Editors/ImageUrlGeneratorController.cs b/src/Umbraco.Web/Editors/ImageUrlGeneratorController.cs index 7a02b2bd65..87d7e29619 100644 --- a/src/Umbraco.Web/Editors/ImageUrlGeneratorController.cs +++ b/src/Umbraco.Web/Editors/ImageUrlGeneratorController.cs @@ -16,12 +16,11 @@ namespace Umbraco.Web.Editors /// /// This controller allows for retrieving URLs for processed images, such as resized, cropped, /// or otherwise altered. These can be different based on the IImageUrlGenerator - /// implementation in use, and so back-office could should not rely on hard-coded string + /// implementation in use, and so the BackOffice could should not rely on hard-coded string /// building to generate correct URLs /// /// - [PluginController("UmbracoApi")] - public class ImageUrlGeneratorController + public class ImageUrlGeneratorController : UmbracoAuthorizedJsonController { private readonly IImageUrlGenerator _imageUrlGenerator; diff --git a/src/Umbraco.Web/Editors/ImagesController.cs b/src/Umbraco.Web/Editors/ImagesController.cs index c8f0e2d9bf..f3682a5b43 100644 --- a/src/Umbraco.Web/Editors/ImagesController.cs +++ b/src/Umbraco.Web/Editors/ImagesController.cs @@ -84,7 +84,7 @@ namespace Umbraco.Web.Editors } var rnd = imageLastModified.HasValue ? $"&rnd={imageLastModified:yyyyMMddHHmmss}" : null; - var imageUrl = _imageUrlGenerator.GetImageUrl(new ImageUrlGenerationOptions { ImageUrl = imagePath, UpScale = false, Width = width, AnimationProcessMode = "first", ImageCropMode = "max", CacheBusterValue = rnd }); + var imageUrl = _imageUrlGenerator.GetImageUrl(new ImageUrlGenerationOptions(imagePath) { UpScale = false, Width = width, AnimationProcessMode = "first", ImageCropMode = "max", CacheBusterValue = rnd }); response.Headers.Location = new Uri(imageUrl, UriKind.RelativeOrAbsolute); return response; diff --git a/src/Umbraco.Web/ImageCropperTemplateCoreExtensions.cs b/src/Umbraco.Web/ImageCropperTemplateCoreExtensions.cs index 74b32f2941..7ac5578d75 100644 --- a/src/Umbraco.Web/ImageCropperTemplateCoreExtensions.cs +++ b/src/Umbraco.Web/ImageCropperTemplateCoreExtensions.cs @@ -343,9 +343,8 @@ namespace Umbraco.Web } else { - options = new ImageUrlGenerationOptions + options = new ImageUrlGenerationOptions (imageUrl) { - ImageUrl = imageUrl, ImageCropMode = (imageCropMode ?? ImageCropMode.Pad).ToString().ToLowerInvariant(), ImageCropAnchor = imageCropAnchor?.ToString().ToLowerInvariant() }; diff --git a/src/Umbraco.Web/Models/ImageProcessorImageUrlGenerator.cs b/src/Umbraco.Web/Models/ImageProcessorImageUrlGenerator.cs index 47d7488c10..e471e9aa4a 100644 --- a/src/Umbraco.Web/Models/ImageProcessorImageUrlGenerator.cs +++ b/src/Umbraco.Web/Models/ImageProcessorImageUrlGenerator.cs @@ -13,26 +13,9 @@ namespace Umbraco.Web.Models var imageProcessorUrl = new StringBuilder(options.ImageUrl ?? string.Empty); - if (options.FocalPoint != null) - { - imageProcessorUrl.Append("?center="); - imageProcessorUrl.Append(options.FocalPoint.Top.ToString(CultureInfo.InvariantCulture)).Append(","); - imageProcessorUrl.Append(options.FocalPoint.Left.ToString(CultureInfo.InvariantCulture)); - imageProcessorUrl.Append("&mode=crop"); - } - else if (options.Crop != null) - { - imageProcessorUrl.Append("?crop="); - imageProcessorUrl.Append(options.Crop.X1.ToString(CultureInfo.InvariantCulture)).Append(","); - imageProcessorUrl.Append(options.Crop.Y1.ToString(CultureInfo.InvariantCulture)).Append(","); - imageProcessorUrl.Append(options.Crop.X2.ToString(CultureInfo.InvariantCulture)).Append(","); - imageProcessorUrl.Append(options.Crop.Y2.ToString(CultureInfo.InvariantCulture)); - imageProcessorUrl.Append("&cropmode=percentage"); - } - else if (options.DefaultCrop) - { - imageProcessorUrl.Append("?anchor=center&mode=crop"); - } + if (options.FocalPoint != null) AppendFocalPoint(imageProcessorUrl, options); + else if (options.Crop != null) AppendCrop(imageProcessorUrl, options); + else if (options.DefaultCrop) imageProcessorUrl.Append("?anchor=center&mode=crop"); else { imageProcessorUrl.Append("?mode=").Append((options.ImageCropMode ?? "crop").ToLower()); @@ -59,5 +42,23 @@ namespace Umbraco.Web.Models return imageProcessorUrl.ToString(); } + + private void AppendFocalPoint(StringBuilder imageProcessorUrl, ImageUrlGenerationOptions options) + { + imageProcessorUrl.Append("?center="); + imageProcessorUrl.Append(options.FocalPoint.Top.ToString(CultureInfo.InvariantCulture)).Append(","); + imageProcessorUrl.Append(options.FocalPoint.Left.ToString(CultureInfo.InvariantCulture)); + imageProcessorUrl.Append("&mode=crop"); + } + + private void AppendCrop(StringBuilder imageProcessorUrl, ImageUrlGenerationOptions options) + { + imageProcessorUrl.Append("?crop="); + imageProcessorUrl.Append(options.Crop.X1.ToString(CultureInfo.InvariantCulture)).Append(","); + imageProcessorUrl.Append(options.Crop.Y1.ToString(CultureInfo.InvariantCulture)).Append(","); + imageProcessorUrl.Append(options.Crop.X2.ToString(CultureInfo.InvariantCulture)).Append(","); + imageProcessorUrl.Append(options.Crop.Y2.ToString(CultureInfo.InvariantCulture)); + imageProcessorUrl.Append("&cropmode=percentage"); + } } } diff --git a/src/Umbraco.Web/PropertyEditors/RichTextEditorPastedImages.cs b/src/Umbraco.Web/PropertyEditors/RichTextEditorPastedImages.cs index e5afc44e43..e7ce0763e4 100644 --- a/src/Umbraco.Web/PropertyEditors/RichTextEditorPastedImages.cs +++ b/src/Umbraco.Web/PropertyEditors/RichTextEditorPastedImages.cs @@ -109,7 +109,7 @@ namespace Umbraco.Web.PropertyEditors if (width != int.MinValue && height != int.MinValue) { - location = imageUrlGenerator.GetImageUrl(new ImageUrlGenerationOptions { ImageUrl = location, ImageCropMode = "max", Width = width, Height = height }); + location = imageUrlGenerator.GetImageUrl(new ImageUrlGenerationOptions(location) { ImageCropMode = "max", Width = width, Height = height }); } img.SetAttributeValue("src", location);