public static IHtmlString GetCropUrl(this UrlHelper urlHelper, ImageCropperValue imageCropperValue, int?width = null, int?height = null, string cropAlias = null, int?quality = null, ImageCropMode?imageCropMode = null, ImageCropAnchor?imageCropAnchor = null, bool preferFocalPoint = false, bool useCropDimensions = false, string cacheBusterValue = null, string furtherOptions = null, ImageCropRatioMode?ratioMode = null, bool upScale = true, bool htmlEncode = true) { if (imageCropperValue == null) { return(EmptyHtmlString); } var imageUrl = imageCropperValue.Src; var url = imageUrl.GetCropUrl(imageCropperValue, width, height, cropAlias, quality, imageCropMode, imageCropAnchor, preferFocalPoint, useCropDimensions, cacheBusterValue, furtherOptions, ratioMode, upScale); return(htmlEncode ? new HtmlString(HttpUtility.HtmlEncode(url)) : new HtmlString(url)); }
/// <summary> /// This is called to merge in the prevalue crops with the value that is saved - similar to the property value converter for the front-end /// </summary> public override object ToEditor(Property property, IDataTypeService dataTypeService, string culture = null, string segment = null) { var val = property.GetValue(culture, segment); if (val == null) { return(null); } ImageCropperValue value; try { value = JsonConvert.DeserializeObject <ImageCropperValue>(val.ToString()); } catch { value = new ImageCropperValue { Src = val.ToString() }; } var dataType = dataTypeService.GetDataType(property.PropertyType.DataTypeId); if (dataType?.Configuration != null) { value.ApplyConfiguration(dataType.ConfigurationAs <ImageCropperConfiguration>()); } return(value); }
/// <summary> /// Gets the ImageProcessor Url from the image path. /// </summary> /// <param name="imageUrl"> /// The image url. /// </param> /// <param name="width"> /// The width of the output image. /// </param> /// <param name="height"> /// The height of the output image. /// </param> /// <param name="imageCropperValue"> /// The Json data from the Umbraco Core Image Cropper property editor /// </param> /// <param name="cropAlias"> /// The crop alias. /// </param> /// <param name="quality"> /// Quality percentage of the output image. /// </param> /// <param name="imageCropMode"> /// The image crop mode. /// </param> /// <param name="imageCropAnchor"> /// The image crop anchor. /// </param> /// <param name="preferFocalPoint"> /// Use focal point to generate an output image using the focal point instead of the predefined crop if there is one /// </param> /// <param name="useCropDimensions"> /// Use crop dimensions to have the output image sized according to the predefined crop sizes, this will override the width and height parameters /// </param> /// <param name="cacheBusterValue"> /// Add a serialized date of the last edit of the item to ensure client cache refresh when updated /// </param> /// <param name="furtherOptions"> /// These are any query string parameters (formatted as query strings) that ImageProcessor supports. For example: /// <example> /// <![CDATA[ /// furtherOptions: "&bgcolor=fff" /// ]]> /// </example> /// </param> /// <param name="ratioMode"> /// Use a dimension as a ratio /// </param> /// <param name="upScale"> /// If the image should be upscaled to requested dimensions /// </param> /// <returns> /// The <see cref="string"/>. /// </returns> public static string GetCropUrl( this string imageUrl, IImageUrlGenerator imageUrlGenerator, int?width = null, int?height = null, string imageCropperValue = null, string cropAlias = null, int?quality = null, ImageCropMode?imageCropMode = null, ImageCropAnchor?imageCropAnchor = null, bool preferFocalPoint = false, bool useCropDimensions = false, string cacheBusterValue = null, string furtherOptions = null, ImageCropRatioMode?ratioMode = null, bool upScale = true) { if (string.IsNullOrEmpty(imageUrl)) { return(string.Empty); } ImageCropperValue cropDataSet = null; if (string.IsNullOrEmpty(imageCropperValue) == false && imageCropperValue.DetectIsJson() && (imageCropMode == ImageCropMode.Crop || imageCropMode == null)) { cropDataSet = imageCropperValue.DeserializeImageCropperValue(); } return(GetCropUrl( imageUrl, imageUrlGenerator, cropDataSet, width, height, cropAlias, quality, imageCropMode, imageCropAnchor, preferFocalPoint, useCropDimensions, cacheBusterValue, furtherOptions, ratioMode, upScale)); }
public void GetBaseCropUrlFromModelTest() { ImageCropperValue cropDataSet = CropperJson1.DeserializeImageCropperValue(); var urlString = cropDataSet.GetCropUrl("thumb", new TestImageUrlGenerator()); Assert.AreEqual("?c=0.58729977382575338,0.055768992440203169,0,0.32457553600198386&w=100&h=100", urlString); }
public static IHtmlContent GetCropUrl(this IUrlHelper urlHelper, ImageCropperValue imageCropperValue, string cropAlias, int?width = null, int?height = null, int?quality = null, ImageCropMode?imageCropMode = null, ImageCropAnchor?imageCropAnchor = null, bool preferFocalPoint = false, bool useCropDimensions = true, string?cacheBusterValue = null, string?furtherOptions = null, bool htmlEncode = true) { if (imageCropperValue == null) { return(HtmlString.Empty); } var imageUrl = imageCropperValue.Src; var url = imageUrl?.GetCropUrl(imageCropperValue, width, height, cropAlias, quality, imageCropMode, imageCropAnchor, preferFocalPoint, useCropDimensions, cacheBusterValue, furtherOptions); return(CreateHtmlString(url, htmlEncode)); }
/// <summary> /// Gets the underlying image processing service URL from the image path. /// </summary> /// <param name="imageUrl">The image URL.</param> /// <param name="cropDataSet">The crop data set.</param> /// <param name="width">The width of the output image.</param> /// <param name="height">The height of the output image.</param> /// <param name="cropAlias">The crop alias.</param> /// <param name="quality">Quality percentage of the output image.</param> /// <param name="imageCropMode">The image crop mode.</param> /// <param name="imageCropAnchor">The image crop anchor.</param> /// <param name="preferFocalPoint">Use focal point to generate an output image using the focal point instead of the predefined crop if there is one.</param> /// <param name="useCropDimensions">Use crop dimensions to have the output image sized according to the predefined crop sizes, this will override the width and height parameters.</param> /// <param name="cacheBusterValue">Add a serialized date of the last edit of the item to ensure client cache refresh when updated.</param> /// <param name="furtherOptions">These are any query string parameters (formatted as query strings) that the underlying image processing service supports. For example: /// <example><![CDATA[ /// furtherOptions: "bgcolor=fff" /// ]]></example></param> /// <returns> /// The URL of the cropped image. /// </returns> public static string?GetCropUrl( this string imageUrl, ImageCropperValue cropDataSet, int?width = null, int?height = null, string?cropAlias = null, int?quality = null, ImageCropMode?imageCropMode = null, ImageCropAnchor?imageCropAnchor = null, bool preferFocalPoint = false, bool useCropDimensions = false, string?cacheBusterValue = null, string?furtherOptions = null) => imageUrl.GetCropUrl( ImageUrlGenerator, cropDataSet, width, height, cropAlias, quality, imageCropMode, imageCropAnchor, preferFocalPoint, useCropDimensions, cacheBusterValue, furtherOptions );
/// <summary> /// Applies the configuration to ensure only valid crops are kept and have the correct width/height. /// </summary> public static void ApplyConfiguration(this ImageCropperValue imageCropperValue, MediaPicker3Configuration?configuration) { var crops = new List <ImageCropperValue.ImageCropperCrop>(); MediaPicker3Configuration.CropConfiguration[]? configuredCrops = configuration?.Crops; if (configuredCrops != null) { foreach (MediaPicker3Configuration.CropConfiguration configuredCrop in configuredCrops) { ImageCropperValue.ImageCropperCrop?crop = imageCropperValue.Crops?.FirstOrDefault(x => x.Alias == configuredCrop.Alias); crops.Add(new ImageCropperValue.ImageCropperCrop { Alias = configuredCrop.Alias, Width = configuredCrop.Width, Height = configuredCrop.Height, Coordinates = crop?.Coordinates, }); } } imageCropperValue.Crops = crops; if (configuration?.EnableLocalFocalPoint == false) { imageCropperValue.FocalPoint = null; } }
/// <summary> /// Gets the crop URL by using only the specified <paramref name="imageCropperValue" />. /// </summary> /// <param name="mediaItem">The media item.</param> /// <param name="imageCropperValue">The image cropper value.</param> /// <param name="cropAlias">The crop alias.</param> /// <param name="imageUrlGenerator">The image URL generator.</param> /// <param name="publishedValueFallback">The published value fallback.</param> /// <param name="publishedUrlProvider">The published URL provider.</param> /// <param name="urlMode">The url mode.s</param> /// <returns> /// The image crop URL. /// </returns> public static string?GetCropUrl( this IPublishedContent mediaItem, ImageCropperValue imageCropperValue, string cropAlias, IImageUrlGenerator imageUrlGenerator, IPublishedValueFallback publishedValueFallback, IPublishedUrlProvider publishedUrlProvider, UrlMode urlMode = UrlMode.Default) => mediaItem.GetCropUrl(imageUrlGenerator, publishedValueFallback, publishedUrlProvider, imageCropperValue, true, cropAlias: cropAlias, useCropDimensions: true, urlMode: urlMode);
public void CanConvertImageCropperDataSetJObject() { // cropperJson3 - has not crops ImageCropperValue cropperValue = CropperJson3.DeserializeImageCropperValue(); Attempt <JObject> serialized = cropperValue.TryConvertTo <JObject>(); Assert.IsTrue(serialized.Success); Assert.AreEqual(cropperValue, serialized.Result.ToObject <ImageCropperValue>()); }
public void CanConvertImageCropperDataSetSrcToString() { // cropperJson3 - has not crops ImageCropperValue cropperValue = CropperJson3.DeserializeImageCropperValue(); Attempt <string> serialized = cropperValue.TryConvertTo <string>(); Assert.IsTrue(serialized.Success); Assert.AreEqual("/media/1005/img_0672.jpg", serialized.Result); }
public static IHtmlString GetCropUrl(this UrlHelper urlHelper, ImageCropperValue imageCropperValue, string cropAlias, bool htmlEncode = true) { if (imageCropperValue == null || string.IsNullOrEmpty(imageCropperValue.Src)) { return(EmptyHtmlString); } var url = imageCropperValue.Src.GetCropUrl(imageCropperValue, cropAlias: cropAlias, useCropDimensions: true); return(CreateHtmlString(url, htmlEncode)); }
public void CanConvertImageCropperDataSetJsonToString() { ImageCropperValue cropperValue = CropperJson1.DeserializeImageCropperValue(); Attempt <string> serialized = cropperValue.TryConvertTo <string>(); Assert.IsTrue(serialized.Success); Assert.IsTrue(serialized.Result.DetectIsJson()); ImageCropperValue obj = JsonConvert.DeserializeObject <ImageCropperValue>(CropperJson1, new JsonSerializerSettings { Culture = CultureInfo.InvariantCulture, FloatParseHandling = FloatParseHandling.Decimal }); Assert.AreEqual(cropperValue, obj); }
/// <summary> /// Gets the ImageProcessor URL from the image path. /// </summary> /// <param name="imageUrl"> /// The image URL. /// </param> /// <param name="cropDataSet"></param> /// <param name="width"> /// The width of the output image. /// </param> /// <param name="height"> /// The height of the output image. /// </param> /// <param name="cropAlias"> /// The crop alias. /// </param> /// <param name="quality"> /// Quality percentage of the output image. /// </param> /// <param name="imageCropMode"> /// The image crop mode. /// </param> /// <param name="imageCropAnchor"> /// The image crop anchor. /// </param> /// <param name="preferFocalPoint"> /// Use focal point to generate an output image using the focal point instead of the predefined crop if there is one /// </param> /// <param name="useCropDimensions"> /// Use crop dimensions to have the output image sized according to the predefined crop sizes, this will override the width and height parameters /// </param> /// <param name="cacheBusterValue"> /// Add a serialized date of the last edit of the item to ensure client cache refresh when updated /// </param> /// <param name="furtherOptions"> /// These are any query string parameters (formatted as query strings) that ImageProcessor supports. For example: /// <example> /// <![CDATA[ /// furtherOptions: "&bgcolor=fff" /// ]]> /// </example> /// </param> /// <param name="ratioMode"> /// Use a dimension as a ratio /// </param> /// <param name="upScale"> /// If the image should be upscaled to requested dimensions /// </param> /// <returns> /// The <see cref="string"/>. /// </returns> public static string GetCropUrl( this string imageUrl, ImageCropperValue cropDataSet, int?width = null, int?height = null, string cropAlias = null, int?quality = null, ImageCropMode?imageCropMode = null, ImageCropAnchor?imageCropAnchor = null, bool preferFocalPoint = false, bool useCropDimensions = false, string cacheBusterValue = null, string furtherOptions = null, ImageCropRatioMode?ratioMode = null, bool upScale = true) => ImageCropperTemplateCoreExtensions.GetCropUrl(imageUrl, Current.ImageUrlGenerator, cropDataSet, width, height, cropAlias, quality, imageCropMode, imageCropAnchor, preferFocalPoint, useCropDimensions, cacheBusterValue, furtherOptions, ratioMode, upScale);
public override object?ConvertIntermediateToObject(IPublishedElement owner, IPublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object?inter, bool preview) { var isMultiple = IsMultipleDataType(propertyType.DataType); if (string.IsNullOrEmpty(inter?.ToString())) { // Short-circuit on empty value return(isMultiple ? Enumerable.Empty <MediaWithCrops>() : null); } var mediaItems = new List <MediaWithCrops>(); IEnumerable <MediaPicker3PropertyEditor.MediaPicker3PropertyValueEditor.MediaWithCropsDto> dtos = MediaPicker3PropertyEditor.MediaPicker3PropertyValueEditor.Deserialize(_jsonSerializer, inter); MediaPicker3Configuration?configuration = propertyType.DataType.ConfigurationAs <MediaPicker3Configuration>(); IPublishedSnapshot publishedSnapshot = _publishedSnapshotAccessor.GetRequiredPublishedSnapshot(); foreach (MediaPicker3PropertyEditor.MediaPicker3PropertyValueEditor.MediaWithCropsDto dto in dtos) { IPublishedContent?mediaItem = publishedSnapshot.Media?.GetById(preview, dto.MediaKey); if (mediaItem != null) { var localCrops = new ImageCropperValue { Crops = dto.Crops, FocalPoint = dto.FocalPoint, Src = mediaItem.Url(_publishedUrlProvider), }; localCrops.ApplyConfiguration(configuration); // TODO: This should be optimized/cached, as calling Activator.CreateInstance is slow Type mediaWithCropsType = typeof(MediaWithCrops <>).MakeGenericType(mediaItem.GetType()); var mediaWithCrops = (MediaWithCrops)Activator.CreateInstance(mediaWithCropsType, mediaItem, _publishedValueFallback, localCrops) !; mediaItems.Add(mediaWithCrops); if (!isMultiple) { // Short-circuit on single item break; } } } return(isMultiple ? mediaItems : mediaItems.FirstOrDefault()); }
public void Get_Media_Url_Resolves_Url_From_Image_Cropper_Property_Editor() { const string expected = "/media/rfeiw584/test.jpg"; var configuration = new ImageCropperConfiguration(); var imageCropperValue = new ImageCropperValue { Src = expected }; var umbracoContext = GetUmbracoContext("/", mediaUrlProviders: new[] { _mediaUrlProvider }); var publishedContent = CreatePublishedContent(Constants.PropertyEditors.Aliases.ImageCropper, imageCropperValue, configuration); var resolvedUrl = umbracoContext.UrlProvider.GetMediaUrl(publishedContent, UrlMode.Auto); Assert.AreEqual(expected, resolvedUrl); }
private static List <IEnterspeedProperty> GetCropsProperty(ImageCropperValue value) { var crops = new List <IEnterspeedProperty>(); if (value != null && value.Crops != null) { foreach (var crop in value.Crops) { var cropProperties = new Dictionary <string, IEnterspeedProperty> { { "alias", new StringEnterspeedProperty(crop.Alias) }, { "height", new NumberEnterspeedProperty(crop.Height) }, { "width", new NumberEnterspeedProperty(crop.Width) } }; ObjectEnterspeedProperty cropCoordinatesProperty = null; if (crop.Coordinates != null) { var cropCoordinatesProperties = new Dictionary <string, IEnterspeedProperty> { { "X1", new NumberEnterspeedProperty(double.Parse(crop.Coordinates.X1.ToString(CultureInfo.InvariantCulture))) }, { "Y1", new NumberEnterspeedProperty(double.Parse(crop.Coordinates.Y1.ToString(CultureInfo.InvariantCulture))) }, { "X2", new NumberEnterspeedProperty(double.Parse(crop.Coordinates.X2.ToString(CultureInfo.InvariantCulture))) }, { "Y2", new NumberEnterspeedProperty(double.Parse(crop.Coordinates.Y2.ToString(CultureInfo.InvariantCulture))) } }; cropCoordinatesProperty = new ObjectEnterspeedProperty(cropCoordinatesProperties); } cropProperties.Add("coordinates", cropCoordinatesProperty); crops.Add(new ObjectEnterspeedProperty(cropProperties)); } } return(crops); }
internal static ImageCropperValue DeserializeImageCropperValue(this string json) { ImageCropperValue imageCrops = null; if (json.DetectIsJson()) { try { imageCrops = JsonConvert.DeserializeObject <ImageCropperValue>(json, s_imageCropperValueJsonSerializerSettings); } catch (Exception ex) { StaticApplicationLogging.Logger.LogError(ex, "Could not parse the json string: {Json}", json); } } imageCrops ??= new ImageCropperValue(); return(imageCrops); }
internal static ImageCropperValue DeserializeImageCropperValue(this string json) { ImageCropperValue imageCrops = null; if (json.DetectIsJson()) { try { imageCrops = JsonConvert.DeserializeObject <ImageCropperValue>(json, ImageCropperValueJsonSerializerSettings); } catch (Exception ex) { Current.Logger.Error <string>(typeof(ImageCropperTemplateExtensions), ex, "Could not parse the json string: {Json}", json); } } imageCrops = imageCrops ?? new ImageCropperValue(); return(imageCrops); }
private static ObjectEnterspeedProperty GetFocalPoint(ImageCropperValue value) { if (value == null || value.FocalPoint == null) { return(null); } var focalPointProperties = new Dictionary <string, IEnterspeedProperty> { { "left", new NumberEnterspeedProperty( double.Parse(value.FocalPoint.Left.ToString(CultureInfo.InvariantCulture))) }, { "top", new NumberEnterspeedProperty( double.Parse(value.FocalPoint.Top.ToString(CultureInfo.InvariantCulture))) } }; return(new ObjectEnterspeedProperty(focalPointProperties)); }
internal static ImageCropperValue DeserializeImageCropperValue(this string json) { var imageCrops = new ImageCropperValue(); if (json.DetectIsJson()) { try { imageCrops = JsonConvert.DeserializeObject <ImageCropperValue>(json, new JsonSerializerSettings { Culture = CultureInfo.InvariantCulture, FloatParseHandling = FloatParseHandling.Decimal }); } catch (Exception ex) { Current.Logger.Error(typeof(ImageCropperTemplateExtensions), ex, "Could not parse the json string: {Json}", json); } } return(imageCrops); }
/// <summary> /// Applies the configuration to ensure only valid crops are kept and have the correct width/height. /// </summary> /// <param name="configuration">The configuration.</param> public static void ApplyConfiguration(this ImageCropperValue imageCropperValue, ImageCropperConfiguration?configuration) { var crops = new List <ImageCropperValue.ImageCropperCrop>(); ImageCropperConfiguration.Crop[]? configuredCrops = configuration?.Crops; if (configuredCrops != null) { foreach (ImageCropperConfiguration.Crop configuredCrop in configuredCrops) { ImageCropperValue.ImageCropperCrop?crop = imageCropperValue.Crops?.FirstOrDefault(x => x.Alias == configuredCrop.Alias); crops.Add(new ImageCropperValue.ImageCropperCrop { Alias = configuredCrop.Alias, Width = configuredCrop.Width, Height = configuredCrop.Height, Coordinates = crop?.Coordinates, }); } } imageCropperValue.Crops = crops; }
/// <summary> /// Gets the ImageProcessor Url from the image path. /// </summary> /// <param name="imageUrl"> /// The image url. /// </param> /// <param name="imageUrlGenerator"> /// The generator that will process all the options and the image URL to return a full image urls with all processing options appended /// </param> /// <param name="cropDataSet"></param> /// <param name="width"> /// The width of the output image. /// </param> /// <param name="height"> /// The height of the output image. /// </param> /// <param name="cropAlias"> /// The crop alias. /// </param> /// <param name="quality"> /// Quality percentage of the output image. /// </param> /// <param name="imageCropMode"> /// The image crop mode. /// </param> /// <param name="imageCropAnchor"> /// The image crop anchor. /// </param> /// <param name="preferFocalPoint"> /// Use focal point to generate an output image using the focal point instead of the predefined crop if there is one /// </param> /// <param name="useCropDimensions"> /// Use crop dimensions to have the output image sized according to the predefined crop sizes, this will override the width and height parameters /// </param> /// <param name="cacheBusterValue"> /// Add a serialized date of the last edit of the item to ensure client cache refresh when updated /// </param> /// <param name="furtherOptions"> /// These are any query string parameters (formatted as query strings) that ImageProcessor supports. For example: /// <example> /// <![CDATA[ /// furtherOptions: "&bgcolor=fff" /// ]]> /// </example> /// </param> /// <param name="ratioMode"> /// Use a dimension as a ratio /// </param> /// <param name="upScale"> /// If the image should be upscaled to requested dimensions /// </param> /// <returns> /// The <see cref="string"/>. /// </returns> public static string GetCropUrl( this string imageUrl, IImageUrlGenerator imageUrlGenerator, ImageCropperValue cropDataSet, int?width = null, int?height = null, string cropAlias = null, int?quality = null, ImageCropMode?imageCropMode = null, ImageCropAnchor?imageCropAnchor = null, bool preferFocalPoint = false, bool useCropDimensions = false, string cacheBusterValue = null, string furtherOptions = null, ImageCropRatioMode?ratioMode = null, bool upScale = true, string animationProcessMode = null) { if (string.IsNullOrEmpty(imageUrl)) { return(string.Empty); } ImageUrlGenerationOptions options; if (cropDataSet != null && (imageCropMode == ImageCropMode.Crop || imageCropMode == null)) { var crop = cropDataSet.GetCrop(cropAlias); // if a crop was specified, but not found, return null if (crop == null && !string.IsNullOrWhiteSpace(cropAlias)) { return(null); } options = cropDataSet.GetCropBaseOptions(imageUrl, crop, string.IsNullOrWhiteSpace(cropAlias), preferFocalPoint); if (crop != null & useCropDimensions) { width = crop.Width; height = crop.Height; } // If a predefined crop has been specified & there are no coordinates & no ratio mode, but a width parameter has been passed we can get the crop ratio for the height if (crop != null && string.IsNullOrEmpty(cropAlias) == false && crop.Coordinates == null && ratioMode == null && width != null && height == null) { options.HeightRatio = (decimal)crop.Height / crop.Width; } // If a predefined crop has been specified & there are no coordinates & no ratio mode, but a height parameter has been passed we can get the crop ratio for the width if (crop != null && string.IsNullOrEmpty(cropAlias) == false && crop.Coordinates == null && ratioMode == null && width == null && height != null) { options.WidthRatio = (decimal)crop.Width / crop.Height; } } else { options = new ImageUrlGenerationOptions(imageUrl) { ImageCropMode = (imageCropMode ?? ImageCropMode.Pad).ToString().ToLowerInvariant(), ImageCropAnchor = imageCropAnchor?.ToString().ToLowerInvariant() }; } options.Quality = quality; options.Width = ratioMode != null && ratioMode.Value == ImageCropRatioMode.Width ? null : width; options.Height = ratioMode != null && ratioMode.Value == ImageCropRatioMode.Height ? null : height; options.AnimationProcessMode = animationProcessMode; if (ratioMode == ImageCropRatioMode.Width && height != null) { // if only height specified then assume a square if (width == null) { width = height; } options.WidthRatio = (decimal)width / (decimal)height; } if (ratioMode == ImageCropRatioMode.Height && width != null) { // if only width specified then assume a square if (height == null) { height = width; } options.HeightRatio = (decimal)height / (decimal)width; } options.UpScale = upScale; options.FurtherOptions = furtherOptions; options.CacheBusterValue = cacheBusterValue; return(imageUrlGenerator.GetImageUrl(options)); }
/// <summary> /// Initializes a new instance of the <see cref="MediaWithCrops" /> class. /// </summary> /// <param name="content">The content.</param> /// <param name="publishedValueFallback">The published value fallback.</param> /// <param name="localCrops">The local crops.</param> public MediaWithCrops(IPublishedContent content, IPublishedValueFallback publishedValueFallback, ImageCropperValue localCrops) : base(content, publishedValueFallback) =>
/// <summary> /// Gets the ImageProcessor Url from the image path. /// </summary> /// <param name="imageUrl"> /// The image url. /// </param> /// <param name="cropDataSet"></param> /// <param name="width"> /// The width of the output image. /// </param> /// <param name="height"> /// The height of the output image. /// </param> /// <param name="cropAlias"> /// The crop alias. /// </param> /// <param name="quality"> /// Quality percentage of the output image. /// </param> /// <param name="imageCropMode"> /// The image crop mode. /// </param> /// <param name="imageCropAnchor"> /// The image crop anchor. /// </param> /// <param name="preferFocalPoint"> /// Use focal point to generate an output image using the focal point instead of the predefined crop if there is one /// </param> /// <param name="useCropDimensions"> /// Use crop dimensions to have the output image sized according to the predefined crop sizes, this will override the width and height parameters /// </param> /// <param name="cacheBusterValue"> /// Add a serialized date of the last edit of the item to ensure client cache refresh when updated /// </param> /// <param name="furtherOptions"> /// These are any query string parameters (formatted as query strings) that ImageProcessor supports. For example: /// <example> /// <![CDATA[ /// furtherOptions: "&bgcolor=fff" /// ]]> /// </example> /// </param> /// <param name="ratioMode"> /// Use a dimension as a ratio /// </param> /// <param name="upScale"> /// If the image should be upscaled to requested dimensions /// </param> /// <returns> /// The <see cref="string"/>. /// </returns> public static string GetCropUrl( this string imageUrl, ImageCropperValue cropDataSet, int?width = null, int?height = null, string cropAlias = null, int?quality = null, ImageCropMode?imageCropMode = null, ImageCropAnchor?imageCropAnchor = null, bool preferFocalPoint = false, bool useCropDimensions = false, string cacheBusterValue = null, string furtherOptions = null, ImageCropRatioMode?ratioMode = null, bool upScale = true) { if (string.IsNullOrEmpty(imageUrl) == false) { var imageProcessorUrl = new StringBuilder(); if (cropDataSet != null && (imageCropMode == ImageCropMode.Crop || imageCropMode == null)) { var crop = cropDataSet.GetCrop(cropAlias); // if a crop was specified, but not found, return null if (crop == null && !string.IsNullOrWhiteSpace(cropAlias)) { return(null); } imageProcessorUrl.Append(imageUrl); cropDataSet.AppendCropBaseUrl(imageProcessorUrl, crop, string.IsNullOrWhiteSpace(cropAlias), preferFocalPoint); if (crop != null & useCropDimensions) { width = crop.Width; height = crop.Height; } // If a predefined crop has been specified & there are no coordinates & no ratio mode, but a width parameter has been passed we can get the crop ratio for the height if (crop != null && string.IsNullOrEmpty(cropAlias) == false && crop.Coordinates == null && ratioMode == null && width != null && height == null) { var heightRatio = (decimal)crop.Height / (decimal)crop.Width; imageProcessorUrl.Append("&heightratio=" + heightRatio.ToString(CultureInfo.InvariantCulture)); } // If a predefined crop has been specified & there are no coordinates & no ratio mode, but a height parameter has been passed we can get the crop ratio for the width if (crop != null && string.IsNullOrEmpty(cropAlias) == false && crop.Coordinates == null && ratioMode == null && width == null && height != null) { var widthRatio = (decimal)crop.Width / (decimal)crop.Height; imageProcessorUrl.Append("&widthratio=" + widthRatio.ToString(CultureInfo.InvariantCulture)); } } else { imageProcessorUrl.Append(imageUrl); if (imageCropMode == null) { imageCropMode = ImageCropMode.Pad; } imageProcessorUrl.Append("?mode=" + imageCropMode.ToString().ToLower()); if (imageCropAnchor != null) { imageProcessorUrl.Append("&anchor=" + imageCropAnchor.ToString().ToLower()); } } var hasFormat = furtherOptions != null && furtherOptions.InvariantContains("&format="); //Only put quality here, if we don't have a format specified. //Otherwise we need to put quality at the end to avoid it being overridden by the format. if (quality != null && hasFormat == false) { imageProcessorUrl.Append("&quality=" + quality); } if (width != null && ratioMode != ImageCropRatioMode.Width) { imageProcessorUrl.Append("&width=" + width); } if (height != null && ratioMode != ImageCropRatioMode.Height) { imageProcessorUrl.Append("&height=" + height); } if (ratioMode == ImageCropRatioMode.Width && height != null) { // if only height specified then assume a square if (width == null) { width = height; } var widthRatio = (decimal)width / (decimal)height; imageProcessorUrl.Append("&widthratio=" + widthRatio.ToString(CultureInfo.InvariantCulture)); } if (ratioMode == ImageCropRatioMode.Height && width != null) { // if only width specified then assume a square if (height == null) { height = width; } var heightRatio = (decimal)height / (decimal)width; imageProcessorUrl.Append("&heightratio=" + heightRatio.ToString(CultureInfo.InvariantCulture)); } if (upScale == false) { imageProcessorUrl.Append("&upscale=false"); } if (furtherOptions != null) { imageProcessorUrl.Append(furtherOptions); } //If furtherOptions contains a format, we need to put the quality after the format. if (quality != null && hasFormat) { imageProcessorUrl.Append("&quality=" + quality); } if (cacheBusterValue != null) { imageProcessorUrl.Append("&rnd=").Append(cacheBusterValue); } return(imageProcessorUrl.ToString()); } return(string.Empty); }
public static string GetCropUrl(this IPublishedContent mediaItem, string cropAlias, IImageUrlGenerator imageUrlGenerator, ImageCropperValue imageCropperValue) { return(mediaItem.Url().GetCropUrl(imageUrlGenerator, imageCropperValue, cropAlias: cropAlias, useCropDimensions: true)); }
/// <inheritdoc /> public override IEnumerable <ValueSet> GetValueSets(params IMedia[] media) { foreach (var m in media) { var urlValue = m.GetUrlSegment(_urlSegmentProviders); var umbracoFilePath = string.Empty; var umbracoFile = string.Empty; var umbracoFileSource = m.GetValue <string>(Constants.Conventions.Media.File); if (umbracoFileSource.DetectIsJson()) { ImageCropperValue cropper = null; try { cropper = JsonConvert.DeserializeObject <ImageCropperValue>( m.GetValue <string>(Constants.Conventions.Media.File)); } catch (Exception ex) { _logger.Error <MediaValueSetBuilder>(ex, $"Could not Deserialize ImageCropperValue for item with key {m.Key} "); } if (cropper != null) { umbracoFilePath = cropper.Src; } } else { umbracoFilePath = umbracoFileSource; } if (!string.IsNullOrEmpty(umbracoFilePath)) { // intentional dummy Uri var uri = new Uri("https://localhost/" + umbracoFilePath); umbracoFile = uri.Segments.Last(); } var values = new Dictionary <string, IEnumerable <object> > { { "icon", m.ContentType.Icon?.Yield() ?? Enumerable.Empty <string>() }, { "id", new object[] { m.Id } }, { UmbracoExamineIndex.NodeKeyFieldName, new object[] { m.Key } }, { "parentID", new object[] { m.Level > 1 ? m.ParentId : -1 } }, { "level", new object[] { m.Level } }, { "creatorID", new object[] { m.CreatorId } }, { "sortOrder", new object[] { m.SortOrder } }, { "createDate", new object[] { m.CreateDate } }, { "updateDate", new object[] { m.UpdateDate } }, { "nodeName", m.Name?.Yield() ?? Enumerable.Empty <string>() }, { "urlName", urlValue?.Yield() ?? Enumerable.Empty <string>() }, { "path", m.Path?.Yield() ?? Enumerable.Empty <string>() }, { "nodeType", m.ContentType.Id.ToString().Yield() }, { "creatorName", (m.GetCreatorProfile(_userService)?.Name ?? "??").Yield() }, { UmbracoExamineIndex.UmbracoFileFieldName, umbracoFile.Yield() } }; foreach (var property in m.Properties) { AddPropertyValue(property, null, null, values); } var vs = new ValueSet(m.Id.ToInvariantString(), IndexTypes.Media, m.ContentType.Alias, values); yield return(vs); } }
public static string GetCropUrl(this IPublishedContent mediaItem, string cropAlias, ImageCropperValue imageCropperValue) => ImageCropperTemplateCoreExtensions.GetCropUrl(mediaItem, cropAlias, Current.ImageUrlGenerator, imageCropperValue);
/// <summary> /// Removes redundant crop data/default focal point. /// </summary> /// <param name="value">The media with crops DTO.</param> /// <remarks> /// Because the DTO uses the same JSON keys as the image cropper value for crops and focal point, we can re-use the prune method. /// </remarks> public static void Prune(JObject?value) => ImageCropperValue.Prune(value);
/// <summary> /// Gets the crop URL by using only the specified <paramref name="imageCropperValue" />. /// </summary> /// <param name="mediaItem">The media item.</param> /// <param name="imageCropperValue">The image cropper value.</param> /// <param name="cropAlias">The crop alias.</param> /// <param name="urlMode">The url mode.</param> /// <returns> /// The image crop URL. /// </returns> public static string?GetCropUrl( this IPublishedContent mediaItem, ImageCropperValue imageCropperValue, string cropAlias, UrlMode urlMode = UrlMode.Default) => ImageCropperTemplateCoreExtensions.GetCropUrl(mediaItem, imageCropperValue, cropAlias, ImageUrlGenerator, PublishedValueFallback, PublishedUrlProvider, urlMode);
/// <summary> /// Converts the value received from the editor into the value can be stored in the database. /// </summary> /// <param name="editorValue">The value received from the editor.</param> /// <param name="currentValue">The current value of the property</param> /// <returns>The converted value.</returns> /// <remarks> /// <para>The <paramref name="currentValue"/> is used to re-use the folder, if possible.</para> /// <para>editorValue.Value is used to figure out editorFile and, if it has been cleared, remove the old file - but /// it is editorValue.AdditionalData["files"] that is used to determine the actual file that has been uploaded.</para> /// </remarks> public override object?FromEditor(ContentPropertyData editorValue, object?currentValue) { // Get the current path var currentPath = string.Empty; try { var svalue = currentValue as string; var currentJson = string.IsNullOrWhiteSpace(svalue) ? null : JObject.Parse(svalue); if (currentJson != null && currentJson.TryGetValue("src", out var src)) { currentPath = src.Value <string>(); } } catch (Exception ex) { // For some reason the value is invalid so continue as if there was no value there _logger.LogWarning(ex, "Could not parse current db value to a JObject."); } if (string.IsNullOrWhiteSpace(currentPath) == false) { currentPath = _mediaFileManager.FileSystem.GetRelativePath(currentPath); } // Get the new JSON and file path var editorFile = string.Empty; var editorJson = (JObject?)editorValue.Value; if (editorJson is not null) { // Populate current file if (editorJson["src"] != null) { editorFile = editorJson["src"]?.Value <string>(); } // Clean up redundant/default data ImageCropperValue.Prune(editorJson); } else { editorJson = null; } // ensure we have the required guids var cuid = editorValue.ContentKey; if (cuid == Guid.Empty) { throw new Exception("Invalid content key."); } var puid = editorValue.PropertyTypeKey; if (puid == Guid.Empty) { throw new Exception("Invalid property type key."); } // editorFile is empty whenever a new file is being uploaded // or when the file is cleared (in which case editorJson is null) // else editorFile contains the unchanged value var uploads = editorValue.Files; if (uploads == null) { throw new Exception("Invalid files."); } var file = uploads.Length > 0 ? uploads[0] : null; if (file == null) // not uploading a file { // if editorFile is empty then either there was nothing to begin with, // or it has been cleared and we need to remove the file - else the // value is unchanged. if (string.IsNullOrWhiteSpace(editorFile) && string.IsNullOrWhiteSpace(currentPath) == false) { _mediaFileManager.FileSystem.DeleteFile(currentPath); return(null); // clear } return(editorJson?.ToString(Formatting.None)); // unchanged } // process the file var filepath = editorJson == null ? null : ProcessFile(file, cuid, puid); // remove all temp files foreach (ContentPropertyFile f in uploads) { File.Delete(f.TempFilePath); } // remove current file if replaced if (currentPath != filepath && string.IsNullOrWhiteSpace(currentPath) == false) { _mediaFileManager.FileSystem.DeleteFile(currentPath); } // update json and return if (editorJson == null) { return(null); } editorJson["src"] = filepath == null ? string.Empty : _mediaFileManager.FileSystem.GetUrl(filepath); return(editorJson.ToString(Formatting.None)); }