2021-08-09 15:52:55 +02:00
using System ;
2020-02-07 15:01:03 -08:00
using System.Globalization ;
2021-02-10 11:42:04 +01:00
using Newtonsoft.Json.Linq ;
2021-07-05 20:58:04 +02:00
using Umbraco.Cms.Core ;
2021-02-09 10:22:42 +01:00
using Umbraco.Cms.Core.Media ;
using Umbraco.Cms.Core.Models ;
using Umbraco.Cms.Core.Models.PublishedContent ;
2021-02-15 10:42:35 +01:00
using Umbraco.Cms.Core.PropertyEditors.ValueConverters ;
2021-02-09 10:22:42 +01:00
using Umbraco.Cms.Core.Routing ;
2020-02-07 15:01:03 -08:00
2020-08-04 14:12:22 +02:00
namespace Umbraco.Extensions
2020-02-07 15:01:03 -08:00
{
public static class ImageCropperTemplateCoreExtensions
{
/// <summary>
2021-08-10 11:23:37 +02:00
/// Gets the underlying image processing service URL by the crop alias (from the "umbracoFile" property alias) on the IPublishedContent item.
2020-02-07 15:01:03 -08:00
/// </summary>
2021-08-10 11:23:37 +02:00
/// <param name="mediaItem">The IPublishedContent item.</param>
/// <param name="cropAlias">The crop alias e.g. thumbnail.</param>
/// <param name="imageUrlGenerator">The image URL generator.</param>
2020-08-04 14:12:22 +02:00
/// <param name="publishedValueFallback">The published value fallback.</param>
2021-08-10 11:23:37 +02:00
/// <param name="publishedUrlProvider">The published URL provider.</param>
2020-02-07 15:01:03 -08:00
/// <returns>
2021-05-06 10:06:22 +02:00
/// The URL of the cropped image.
2020-02-07 15:01:03 -08:00
/// </returns>
2020-08-04 14:12:22 +02:00
public static string GetCropUrl (
this IPublishedContent mediaItem ,
string cropAlias ,
IImageUrlGenerator imageUrlGenerator ,
IPublishedValueFallback publishedValueFallback ,
2021-08-10 11:23:37 +02:00
IPublishedUrlProvider publishedUrlProvider ) = > mediaItem . GetCropUrl ( imageUrlGenerator , publishedValueFallback , publishedUrlProvider , cropAlias : cropAlias , useCropDimensions : true ) ;
2020-02-07 15:01:03 -08:00
2021-07-05 20:58:04 +02:00
public static string GetCropUrl (
this MediaWithCrops mediaWithCrops ,
string cropAlias ,
IImageUrlGenerator imageUrlGenerator ,
IPublishedValueFallback publishedValueFallback ,
2021-08-10 11:23:37 +02:00
IPublishedUrlProvider publishedUrlProvider ) = > mediaWithCrops . GetCropUrl ( imageUrlGenerator , publishedValueFallback , publishedUrlProvider , cropAlias : cropAlias , useCropDimensions : true ) ;
2021-06-28 09:28:32 +02:00
/// <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>
2021-08-10 11:23:37 +02:00
/// <param name="publishedValueFallback">The published value fallback.</param>
/// <param name="publishedUrlProvider">The published URL provider.</param>
2021-06-28 09:28:32 +02:00
/// <returns>
/// The image crop URL.
/// </returns>
2021-07-05 20:58:04 +02:00
public static string GetCropUrl (
this IPublishedContent mediaItem ,
ImageCropperValue imageCropperValue ,
string cropAlias ,
IImageUrlGenerator imageUrlGenerator ,
IPublishedValueFallback publishedValueFallback ,
2021-08-10 11:23:37 +02:00
IPublishedUrlProvider publishedUrlProvider ) = > mediaItem . GetCropUrl ( imageUrlGenerator , publishedValueFallback , publishedUrlProvider , imageCropperValue , true , cropAlias : cropAlias , useCropDimensions : true ) ;
Media Picker v3 (#9461)
* set input file accept
* Use PreValue file extensions for limiting the files to be chosen in file input
* Current state for Warren to review
* This should fix up what you need Niels
* update csproj
* use empty string if fileExtensions is undefined
* public interface
* initial work
* local crops
* translations
* translation correction
* fix misspeling
* some progress
* filter media picker
* align media card grid items correctly
* responsive media cropper
* always be able to scale 3 times smallest scale
* making image cropper property editor responsive
* scroll to scale
* adjust slider look
* rearrange parts of mediaentryeditor
* test helper
* styling
* move controls inside umb-image-crop
* seperate umg-cropper-gravity styling
* corrected layout
* more ui refinement
* keep the idea of mandatory out for now.
* remove double ;
* removed testing code
* JSON Property Value Convertor now has an array of property editors to exclude
* Property Value Convertor for Media Picker 3 aka Media Picker with Local Crops
* Experimenting on best approach to retrieve local crop in razor view when iterating over picked media items
* Update ValueConvertor to use ImageCropperValue as part of the model for views as alot of existing CropUrls can then use it
* Update extension methods to take an ImageCropperValue model (localCropData)
* Forgot to update CSProj for new ValueConvertor
* New GetCropUrl @Url.GetCropUrl(crop.Alias, media.LocalCrops) as oppposed to @Url.GetCropUrl(media.LocalCrops, cropAlias:crop.Alias, useCropDimensions: true)
* Remove dupe item in CSProj
* Use a contains as an opposed to Array.IndexOf
* various corrections, SingleMode based on max 1, remove double checkerBackground, enforce validation for Crops, changed error indication
* mediapicker v3
* correct version
* fixing file ext label text color
* clipboard features for MediaPicker v3
* highlight not allowed types
* highlight trashed as an error
* Media Types Video, Sound, Document and Vector Image
* Rename to Audio and VectorGraphics
* Add (SVG) in the name for Vector Graphics
* adding CSV to Documents
* remove this commented code.
* remove this commented code
* number range should not go below 0, at-least as default until we make that configurable.
* use min not ng-min
* description for local crops
* Error/Limits highlighting reactive
* visual adjustments
* Enabling opening filtered folders + corrected select hover states
* Varous fixes to resolve issues with unit tests.
* Refactor MediaType Documents to only contain Article file type
* mark as build-in
* predefined MediaPicker3 DataTypes, renaming v2 to "old"
* set scale bar current value after min and max has been set
* added missing }
* update when focal point is dragged
* adjusted styling for Image Cropper property editor
* correcting comment
* remove todo - message for trashed media items works
* Changed parameter ordering
* Introduced new extension method on MediaWithCrops to get croppings urls in with full path
* Reintroducing Single Item Mode
* use Multiple instead of SingleMode
* renaming and adding multiple to preconfigured datatypes
* Change existing media picker to use the Clipboard type MEDIA, enabling shared functionality.
* clean up unused clipboard parts
* adjusted to new amount
* correcting test
* Fix unit test
* Move MediaWithCrops to separate file and move to Core.Models
* parseContentForPaste
* clean up
* ensure crops is an array.
* actively enable focal points, so we dont set focal points that aren't used.
* only accept files that matches file extensions from Umbraco Settings
* Cleanup
* Add references from MediaPicker3 to media
* corrections from various feedback
* remove comment
* correct wording
* use windowResizeListener
Co-authored-by: Warren Buckley <warren@umbraco.com>
Co-authored-by: Niels Lyngsø <nsl@umbraco.com>
Co-authored-by: Mads Rasmussen <madsr@hey.com>
Co-authored-by: Andy Butland <abutland73@gmail.com>
Co-authored-by: Bjarke Berg <mail@bergmania.dk>
Co-authored-by: Sebastiaan Janssen <sebastiaan@umbraco.com>
Co-authored-by: Elitsa Marinovska <elm@umbraco.dk>
2021-04-22 10:28:53 +02:00
2020-02-07 15:01:03 -08:00
/// <summary>
2021-08-10 11:23:37 +02:00
/// Gets the underlying image processing service URL by the crop alias using the specified property containing the image cropper JSON data on the IPublishedContent item.
2020-02-07 15:01:03 -08:00
/// </summary>
2021-08-10 11:23:37 +02:00
/// <param name="mediaItem">The IPublishedContent item.</param>
/// <param name="propertyAlias">The property alias of the property containing the JSON data e.g. umbracoFile.</param>
/// <param name="cropAlias">The crop alias e.g. thumbnail.</param>
/// <param name="imageUrlGenerator">The image URL generator.</param>
2020-08-04 14:12:22 +02:00
/// <param name="publishedValueFallback">The published value fallback.</param>
2021-08-10 11:23:37 +02:00
/// <param name="publishedUrlProvider">The published URL provider.</param>
2020-02-07 15:01:03 -08:00
/// <returns>
2021-05-06 10:06:22 +02:00
/// The URL of the cropped image.
2020-02-07 15:01:03 -08:00
/// </returns>
2020-08-04 14:12:22 +02:00
public static string GetCropUrl (
this IPublishedContent mediaItem ,
string propertyAlias ,
string cropAlias ,
IImageUrlGenerator imageUrlGenerator ,
IPublishedValueFallback publishedValueFallback ,
2021-08-10 11:23:37 +02:00
IPublishedUrlProvider publishedUrlProvider ) = > mediaItem . GetCropUrl ( imageUrlGenerator , publishedValueFallback , publishedUrlProvider , propertyAlias : propertyAlias , cropAlias : cropAlias , useCropDimensions : true ) ;
2020-02-07 15:01:03 -08:00
2021-07-05 20:58:04 +02:00
public static string GetCropUrl ( this MediaWithCrops mediaWithCrops ,
IPublishedValueFallback publishedValueFallback ,
IPublishedUrlProvider publishedUrlProvider ,
string propertyAlias ,
string cropAlias ,
2021-08-10 11:23:37 +02:00
IImageUrlGenerator imageUrlGenerator ) = > mediaWithCrops . GetCropUrl ( imageUrlGenerator , publishedValueFallback , publishedUrlProvider , propertyAlias : propertyAlias , cropAlias : cropAlias , useCropDimensions : true ) ;
2021-06-28 09:28:32 +02:00
2020-02-07 15:01:03 -08:00
/// <summary>
2021-05-06 10:06:22 +02:00
/// Gets the underlying image processing service URL from the IPublishedContent item.
2020-02-07 15:01:03 -08:00
/// </summary>
2021-08-10 11:23:37 +02:00
/// <param name="mediaItem">The IPublishedContent item.</param>
/// <param name="imageUrlGenerator">The image URL generator.</param>
2020-08-04 14:12:22 +02:00
/// <param name="publishedValueFallback">The published value fallback.</param>
2021-08-10 11:23:37 +02:00
/// <param name="publishedUrlProvider">The published URL provider.</param>
/// <param name="width">The width of the output image.</param>
/// <param name="height">The height of the output image.</param>
/// <param name="propertyAlias">Property alias of the property containing the JSON data.</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.</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="cacheBuster">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[
2020-02-07 15:01:03 -08:00
/// furtherOptions: "&bgcolor=fff"
2021-08-10 11:23:37 +02:00
/// ]]></example></param>
/// <param name="ratioMode">Use a dimension as a ratio.</param>
2020-02-07 15:01:03 -08:00
/// <returns>
2021-05-06 10:06:22 +02:00
/// The URL of the cropped image.
2020-02-07 15:01:03 -08:00
/// </returns>
public static string GetCropUrl (
this IPublishedContent mediaItem ,
IImageUrlGenerator imageUrlGenerator ,
2020-08-04 14:12:22 +02:00
IPublishedValueFallback publishedValueFallback ,
IPublishedUrlProvider publishedUrlProvider ,
2020-02-07 15:01:03 -08:00
int? width = null ,
int? height = null ,
2021-02-10 11:42:04 +01:00
string propertyAlias = Cms . Core . Constants . Conventions . Media . File ,
2020-02-07 15:01:03 -08:00
string cropAlias = null ,
int? quality = null ,
ImageCropMode ? imageCropMode = null ,
ImageCropAnchor ? imageCropAnchor = null ,
bool preferFocalPoint = false ,
bool useCropDimensions = false ,
bool cacheBuster = true ,
string furtherOptions = null ,
2021-08-10 11:23:37 +02:00
ImageCropRatioMode ? ratioMode = null ) = > mediaItem . GetCropUrl ( imageUrlGenerator , publishedValueFallback , publishedUrlProvider , null , false , width , height , propertyAlias , cropAlias , quality , imageCropMode , imageCropAnchor , preferFocalPoint , useCropDimensions , cacheBuster , furtherOptions , ratioMode ) ;
2021-06-28 09:28:32 +02:00
public static string GetCropUrl (
this MediaWithCrops mediaWithCrops ,
IImageUrlGenerator imageUrlGenerator ,
2021-07-05 20:58:04 +02:00
IPublishedValueFallback publishedValueFallback ,
IPublishedUrlProvider publishedUrlProvider ,
2021-06-28 09:28:32 +02:00
int? width = null ,
int? height = null ,
string propertyAlias = Constants . Conventions . Media . File ,
string cropAlias = null ,
int? quality = null ,
ImageCropMode ? imageCropMode = null ,
ImageCropAnchor ? imageCropAnchor = null ,
bool preferFocalPoint = false ,
bool useCropDimensions = false ,
bool cacheBuster = true ,
string furtherOptions = null ,
2021-08-10 11:23:37 +02:00
ImageCropRatioMode ? ratioMode = null )
2021-06-28 09:28:32 +02:00
{
2021-08-10 11:23:37 +02:00
if ( mediaWithCrops = = null )
{
throw new ArgumentNullException ( nameof ( mediaWithCrops ) ) ;
}
2021-06-28 09:28:32 +02:00
2021-08-10 11:23:37 +02:00
return mediaWithCrops . Content . GetCropUrl ( imageUrlGenerator , publishedValueFallback , publishedUrlProvider , mediaWithCrops . LocalCrops , false , width , height , propertyAlias , cropAlias , quality , imageCropMode , imageCropAnchor , preferFocalPoint , useCropDimensions , cacheBuster , furtherOptions , ratioMode ) ;
2021-06-28 09:28:32 +02:00
}
private static string GetCropUrl (
this IPublishedContent mediaItem ,
IImageUrlGenerator imageUrlGenerator ,
2021-07-05 20:58:04 +02:00
IPublishedValueFallback publishedValueFallback ,
IPublishedUrlProvider publishedUrlProvider ,
2021-06-28 09:28:32 +02:00
ImageCropperValue localCrops ,
bool localCropsOnly ,
int? width = null ,
int? height = null ,
string propertyAlias = Constants . Conventions . Media . File ,
string cropAlias = null ,
int? quality = null ,
ImageCropMode ? imageCropMode = null ,
ImageCropAnchor ? imageCropAnchor = null ,
bool preferFocalPoint = false ,
bool useCropDimensions = false ,
bool cacheBuster = true ,
string furtherOptions = null ,
2021-08-10 11:23:37 +02:00
ImageCropRatioMode ? ratioMode = null )
2021-06-28 09:28:32 +02:00
{
2021-08-10 11:23:37 +02:00
if ( mediaItem = = null )
{
throw new ArgumentNullException ( nameof ( mediaItem ) ) ;
}
2020-02-07 15:01:03 -08:00
if ( mediaItem . HasProperty ( propertyAlias ) = = false | | mediaItem . HasValue ( propertyAlias ) = = false )
2021-08-10 11:23:37 +02:00
{
return null ;
}
2020-02-07 15:01:03 -08:00
2020-08-04 14:12:22 +02:00
var mediaItemUrl = mediaItem . MediaUrl ( publishedUrlProvider , propertyAlias : propertyAlias ) ;
2020-02-07 15:01:03 -08:00
2021-06-28 09:28:32 +02:00
// Only get crops from media when required and used
if ( localCropsOnly = = false & & ( imageCropMode = = ImageCropMode . Crop | | imageCropMode = = null ) )
2020-02-07 15:01:03 -08:00
{
2021-06-28 09:28:32 +02:00
// Get the default cropper value from the value converter
2021-07-05 20:58:04 +02:00
var cropperValue = mediaItem . Value ( publishedValueFallback , propertyAlias ) ;
2020-02-07 15:01:03 -08:00
2021-06-28 09:28:32 +02:00
var mediaCrops = cropperValue as ImageCropperValue ;
if ( mediaCrops = = null & & cropperValue is JObject jobj )
{
mediaCrops = jobj . ToObject < ImageCropperValue > ( ) ;
}
if ( mediaCrops = = null & & cropperValue is string imageCropperValue & &
string . IsNullOrEmpty ( imageCropperValue ) = = false & & imageCropperValue . DetectIsJson ( ) )
{
mediaCrops = imageCropperValue . DeserializeImageCropperValue ( ) ;
}
// Merge crops
if ( localCrops = = null )
{
localCrops = mediaCrops ;
}
else if ( mediaCrops ! = null )
{
localCrops = localCrops . Merge ( mediaCrops ) ;
}
2020-02-07 15:01:03 -08:00
}
2021-08-10 11:23:37 +02:00
var cacheBusterValue = cacheBuster ? mediaItem . UpdateDate . ToFileTimeUtc ( ) . ToString ( CultureInfo . InvariantCulture ) : null ;
2020-02-07 15:01:03 -08:00
return GetCropUrl (
2021-06-28 09:28:32 +02:00
mediaItemUrl , imageUrlGenerator , localCrops , width , height , cropAlias , quality , imageCropMode , imageCropAnchor , preferFocalPoint , useCropDimensions ,
2021-08-10 11:23:37 +02:00
cacheBusterValue , furtherOptions , ratioMode ) ;
2020-02-07 15:01:03 -08:00
}
/// <summary>
2021-05-06 10:06:22 +02:00
/// Gets the underlying image processing service URL from the image path.
2020-02-07 15:01:03 -08:00
/// </summary>
2021-08-10 11:23:37 +02:00
/// <param name="imageUrl">The image URL.</param>
/// <param name="imageUrlGenerator">The image URL generator.</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 the underlying image processing service supports. For example:
/// <example><![CDATA[
2020-02-07 15:01:03 -08:00
/// furtherOptions: "&bgcolor=fff"
2021-08-10 11:23:37 +02:00
/// ]]></example></param>
/// <param name="ratioMode">Use a dimension as a ratio.</param>
2020-02-07 15:01:03 -08:00
/// <returns>
2021-08-10 11:23:37 +02:00
/// The URL of the cropped image.
2020-02-07 15:01:03 -08:00
/// </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 ,
2021-08-10 11:23:37 +02:00
ImageCropRatioMode ? ratioMode = null )
2020-02-07 15:01:03 -08:00
{
2021-08-10 11:23:37 +02:00
if ( string . IsNullOrWhiteSpace ( imageUrl ) )
{
return null ;
}
2020-02-07 15:01:03 -08:00
ImageCropperValue cropDataSet = null ;
if ( string . IsNullOrEmpty ( imageCropperValue ) = = false & & imageCropperValue . DetectIsJson ( ) & & ( imageCropMode = = ImageCropMode . Crop | | imageCropMode = = null ) )
{
cropDataSet = imageCropperValue . DeserializeImageCropperValue ( ) ;
}
2021-06-28 09:28:32 +02:00
2020-02-07 15:01:03 -08:00
return GetCropUrl (
imageUrl , imageUrlGenerator , cropDataSet , width , height , cropAlias , quality , imageCropMode ,
2021-08-10 11:23:37 +02:00
imageCropAnchor , preferFocalPoint , useCropDimensions , cacheBusterValue , furtherOptions , ratioMode ) ;
2020-02-07 15:01:03 -08:00
}
/// <summary>
2021-05-06 10:06:22 +02:00
/// Gets the underlying image processing service URL from the image path.
2020-02-07 15:01:03 -08:00
/// </summary>
2021-08-10 11:23:37 +02:00
/// <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">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[
2020-02-07 15:01:03 -08:00
/// furtherOptions: "&bgcolor=fff"
2021-08-10 11:23:37 +02:00
/// ]]></example></param>
/// <param name="ratioMode">Use a dimension as a ratio.</param>
2020-02-07 15:01:03 -08:00
/// <returns>
2021-08-10 11:23:37 +02:00
/// The URL of the cropped image.
2020-02-07 15:01:03 -08:00
/// </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 ,
2021-08-10 11:23:37 +02:00
ImageCropRatioMode ? ratioMode = null )
2020-02-07 15:01:03 -08:00
{
2021-08-10 11:23:37 +02:00
if ( string . IsNullOrWhiteSpace ( imageUrl ) )
{
return null ;
}
2020-02-07 15:01:03 -08:00
2020-02-08 11:05:14 -08:00
ImageUrlGenerationOptions options ;
if ( cropDataSet ! = null & & ( imageCropMode = = ImageCropMode . Crop | | imageCropMode = = null ) )
{
2021-08-11 17:18:23 +02:00
ImageCropperValue . ImageCropperCrop crop = cropDataSet . GetCrop ( cropAlias ) ;
2020-02-07 15:01:03 -08:00
2021-08-10 11:23:37 +02:00
// If a crop was specified, but not found, return null
2020-02-08 11:05:14 -08:00
if ( crop = = null & & ! string . IsNullOrWhiteSpace ( cropAlias ) )
2021-08-10 11:23:37 +02:00
{
2020-02-08 11:05:14 -08:00
return null ;
2021-08-10 11:23:37 +02:00
}
2020-02-07 15:01:03 -08:00
2021-08-10 13:36:50 +02:00
options = cropDataSet . GetCropBaseOptions ( imageUrl , crop , preferFocalPoint | | string . IsNullOrWhiteSpace ( cropAlias ) ) ;
2020-02-07 15:01:03 -08:00
2020-02-08 11:05:14 -08:00
if ( crop ! = null & useCropDimensions )
2020-02-07 15:01:03 -08:00
{
2020-02-08 11:05:14 -08:00
width = crop . Width ;
height = crop . Height ;
2020-02-07 15:01:03 -08:00
}
2021-08-09 15:52:55 +02:00
// Calculate missing dimension if a predefined crop has been specified, there are no coordinates and no ratio mode
if ( crop ! = null & & string . IsNullOrEmpty ( cropAlias ) = = false & & crop . Coordinates = = null & & ratioMode = = null )
2020-02-07 15:01:03 -08:00
{
2021-08-09 15:52:55 +02:00
if ( width ! = null & & height = = null )
{
height = ( int ) MathF . Round ( width . Value * ( ( float ) crop . Height / crop . Width ) ) ;
}
else if ( width = = null & & height ! = null )
{
width = ( int ) MathF . Round ( height . Value * ( ( float ) crop . Width / crop . Height ) ) ;
}
2020-02-07 15:01:03 -08:00
}
2020-02-08 11:05:14 -08:00
}
else
{
2021-08-10 11:23:37 +02:00
options = new ImageUrlGenerationOptions ( imageUrl )
2020-02-08 11:05:14 -08:00
{
2020-05-20 17:39:07 +02:00
ImageCropMode = ( imageCropMode ? ? ImageCropMode . Pad ) ,
ImageCropAnchor = imageCropAnchor
2020-02-08 11:05:14 -08:00
} ;
}
2020-02-07 15:01:03 -08:00
2020-02-08 11:05:14 -08:00
options . Quality = quality ;
options . Width = ratioMode ! = null & & ratioMode . Value = = ImageCropRatioMode . Width ? null : width ;
options . Height = ratioMode ! = null & & ratioMode . Value = = ImageCropRatioMode . Height ? null : height ;
2020-02-07 15:01:03 -08:00
2020-02-08 11:05:14 -08:00
if ( ratioMode = = ImageCropRatioMode . Width & & height ! = null )
{
2021-08-09 15:52:55 +02:00
// If only height specified then assume a square
if ( width = = null )
{
options . Width = height ;
}
else
{
options . Width = ( int ) MathF . Round ( height . Value * ( ( float ) width . Value / height . Value ) ) ;
}
2020-02-07 15:01:03 -08:00
}
2020-02-08 11:05:14 -08:00
if ( ratioMode = = ImageCropRatioMode . Height & & width ! = null )
{
2021-08-09 15:52:55 +02:00
// If only width specified then assume a square
if ( height = = null )
{
options . Height = width ;
}
else
{
options . Height = ( int ) MathF . Round ( width . Value * ( ( float ) height . Value / width . Value ) ) ;
}
2020-02-08 11:05:14 -08:00
}
options . FurtherOptions = furtherOptions ;
options . CacheBusterValue = cacheBusterValue ;
return imageUrlGenerator . GetImageUrl ( options ) ;
2020-02-07 15:01:03 -08:00
}
}
}