Copied to clipboard

Flag this post as spam?

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


  • André Lange 108 posts 410 karma points
    Aug 21, 2019 @ 11:31
    André Lange
    0

    Umbraco 8 Preprocessing of images

    So on another of my sites which is an umbraco 7, i have an event that starts when i upload images, and then resizes them to max 1920px wide. Thereby saving me space, since i have no need for those large images.

    But on Umbraco 8, i have several issues, since Filesystemprovider and UmbracoConfig, i have no idea how to access.

    My code:

    public class Preprocessing : ApplicationEventHandler
    {
        protected override void ApplicationStarting(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
        {
            // Tap into the Saving event
            MediaService.Saving += (sender, args) =>
            {
                MediaFileSystem mediaFileSystem = FileSystemProviderManager.Current.GetFileSystemProvider<MediaFileSystem>();
                IContentSection contentSection = UmbracoConfig.For.UmbracoSettings().Content;
                IEnumerable<string> supportedTypes = contentSection.ImageFileTypes.ToList();
    
                foreach (IMedia media in args.SavedEntities)
                {
                    if (media.HasProperty("umbracoFile"))
                    {
                        //Make sure it's an image.
                        string path = media.GetValue<string>("umbracoFile");
                        string extension = Path.GetExtension(path).Substring(1);
                        if (supportedTypes.InvariantContains(extension))
                        {
                            //Resize the image to 1920px wide, height is driven by the aspect ratio of the image.
                            string fullPath = mediaFileSystem.GetFullPath(path);
                            using (ImageFactory imageFactory = new ImageFactory(true))
                            {
                                ResizeLayer layer = new ResizeLayer(new Size(1920, 0), ResizeMode.Max)
                                {
                                    Upscale = false
                                };
    
                                imageFactory.Load(fullPath)
                                                        .Resize(layer)
                                                        .Save(fullPath);
                            }
                        }
                    }
                }
            };
        }
    }
    

    I know i have to use the composer/component setup to get it started. But so far i am at a loss as to how i get this working.

    Any ideas ?

  • Marc Goodson 2157 posts 14431 karma points MVP 9x c-trib
    Aug 21, 2019 @ 20:17
    Marc Goodson
    101

    Hi André

    How about this?

    using ImageProcessor;
    using ImageProcessor.Imaging;
    using Newtonsoft.Json;
    using System;
    using System.Collections.Generic;
    using System.Drawing;
    using System.IO;
    using System.Linq;
    using System.Web;
    using Umbraco.Core;
    using Umbraco.Core.Composing;
    using Umbraco.Core.Configuration.UmbracoSettings;
    using Umbraco.Core.IO;
    using Umbraco.Core.Models;
    using Umbraco.Core.PropertyEditors.ValueConverters;
    using Umbraco.Core.Services;
    using Umbraco.Core.Services.Implement;
    
    namespace umbraco_8_1_release.Components
    {
        [RuntimeLevel(MinLevel = RuntimeLevel.Run)]
        public class ImagePreprocessingComposer : ComponentComposer<ImagePreprocessingComponent>
        {
        }
        public class ImagePreprocessingComponent : IComponent
        {
    
            private readonly IMediaFileSystem _mediaFileSystem;
            private readonly IContentSection _contentSection;
            public ImagePreprocessingComponent(IMediaFileSystem mediaFileSystem, IContentSection contentSection)
            {
                _mediaFileSystem = mediaFileSystem;
                _contentSection = contentSection;
            }
            public void Initialize()
            {
                MediaService.Saving += MediaService_Saving;
            }
    
            public void Terminate()
            {
    
            }
    
            private void MediaService_Saving(IMediaService sender, Umbraco.Core.Events.SaveEventArgs<Umbraco.Core.Models.IMedia> e)
            {
                IEnumerable<string> supportedTypes = _contentSection.ImageFileTypes.ToList();
                foreach (IMedia media in e.SavedEntities)
                {
                    if (media.HasProperty("umbracoFile"))
                    {
                        //Make sure it's an image.
                        string cropInfo = media.GetValue<string>("umbracoFile");
                        string path = JsonConvert.DeserializeObject<ImageCropperValue>(cropInfo).Src;
                        string extension = Path.GetExtension(path).Substring(1);
                        if (supportedTypes.InvariantContains(extension))
                        {
                            //Resize the image to 1920px wide, height is driven by the aspect ratio of the image.
                            string fullPath = _mediaFileSystem.GetFullPath(path);
                            using (ImageFactory imageFactory = new ImageFactory(true))
                            {
                                ResizeLayer layer = new ResizeLayer(new Size(1920, 0), ResizeMode.Max)
                                {
                                    Upscale = false
                                };
    
                                var image = imageFactory.Load(fullPath);
                                image.Resize(layer);
                                media.SetValue("umbracoWidth", image.Image.Width);
                                media.SetValue("umbracoHeight", image.Image.Height);
                                image.Save(fullPath);
    
                            }
                        }
                    }
                }
            }
        }
    }
    

    Essentially create a new class in your project, and create a Component to setup the handling of the MediaService saving event, when Umbraco is initialized and then you can get access to the MediaFileSystem and ContentSection configuration elements by adding them as arguments to the public constructor for your component...

    ... and then the code is pretty much the same as you had before...

    except if you are using ImageCropper as the UmbracoFile property will contain a blob of JSON instead of your file path...

    .. and you'll want to adjust the new height and width to be displayed in the backoffice...

    ... so that's sort of how to do the same thing in V8 ...

    Some documentation on composing here: https://our.umbraco.com/Documentation/Implementation/Composing/ and some examples of injection of services here: https://our.umbraco.com/Documentation/Implementation/Services/

    might be of use.

    regards

    Marc

  • André Lange 108 posts 410 karma points
    Aug 22, 2019 @ 06:53
    André Lange
    0

    Works great ^^

    Thx

Please Sign in or register to post replies

Write your reply to:

Draft