Url.GetCropUrl() Specifying a Width or Height AND a Crop Alias?
TL;DR;
Is it at all possible to combine the use of my predefined crops (which dictate aspect ratio and crop area of source image) whilst overriding the requested width or height. e.g. my predefined crop is a 1000x500px (so 2:1) selection of the source image, but what I also want is a smaller 500x250 (so still 2:1 still the same crop area) version of this same image.
From what I am seeing the cc URL param (which I can't see documented anywhere in ImageSharp.Web docs) overrules any width or height URL params and if excluding the cc param, there is no way of specifying your crop boundaries (so you get the source image as it was but resized down)?
Full Details:
I am working with Media Picker 3 in Umbraco 10 to allow for the upload/selection of a banner image for my sites header.
I am attempting to give consideration to desktop usage (where a landscape banner is needed) and mobile usage (where a square or portrait banner is needed). Obviously either of these, but more notable with the desktop version, will need to fill a range of widths depending on viewport width.
I have this part working using a couple of 'local crops' crop aliases (which I understand are stored per document the image is attached to, as opposed to global crops on the image itself). So, for example:
Url.GetCropUrl(bannerImage.LocalCrops, "portrait");
and
Url.GetCropUrl(bannerImage.LocalCrops, "landscape"); then I use these URLs in the background-image properties of some on-page CSS with a media query to manage mobile vs desktop BG selection.
I also want to make use of CSS background-image: image-set() in order to resample and serve more suitably sized background images based on device pixel density. For example, my landscape crop alias has to cater for a full width 16:9 image on a retina display, so is a 5120x2880px crop of the source image. This is massive and of course serving this to a 1x DPI laptop screen at 1024px wide is a massive waste, so I want to specify a smaller (say 2560x1440px) version of the same 'landscape' crop alias (where the 16:9 aspect ratio, and crop area is maintained, but both the source and output image are dealt with at the 50% size).
I would have thought that would be possible using code where the 9th and final param I pass to GetCropUrl is useCropDimensions = false like the below:
but despite the different and 'as expected' width/heights referenced in the URLs, these two URLs produce the exact same image, which seems to be my source image, at 16:9 and the correct section cropped, but at the source images original width (and calculated height based on 16:9 presumably) and disregards the width and height URL params entirely (So I assume the useCropDimensions = false setting means ignore width/height all together, as opposed to overload the predefined crop dimensions with the ones in the URL)
I have been doing this since "forever" (i.e. essentially using the crop definition for the aspect-ratio), so I'd say it's a bug if it's indeed giving you the same image, regardless of the width/height params.
However - and I'm not too familiar with the new engine (ImageSharp) but - I know that the one used in v7—v9 (ImageProcessor) did have some config options that could be affecting this (e.g. there's a way to prevent generating images above a maximum size and that could be the problem you're having, as your 2x image is quite large (4000+ px).
Could you maybe try generating a couple of smaller images (e.g. 500px and 1000px) and see what you get there?
I have parked this temporarily in favour of getting more of the core of this site developed, but I will try out some smaller resamples and also a smaller source image (in case it's over the limit it feels safe to load in for resampling) and see how it goes.
Reassuring to hear you've also used this technique before as well so I am at least not trying something illogical or unsupported.
Recently returned to try and resolve this one with a fresh head, unfortunately I still think this is a bug. Just looking to see if anyone has any final 'gotchas' and if not I will raise as a bug against Umbraco CMS via GitHub Issue Tracker.
Firstly, I was noticing some issues when testing with regards to the generated URL params being appended with HTML/URL encoded & as opposed to just &. I have a feeling this might have cause all or at least all but the first URL params from being processed correctly, just to rule this out I have set the final IUrlHelper.GetCropUrl() param to htmlEncode = false.
This has left me with my Media Picker configured to enable focal point and define two crop aliases of landscape (16:9) and portrait (9:16) with the width/heights defined being the largest I will ever need these images:
I then have 4x lines of code making use of GetCropUrl() using the LocalCrops defined on my banner image(s) selected for each page of my site e.g.:
Note that the 2x versions use the exact same width/heights defined in the crop definitions, the 1x are 50% of the crop definition values (so same orientation and aspect ratio, but half the size).
What I have found, is that this seems to work if and only if, I manually select a non-standard crop preset for each of my crop definitions e.g. opening the 'Landscape 16:9 (Max)' and 'Portrait 9:16 (Max)' presets and dragging the cropped area to anything but the default (even if just a couple of pixels off). I have exaggerated this to be top and right in the below:
In this case, I get the resized images back at both the aspect ratios and width/heights as expected.
However, if I either:
Leave the focal point in its default, centred, position and do not
adjust the crop presets at all; or
Manually update the focal point,
but leave the crop presets in their automatically adjusted position
based on this new focal point (e.g. without opening and dragging them
at all)
then in both cases my Landscape 16:9 @ 2x resized image fails to resize as requested and instead gives me a square 1:1 image where width and height are both 2880px (the height I requested has been used for both dimensions) e.g.:
I initially thought this might be related to an undocumented maximum resize value of 5000px, as my landscape 2x crop is the only one which breaches that size however, I am able to resize to 5120x2880px successfully as long as I manual select my crop preset (as I mention above), also, I have updated any references in appsettings.json I can find which references max width/height for image resizing, being:
Finally, as a bit of an aside, I also find it odd (presumably as per design, but seems wrong to me) that with my large 6000x6000px test image, I am not able to select a partial crop of say the centre of my source image for my 'Portrait 9:16 (Max)' crop alias. Instead, the entire 6000x6000px source image is resized down to the larger of the two crop definitions dimentions (in this case, height at 2560px) and then I can select the slither of this I want e.g.:
Any support or suggestions welcomed. At the moment I am left telling my users "Make sure you manually select a crop preset, even if that's just dragging the default 1px left/right or up/down" which is just going to be forgotten/ignored
Url.GetCropUrl() Specifying a Width or Height AND a Crop Alias?
TL;DR;
Is it at all possible to combine the use of my predefined crops (which dictate aspect ratio and crop area of source image) whilst overriding the requested width or height. e.g. my predefined crop is a 1000x500px (so 2:1) selection of the source image, but what I also want is a smaller 500x250 (so still 2:1 still the same crop area) version of this same image.
From what I am seeing the
cc
URL param (which I can't see documented anywhere in ImageSharp.Web docs) overrules anywidth
orheight
URL params and if excluding thecc
param, there is no way of specifying your crop boundaries (so you get the source image as it was but resized down)?Full Details:
I am working with Media Picker 3 in Umbraco 10 to allow for the upload/selection of a banner image for my sites header.
I am attempting to give consideration to desktop usage (where a landscape banner is needed) and mobile usage (where a square or portrait banner is needed). Obviously either of these, but more notable with the desktop version, will need to fill a range of widths depending on viewport width.
I have this part working using a couple of 'local crops' crop aliases (which I understand are stored per document the image is attached to, as opposed to global crops on the image itself). So, for example:
Url.GetCropUrl(bannerImage.LocalCrops, "portrait");
andUrl.GetCropUrl(bannerImage.LocalCrops, "landscape");
then I use these URLs in thebackground-image
properties of some on-page CSS with a media query to manage mobile vs desktop BG selection.I also want to make use of CSS
background-image: image-set()
in order to resample and serve more suitably sized background images based on device pixel density. For example, my landscape crop alias has to cater for a full width 16:9 image on a retina display, so is a 5120x2880px crop of the source image. This is massive and of course serving this to a 1x DPI laptop screen at 1024px wide is a massive waste, so I want to specify a smaller (say 2560x1440px) version of the same 'landscape' crop alias (where the 16:9 aspect ratio, and crop area is maintained, but both the source and output image are dealt with at the 50% size).I would have thought that would be possible using code where the 9th and final param I pass to GetCropUrl is
useCropDimensions = false
like the below:1x DPI Version:
bannerImageUrlLandscape1x = Url.GetCropUrl(bannerImage.LocalCrops, "landscape", 2560, 1440 80, null, null, false, false).ToString();
Which outputs: https://localhost:44362/media/evijrul4/alexandre-debieve-fo7jilwjotu-unsplash.jpg?cc=0,0,0,0.15709459459459466&width=2560&height=1440&quality=80
2x DPI Version:
bannerImageUrlLandscape2x = Url.GetCropUrl(bannerImage.LocalCrops, "landscape", 5120, 2880, 80, null, null, false, false).ToString();
Which outputs: https://localhost:44362/media/evijrul4/alexandre-debieve-fo7jilwjotu-unsplash.jpg?cc=0,0,0,0.15709459459459466&width=5120&height=2880&quality=80
but despite the different and 'as expected' width/heights referenced in the URLs, these two URLs produce the exact same image, which seems to be my source image, at 16:9 and the correct section cropped, but at the source images original width (and calculated height based on 16:9 presumably) and disregards the
width
andheight
URL params entirely (So I assume theuseCropDimensions = false
setting means ignore width/height all together, as opposed to overload the predefined crop dimensions with the ones in the URL)Hi Joe,
I have been doing this since "forever" (i.e. essentially using the crop definition for the aspect-ratio), so I'd say it's a bug if it's indeed giving you the same image, regardless of the width/height params.
However - and I'm not too familiar with the new engine (ImageSharp) but - I know that the one used in v7—v9 (ImageProcessor) did have some config options that could be affecting this (e.g. there's a way to prevent generating images above a maximum size and that could be the problem you're having, as your 2x image is quite large (4000+ px).
Could you maybe try generating a couple of smaller images (e.g. 500px and 1000px) and see what you get there?
Otherwise, I'd suggest you log an issue on the issue tracker on GitHub.
/Chriztian
Thank you Chriztian,
I have parked this temporarily in favour of getting more of the core of this site developed, but I will try out some smaller resamples and also a smaller source image (in case it's over the limit it feels safe to load in for resampling) and see how it goes.
Reassuring to hear you've also used this technique before as well so I am at least not trying something illogical or unsupported.
Cheers,
Joe
Recently returned to try and resolve this one with a fresh head, unfortunately I still think this is a bug. Just looking to see if anyone has any final 'gotchas' and if not I will raise as a bug against Umbraco CMS via GitHub Issue Tracker.
Firstly, I was noticing some issues when testing with regards to the generated URL params being appended with HTML/URL encoded
&
as opposed to just&
. I have a feeling this might have cause all or at least all but the first URL params from being processed correctly, just to rule this out I have set the finalIUrlHelper.GetCropUrl()
param tohtmlEncode = false
.This has left me with my Media Picker configured to enable focal point and define two crop aliases of landscape (16:9) and portrait (9:16) with the width/heights defined being the largest I will ever need these images:
I then have 4x lines of code making use of
GetCropUrl()
using theLocalCrops
defined on my banner image(s) selected for each page of my site e.g.:Note that the 2x versions use the exact same width/heights defined in the crop definitions, the 1x are 50% of the crop definition values (so same orientation and aspect ratio, but half the size).
What I have found, is that this seems to work if and only if, I manually select a non-standard crop preset for each of my crop definitions e.g. opening the 'Landscape 16:9 (Max)' and 'Portrait 9:16 (Max)' presets and dragging the cropped area to anything but the default (even if just a couple of pixels off). I have exaggerated this to be top and right in the below:
In this case, I get the resized images back at both the aspect ratios and width/heights as expected.
However, if I either:
then in both cases my Landscape 16:9 @ 2x resized image fails to resize as requested and instead gives me a square 1:1 image where width and height are both 2880px (the height I requested has been used for both dimensions) e.g.:
Landscape DPI 2x: https://localhost:54302/media/2s4bjzid/6000x6000-banner-test.jpeg?width=5120&height=2880
Returned Dimensions: 2880 x 2880px
Outcome: Ignored specified width and aspect ratio (infered from cropAlias) and made square using specified height for both dimension
Landscape DPI 1x: https://localhost:54302/media/2s4bjzid/6000x6000-banner-test.jpeg?width=2560&height=1440
Returned Dimensions: 2560 x 1440px
Outcome: As expected
Portrait DPI 2x: https://localhost:54302/media/2s4bjzid/6000x6000-banner-test.jpeg?width=1440&height=2560
Returned Dimensions: 1440 x 2560px (correct)
Outcome: As expected
Portrait DPI 1x: https://localhost:54302/media/2s4bjzid/6000x6000-banner-test.jpeg?width=720&height=1280
Returned Dimensions: 720 x 1280px (correct)
Outcome: As expected
I initially thought this might be related to an undocumented maximum resize value of 5000px, as my landscape 2x crop is the only one which breaches that size however, I am able to resize to 5120x2880px successfully as long as I manual select my crop preset (as I mention above), also, I have updated any references in appsettings.json I can find which references max width/height for image resizing, being:
I'm not sure if there are others?
Finally, as a bit of an aside, I also find it odd (presumably as per design, but seems wrong to me) that with my large 6000x6000px test image, I am not able to select a partial crop of say the centre of my source image for my 'Portrait 9:16 (Max)' crop alias. Instead, the entire 6000x6000px source image is resized down to the larger of the two crop definitions dimentions (in this case, height at 2560px) and then I can select the slither of this I want e.g.:
Any support or suggestions welcomed. At the moment I am left telling my users "Make sure you manually select a crop preset, even if that's just dragging the default 1px left/right or up/down" which is just going to be forgotten/ignored
is working on a reply...