Copied to clipboard

Flag this post as spam?

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


  • Asembli 81 posts 255 karma points
    Apr 03, 2023 @ 08:59
    Asembli
    0

    Practical example modifying content/images before saving - backend

    Hi,

    We are doing upgrades from v7 to v11. Unfortunately, we mostly have custom apps that helpfully intercept content before saving and modify it (of course in backend and yes, that turned out fine and we'd like to keep it). So I'm wondering if anyone already has a working example for:

    • I want to programmatically change the data (node properties eg. node name or some simple properties -> textstring, numeric, t/f...) before saving it (now we solve this with the following handlers: ContentService.Saving, ContentService.Publishing)

    • I want to programmatically change the dimensions and type of the image before saving (we have now solved this with the following handler MediaService.Saved += (sender, args)) and we do not using backend cropper etc.

    That I would like to do it at this (saving, publishing) stage and not later at rendering!

    I know that Composer and Notifications should be used, but somehow I can't do it (I'm still learning core and U11 :)). I followed the instructions in the documentation. There are only rudiments, but not concrete solutions to follow. In particular, I can't find how to manipulate images from code with ImageSharp before saving.

    If anyone has a piece of code (with last command to save content) that would come in handy, I would be very grateful.

    Regards

  • Asembli 81 posts 255 karma points
    Apr 26, 2023 @ 19:30
    Asembli
    103

    I will answer to myself. I am also attaching the code if anyone ever needs it. If the website is a 'website' and not a DMS (if they are doing a DMS then they should zip them and deliver them as an link attachment) then it is not necessary to make the images larger than the maximum size for the screen. They are usually smaller! Our editors like to upload huge amounts of images, but they never use them. That's why I have a handler that, when uploading, reduces extremely large images to the appropriate size and at the same time converts them to webp format. And so this handler:

    public class MediaSavingNotificationHandler : INotificationHandler<MediaSavingNotification>
    {
        private readonly IMediaService _mediaService;
        private readonly MediaFileManager _mediaFileManager;
    
        public MediaSavingNotificationHandler(
            IMediaService mediaService,
            MediaFileManager mediaFileManager
        )
        {
            _mediaService = mediaService;
            _mediaFileManager = mediaFileManager;
        }
    
        public void Handle(MediaSavingNotification notification)
        {
            foreach (var mediaItem in notification.SavedEntities)
            {
                if (mediaItem.ContentType.Alias.Equals("Image"))
                {
                    if (!mediaItem.HasIdentity)
                    {
                        string filePath = string.Empty;
    
                        using (Stream stream = _mediaFileManager.GetFile(mediaItem, out string mediaFilePath))
                        {
                            filePath = _mediaFileManager.FileSystem.GetFullPath(mediaFilePath);
                        }
    
                        using (Image img = Image.Load(filePath))
                        {
                            // only if image is larger
                            if (img.Width > 2560 || img.Height > 2560)
                            {
                                img.Mutate(x =>
                                    x.Resize(
                                        new ResizeOptions()
                                        {
                                            Mode = ResizeMode.Max,
                                            Size = new Size(2560, 2560)
                                        }
                                    )
                                );
                                img.SaveAsWebp(filePath);
    
                                // get file info
                                FileInfo fi = new FileInfo(filePath);
    
                                // set new values
                                mediaItem.SetValue(Constants.Conventions.Media.Width, img.Width);
                                mediaItem.SetValue(Constants.Conventions.Media.Height, img.Height);
                                mediaItem.SetValue(Constants.Conventions.Media.Bytes, fi.Length);
                            }
                        };
                    }
                }
            }
        }
    }
    

    First, I had a problem because I was additionally calling

    mediaService.Save(mediaItem);
    

    which is redundant here

    Regards

  • Ian McNeish 4 posts 74 karma points
    Jul 26, 2023 @ 14:54
    Ian McNeish
    0

    Thanks for the code you're using here - I've stumbled upon this as I'm now facing the same issue.

    What other libraries are you using please ? Specifically for Image, Mutate(), Resize() etc.

    Thanks

  • Asembli 81 posts 255 karma points
    Aug 07, 2023 @ 07:40
    Asembli
    0

    Hi,

    Absolutely nothing special - everything is original Umbraco and what comes with it. I already went into it with this premise - that I will not use any additional or 3rd party stuff, because that only complicates the matter.

    Here are all namespaces for this function

    using SixLabors.ImageSharp;
    using SixLabors.ImageSharp.Processing;
    using Umbraco.Cms.Core;
    using Umbraco.Cms.Core.Events;
    using Umbraco.Cms.Core.IO;
    using Umbraco.Cms.Core.Notifications;
    using Umbraco.Cms.Core.Services;
    

    Regards

Please Sign in or register to post replies

Write your reply to:

Draft