Preprocessing in Umbraco

I added this bit of code to handle a slight worry i had, because in the group (union or “forening”), a lot of high quality images tended to be uploaded, 10+mb images. So to combat this, i added this component, to cut images down to a HD format. 1920 wide max.

This way it would be easier for an editor to upload images, and conserve space on the drive. So instead of having multiple gigabytes, it got slimmed down to less than one gigabyte.

It was simply the way i thought it would be easiest to handle image sizes, without having to use an external service, which could become much more expensive.

public class ImagePreprocessingComponent : IComponent
    {
        private readonly IMediaFileSystem _mediaFileSystem;
        private readonly IContentSection _contentSection;
        private readonly int ImageWidth = 1920;
        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");
                    if (!cropInfo.EndsWith(".pdf"))
                    {
                        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(ImageWidth, 0), ResizeMode.Max)
                                {
                                    Upscale = false
                                };

                                var image = imageFactory.Load(fullPath);
                                // Only manipulate the image if it is larger than 1920px wide. 
                                if (image.Image.Width > ImageWidth)
                                {
                                    image.Resize(layer);
                                    media.SetValue("umbracoWidth", image.Image.Width);
                                    media.SetValue("umbracoHeight", image.Image.Height);
                                    image.Save(fullPath);
                                }
                            }
                        }
                    }
                }
            }
        }
    }

And of course since it is a Component, i need to register it in my Composer.

public class SystemComposer : IUserComposer
    {
        public void Compose(Composition composition)
        {
          composition.Components().Append<ImagePreprocessingComponent>();
                   
            composition.RegisterAuto<IInjected>(); // So any classes that implement IInjected, will be added.
        }
    }

Leave a Reply

Your email address will not be published. Required fields are marked *