Skip to content

Instantly share code, notes, and snippets.

@JasonElkin
Last active November 8, 2021 17:37
Show Gist options
  • Save JasonElkin/0cfdf57d11ed90089cd4dc87acdb5b83 to your computer and use it in GitHub Desktop.
Save JasonElkin/0cfdf57d11ed90089cd4dc87acdb5b83 to your computer and use it in GitHub Desktop.
Basic srcset generator for ImageProcessor in Umbraco v8
using System.Collections.Specialized;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Web;
namespace MooseCoding.Web.UI
{
public static class ResponsiveImageHelper
{
// TODO: These will need to be optimised for the site's images, ideally based on real-world user/device data.
public static int[] Widths = { 320, 480, 640, 768, 1024, 1366, 1600, 1920, 2560, 3840 };
/// <summary>
/// Turn a crop URL into a srcset of multiple sizes for responsive image loading.
/// </summary>
/// <param name="cropUrl">The image URL, probably generated with <seealso cref="Umbraco.Web.ImageCropperTemplateExtensions.GetCropUrl"/></param>
/// <param name="maxWidth">Will not return image URLs larger than this, not strictly necessary but will cut down on HTML and cache use, if you set this remember to account for high-DPI!</param>
/// <returns></returns>
public static string GetSrcSet(string cropUrl, uint? maxWidth = null)
{
maxWidth = maxWidth ?? uint.MaxValue;
uint? height = null;
var urlParts = cropUrl.Split('?');
var queryParams = urlParts.Length == 2 ? HttpUtility.ParseQueryString(urlParts[1]) : new NameValueCollection();
_ = uint.TryParse(queryParams.Get("width"), out uint width);
if (uint.TryParse(queryParams.Get("height"), out uint parsedHeight))
{
height = parsedHeight;
}
if (decimal.TryParse(queryParams.Get("heightratio"), out decimal heightRatio))
{
height = (uint)(heightRatio * width);
}
// remove any predetermined sizes, we're going to recalculate
queryParams.Remove("width");
queryParams.Remove("height");
queryParams.Remove("heightratio");
var sb = new StringBuilder();
foreach (var w in Widths.Where(w => w < maxWidth))
{
sb.Append($"{urlParts[0]}?width={w}");
// If there's a height defined, crop to an aspect ratio.
// unless there's a crop set, as ImageProcessor will then determine the height as a %age of width
if (height.HasValue && queryParams.Get("crop") == null)
{
sb.AppendFormat(CultureInfo.InvariantCulture, "&heightratio={0}", height / (decimal)width);
}
// re-apply all other params
if (queryParams.Count > 0)
{
sb.Append($"&{queryParams}");
}
sb.Append($" {w}w, ");
}
sb.Remove(sb.Length - 2, 2);
return sb.ToString();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment