Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Kieron 152 posts 390 karma points
    Nov 13, 2018 @ 08:45
    Kieron
    0

    How to use .webp format with the image processor?

    Hi guys, using Umbraco 7.12.4 and using plenty of image processor stuff, but would really like to use the webp format tag, has anyone got this working?

  • Nik 1593 posts 7151 karma points MVP 6x c-trib
    Nov 13, 2018 @ 09:06
    Nik
    2

    Hi Kieron,

    I think you might have to install this Image Processor plugin in oder to get WebP format working:

    http://imageprocessor.org/imageprocessor/plugins/webp/

    Thanks

    Nik

  • Kieron 152 posts 390 karma points
    Nov 13, 2018 @ 11:56
    Kieron
    0

    Ive installed it onto the server using nuget but not sure what to do beyond that.

  • Jan Skovgaard 11280 posts 23678 karma points MVP 10x admin c-trib
    Nov 13, 2018 @ 12:46
    Jan Skovgaard
    5

    Hi Kieron

    If I'm not mistaken you should be able to use the "Format" setting to specify that you need to image in WebP format.

    So depending on how you render you images you should be able to do something like this

    <img src="@Url.GetCropUrl(Model.Content, propertyAlias: "image", cropAlias: "banner", useCropDimensions:true, furtherOptions: "&format=webp&quality=80")" />
    

    Please be aware that if you don't specify the quality parameter you might experience that the served images are in fact larger than if you just served the .jpg or .png versions of your image for instance.

    The above code snippet is a modified version of what you will find in the documentation here https://our.umbraco.com/Documentation/Getting-Started/Backoffice/Property-Editors/Built-in-Property-Editors/Image-Cropper#typed-umbraco-v735-4

    You can see a list of all the available methods here http://imageprocessor.org/imageprocessor-web/imageprocessingmodule/

    As you're probably aware currently only Chrome and Edge18 support webp and Firefox will probably get support in upcoming versions so you should of course consider serving jpg or png for those browsers that don't understand the webp format :-)

    I hope this helps :)

    /Jan

  • Kieron 152 posts 390 karma points
    Nov 13, 2018 @ 12:49
    Kieron
    0

    Hi Jan that's great thank you.

    I note now that even though I've 'installed' the Plugin on the server, I haven't dropped it into the correct location, I'm not familiar with nuget so had no idea it just installed it to my local downloads folder on the server, haha.

    Where does the Imageprocessor live within each Umbraco install, so that I can add the plugin?

  • Justin RW 17 posts 137 karma points
    Dec 28, 2018 @ 16:06
    Justin RW
    0

    Kieron, if you install the WebP plugin via NuGet it'll install it in the correct place.

    'format=webp' does output a webp image with the plugin installed but how do I get none supported browsers to load the non webp version of the image?

  • Søren Kottal 702 posts 4497 karma points MVP 5x c-trib
    Dec 28, 2018 @ 21:44
    Søren Kottal
    3

    Hi Justin

    To get browsers to fallback to jpg/png if they don't support webp, you need to use a <picture> element.

    You can use it like this:

    <picture>
      <source srcset="img/awesomeWebPImage.webp" type="image/webp">
      <source srcset="img/creakyOldJPEG.jpg" type="image/jpeg"> 
      <img src="img/creakyOldJPEG.jpg" alt="Alt Text!">
    </picture>
    

    The browser picks the first matching supported source, so in this case the webp image gets selected in Chrome/Firefox, and the jpg will be selected everywhere else.

    For browsers not supporting the picture element, the img element is shown instead.

    You can also polyfill support for <picture> using something like picturefill

  • James 23 posts 156 karma points
    Jan 22, 2019 @ 21:41
    James
    0

    I've been trying to get the working, have installed the webp plugin but nothing will work, it always returns the file in its original format.

    banner.BannerImage.GetCropUrl(cropAlias: cropAlias, furtherOptions: "&format=png&quality=80")
    
    banner.BannerImage.GetCropUrl(cropAlias: cropAlias, furtherOptions: "&format=webp&quality=80")
    

    both are returning jpeg, what could be wrong?

  • James 23 posts 156 karma points
    Jan 22, 2019 @ 22:06
    James
    1

    Ok i just figured out it says .jpeg but it's actually working you just cant tell from looking at the file extension but you can tell if you look at network or try to save the picture

  • David Armitage 505 posts 2073 karma points
    Jan 05, 2020 @ 07:30
    David Armitage
    0

    Hi Guys,

    I wrote an helper method to handle this.

    using System.Text;
    using System.Web;
    using Umbraco.Core.Models.PublishedContent;
    using Umbraco.Web;
    
    namespace CMS.Helpers
    {
        public class PropertyHelper
        {
            public static HtmlString GetWebPImageHtml(IPublishedContent image, string altText, string cropAlias = null)
            {
                try
                {
                    string imageUrl = image.Url;
                    string webpImageUrl = image.Url;
    
                    if (string.IsNullOrEmpty(cropAlias))
                    {
                        webpImageUrl = imageUrl + "?format=webp&amp;quality=80";
                    }
                    else
                    {
                        imageUrl = image.GetCropUrl(cropAlias: cropAlias);
                        webpImageUrl = image.GetCropUrl(cropAlias: cropAlias, furtherOptions: "&format=webp&quality=80");
                    }
    
                    StringBuilder html = new StringBuilder("<picture>");
                    html.Append("<source srcset='" + webpImageUrl + "' type='image/webp'>");
                    html.Append("<source srcset='" + imageUrl + "' type='image/jpeg'>");
                    html.Append("<img src='" + imageUrl + "' alt='" + altText + "'>");
                    html.Append("</picture>");
                    return new HtmlString(html.ToString());
                }
                catch
                {
                    return new HtmlString("<p>There was an error loading the image</p>");
                }
            }
        }
    }
    

    This supports with or without passing a cropAlias incase you just want full size images converting to WEBP.

    Use this code in the frontend to render the correct html.

    With a cropAlias.

     @PropertyHelper.GetWebPImageHtml(Model.Image,"SOME ALT TEXT HERE", "banner")
    

    Without a cropAlias

     @PropertyHelper.GetWebPImageHtml(Model.Image,"SOME ALT TEXT HERE",)
    

    Here is an example of the html it renders.

    <picture><source srcset="/media/ppzp2iig/homer-simpson.jpg?crop=0,0.055803571428571425,0.16294642857142866,0.66517857142857151&amp;cropmode=percentage&amp;format=webp&amp;quality=80&amp;rnd=132227046170000000" type="image/webp"><source srcset="/media/ppzp2iig/homer-simpson.jpg?crop=0,0.055803571428571425,0.16294642857142866,0.66517857142857151&amp;cropmode=percentage&amp;width=300&amp;height=100&amp;rnd=132227046170000000" type="image/jpeg"><img src="/media/ppzp2iig/homer-simpson.jpg?crop=0,0.055803571428571425,0.16294642857142866,0.66517857142857151&amp;cropmode=percentage&amp;width=300&amp;height=100&amp;rnd=132227046170000000" alt="SOME ALT TEXT HERE"></picture>
    

    I tested saving the image and it saves as a webp file.

    I also testing in multiple browsers to see if it works on browsers that don't support webp. It works fine in the browsers I tested.

  • David Armitage 505 posts 2073 karma points
    Jan 05, 2020 @ 08:46
    David Armitage
    1

    Hi,

    I improved the code slightly. Thought it was a good idea to include lazyloading in there as a bonus.

    public static HtmlString GetWebPImageHtml(IPublishedContent image, string altText, string cropAlias = null, bool lazyload = false)
            {
                try
                {
                    string imageUrl = image.Url;
                    string webpImageUrl = image.Url;
    
                    if (string.IsNullOrEmpty(cropAlias))
                    {
                        webpImageUrl = imageUrl + "?format=webp&amp;quality=80";
                    }
                    else
                    {
                        imageUrl = image.GetCropUrl(cropAlias: cropAlias);
                        webpImageUrl = image.GetCropUrl(cropAlias: cropAlias, furtherOptions: "&format=webp&quality=80");
                    }
    
                    StringBuilder html = new StringBuilder("<picture>");
    
                    if(lazyload)
                    {
                        html.Append("<source data-srcset='" + webpImageUrl + "' type='image/webp'>");
                        html.Append("<source data-srcset='" + imageUrl + "' type='image/jpeg'>");
                        html.Append("<img data-src='" + imageUrl + "' alt='" + altText + "' class='lazy'>");
                    }
                    else
                    {
                        html.Append("<source srcset='" + webpImageUrl + "' type='image/webp'>");
                        html.Append("<source srcset='" + imageUrl + "' type='image/jpeg'>");
                        html.Append("<img src='" + imageUrl + "' alt='" + altText + "'>");
                    }
    
                    html.Append("</picture>");
                    return new HtmlString(html.ToString());
                }
                catch
                {
                    return new HtmlString("<p>There was an error loading the image</p>");
                }
            }
    

    In the front-end render the images like this.

    Lazy Load

    @PropertyHelper.GetWebPImageHtml(Model.Image,"SOME ALT TEXT HERE", "banner", true)
    

    Normal Loading

    @PropertyHelper.GetWebPImageHtml(Model.Image,"SOME ALT TEXT HERE", "banner", false)
    

    There is one thing extra. If you want to use lazy loading then please include the following javascript on your master page.

     <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/lazyload.min.js"></script>
        <script>
            (function () {
                ll = new LazyLoad({
                    elements_selector: ".lazy"
                });
            })();
        </script>
    

    Hope this helps someone.

  • Thomas 315 posts 602 karma points c-trib
    Mar 11, 2020 @ 11:43
    Thomas
    1

    Hey,

    I have tried you code and I works.

    I just notes that if I check the "Network" and see what images that are loaded. Then I can see at the image where I use this method, the image has a size of 2.5mb...

  • Gerhard Grossberger 54 posts 178 karma points
    Apr 09, 2021 @ 17:50
    Gerhard Grossberger
    0

    Thanks for the writeup, works like a charm. For all those following here, don´t forget to add webp mime-type on IIS. Took me a few minutes to figure this out.

  • Piotr Bach 15 posts 129 karma points c-trib
    Jun 15, 2021 @ 06:52
    Piotr Bach
    3

    Hi, to enable webP format in Umbraco you need to:

    1. Install-Package ImageProcessor.Plugins.WebP
    2. Enable ImageProcessor's 'Format' feature in imageprocessor/processing.config (if it's not turned on)
    3. Set mimeMap (mimeType - image/webp) in web.config

    Works great for Umbraco 8 sites, should work for Umbraco 7 as well. I've covered the entire process here: https://piotrbach.com/enable-webp-image-format-in-umbraco-cms

    Best, Piotr

  • Eric Wilkinson 21 posts 91 karma points
    Jun 18, 2021 @ 17:29
    Eric Wilkinson
    0

    I want to also include that you can tie into the ImageProcessingModule.ValidatingRequest event, and check the URL, Request AcceptTypes header, and alter the QueryString all in an IApplicationEventHandler OnApplicationStarted

    This is covered for v7 and v8 (with reusable code) here: https://kieron.codes/blog/using-webp-images-in-umbraco/ (full credit to the code below!)

    The code there excludes .gif images, but you may also want to prevent .webp and .svg as well.

    v8:

     public class SubscribeToContentServiceSavingComposer : IUserComposer
    {
        public void Compose(Composition composition)
        {
            composition.Components().Append();
        }
    }
    
    public class SubscribeToContentServiceSavingComponent : Umbraco.Core.Composing.IComponent
    {
        public void Initialize()
        {
            ImageProcessingModule.ValidatingRequest += ImageProcessingModule_ValidatingRequest;
        }
    
        private void ImageProcessingModule_ValidatingRequest(object sender, ValidatingRequestEventArgs e)
        {
            if (!e.Context.Request.Url.AbsolutePath.EndsWith(".gif"))
            {
                var queryString = HttpUtility.ParseQueryString(e.QueryString);
                if (e.Context.Request.AcceptTypes != null && e.Context.Request.AcceptTypes.Contains("image/webp"))
                {
                    queryString.Remove("format");
                    queryString["format"] = "webp";
                    if (queryString.Get("quality") != null)
                    {
                        string quality = queryString["quality"];
                        queryString.Remove("quality");
                        queryString["quality"] = quality;
                    }
                }
                e.QueryString = queryString.ToString();
            }
        }
    
        public void Terminate()
        {
        }
    }
    

    v7:

    public void OnApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
        {
            ImageProcessingModule.ValidatingRequest += ImageProcessingModule_ValidatingRequest;
        }
    
    private void ImageProcessingModule_ValidatingRequest(object sender, ValidatingRequestEventArgs e)
        {
            if (!e.Context.Request.Url.AbsolutePath.EndsWith(".gif"))
            {
                var queryString = HttpUtility.ParseQueryString(e.QueryString);
                if (e.Context.Request.AcceptTypes != null && e.Context.Request.AcceptTypes.Contains("image/webp"))
                {
                    queryString.Remove("format");
                    queryString["format"] = "webp";
                    if (queryString.Get("quality") != null)
                    {
                        string quality = queryString["quality"];
                        queryString.Remove("quality");
                        queryString["quality"] = quality;
                    }
                }
                e.QueryString = queryString.ToString();
            }
        }
    
  • Osman Coskun 164 posts 398 karma points
    Jul 14, 2021 @ 15:34
    Osman Coskun
    1

    I noticed if i use format=webp after quality parameter it does not apply quality. When i use quality at the end it works.

  • Eric Wilkinson 21 posts 91 karma points
    Jul 14, 2021 @ 15:38
    Eric Wilkinson
    0

    Yes that is correct, you can use the above code, which removed the quality query string parameter and then appends it to the end automatically.

    ImageProcessingModule.ValidatingRequest += ImageProcessingModule_ValidatingRequest;

  • Mikael Axel Kleinwort 140 posts 484 karma points c-trib
    Jan 20, 2022 @ 09:25
    Mikael Axel Kleinwort
    0

    @Osman, thank you, this hint saved my day....

Please Sign in or register to post replies

Write your reply to:

Draft