Skip to content

Instantly share code, notes, and snippets.

@JimBobSquarePants
Created July 23, 2015 15:40
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save JimBobSquarePants/ed90a0f9b34cd14a3a2a to your computer and use it in GitHub Desktop.
Save JimBobSquarePants/ed90a0f9b34cd14a3a2a to your computer and use it in GitHub Desktop.
Demonstration code for Preprocessing uploaded images with Umbraco
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="ImageProcessorPreProcessor.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South.
// Licensed under the Apache License, Version 2.0.
// </copyright>
// <summary>
// Attaches ImageProcessor to the Media.Saving event to ensure that uploaded files do not exceed
// a maximum size.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace CodeGardenDemo.Events
{
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Web.Helpers;
using ImageProcessor;
using ImageProcessor.Imaging;
using Umbraco.Core;
using Umbraco.Core.Configuration;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Services;
/// <summary>
/// Attaches ImageProcessor to the Media.Saving event to ensure that uploaded files do not exceed
/// a maximum size.
/// </summary>
public class ImageProcessorPreProcessor : ApplicationEventHandler
{
/// <summary>
/// Overridable method to execute when All resolvers have been initialized but resolution is not
/// frozen so they can be modified in this method
/// </summary>
/// <param name="umbracoApplication">The current <see cref="UmbracoApplicationBase"/></param>
/// <param name="applicationContext">The Umbraco <see cref="ApplicationContext"/> for the current application.</param>
protected override void ApplicationStarting(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
{
const string UmbracoFile = Constants.Conventions.Media.File;
// Tap into the Saved event
MediaService.Saved += (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))
{
string path = media.GetValue<string>(UmbracoFile);
try
{
// Make sure it's not empty.
if (string.IsNullOrWhiteSpace(path))
{
return;
}
// This might happen after changing the data type of umbracoFile from
// Image Cropper back to Upload.
if (path.Contains("{"))
{
dynamic cropper = Json.Decode(path);
string src = cropper.Src;
if (!string.IsNullOrWhiteSpace(src))
{
path = src;
}
else
{
return;
}
}
// Make sure it's an image.
string extension = Path.GetExtension(path).Substring(1);
if (supportedTypes.InvariantContains(extension))
{
// Resize the image, height is driven by the
// aspect ratio of the image.
string fullPath = mediaFileSystem.GetFullPath(path);
using (ImageFactory imageFactory = new ImageFactory(true))
{
// Hardcoded at 1920 but could be configurable.
ResizeLayer layer = new ResizeLayer(new Size(1920, 0), ResizeMode.Max)
{
Upscale = false
};
// Resize
imageFactory.Load(fullPath).Resize(layer);
int newWidth = imageFactory.Image.Width;
int newHeight = imageFactory.Image.Height;
// Save
imageFactory.Save(fullPath);
FileInfo info = new FileInfo(fullPath);
long bytes = info.Length;
// Set the correct meta values for the image.
media.SetValue(Constants.Conventions.Media.Width, newWidth);
media.SetValue(Constants.Conventions.Media.Height, newHeight);
media.SetValue(Constants.Conventions.Media.Bytes, bytes);
sender.Save(media, 0, false);
}
}
}
catch (Exception ex)
{
// For all unexpected errors we get a hint in the log file.
LogHelper.Error<ImageProcessorPreProcessor>(
string.Format("Could not resize image. Path: {0}", path), ex);
}
}
}
};
}
}
}
@JimBobSquarePants
Copy link
Author

Note This needs splitting up into separate events to work correctly with Azure.

@TomSteer
Copy link

TomSteer commented Nov 23, 2017

@JimBobSquarePants Firstly thanks for sharing this 👍 I'm currently having an issue which is probably related to your comment above. I'm trying to use this along side your AzureBlobStorage file provider, however, it currently errors when trying to load/save the image using the ImageFactory. Do you have any pointers on what might need changing for it to work with blob storage? Cheers

@DmitryMorlender
Copy link

Hi, I'm having the same issue.. do you have any suggestions?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment