30
Mar
2016

Storing your thumbnails in the correct mime type

By default Episerver stores you thumbnails, or any image you store using an ImageDescriptor attribute, as a .png file. This is hard coded in the ThumbnailManager and there probably are good reasons for this.
But maybe you want to store your thumbnails in the same type as the original image

To to this we have to replace some methods of the thumbnail manager.

In the container configuration of your dependency resolver replace the ThumbnailManager by you own implementation

private static void ConfigureContainer(ConfigurationExpression container)
{
    //Swap out the default ThumbnailManager for our custom
    container.For<ThumbnailManager>().Use<MyThumbnailManager>();
}

The remove the hard coded .png mime type we overide the CreateImageBlob method.

public class MyThumbnailManager : ThumbnailManager
{
    public MyThumbnailManager(IContentRepository contentRepository, BlobFactory blobFactory, BlobResolver blobResolver) 
        : base(contentRepository, blobFactory, blobResolver)
    {
    }

    public override Blob CreateImageBlob(Blob sourceBlob, string propertyName, ImageDescriptorAttribute descriptorAttribute)
    {
        Validator.ThrowIfNull("sourceBlob", sourceBlob);
        Validator.ThrowIfNullOrEmpty("propertyName", propertyName);
        Validator.ThrowIfNull("descriptorAttribute", descriptorAttribute);
        return CreateBlob(CreateNewThumbnailUri(sourceBlob, propertyName), sourceBlob,descriptorAttribute. Width, descriptorAttribute.Height);
    }
    
    public static Uri CreateNewThumbnailUri(Blob sourceBlob, string propertyName)
    {
        string id = Blob.GetContainerIdentifier(sourceBlob.ID).ToString();
        string fileName = Path.GetFileNameWithoutExtension(sourceBlob.ID.LocalPath);
        string extension = Path.GetExtension(sourceBlob.ID.LocalPath); ;
        return new Uri(string.Format("{0}{1}_{2}{3}", id, fileName, propertyName, extension));
    }
}

Unfortunately we cannot override the CreateThumbnailUri from ThumbnailManager, so we create our own method for generating the correct Uri.
Although our thumbnails are now stored in the correct mime type, the filename stored in the database still has the extension .png.
To resolve this we have to set the right blobs in our Media object. This can be done by subscribing to some events.

[InitializableModule]
[ModuleDependency(typeof(EPiServer.Web.InitializationModule))]
public class ThumbnailInitialization : IInitializableModule
{
    private BlobResolver _blobResolver;
    private BlobFactory _blobFactory;

    public void Initialize(InitializationEngine context)
    {
        DataFactory.Instance.CreatingContent += AssignThumbnailBlob;
        DataFactory.Instance.SavingContent += AssignThumbnailBlob;
        _blobResolver = context.Locate.Advanced.GetInstance<BlobResolver>();
        _blobFactory = context.Locate.Advanced.GetInstance<BlobFactory>();
    }

    private void AssignThumbnailBlob(object sender, ContentEventArgs contentEventArgs)
    {
        var media = contentEventArgs.Content as MediaData;
            
        if (media == null || media.BinaryData == null || media.Thumbnail == null) return;

        _blobResolver.SetBlob(_blobFactory.GetBlob(MyThumbnailManager.CreateNewThumbnailUri(media.BinaryData, "Thumbnail")), media, "Thumbnail");
    }

    public void Uninitialize(InitializationEngine context)
    {
        //Add uninitialization logic
    }
}

Our images are now stored in the correct mime type and we can also see the thumbnail correctly in the UI.
A disadvantage of storing the images in the same type as the original is that we might lose transparency in our thumbnails. For example when using .jpg file, where we will end up with white borders.

A little disclaimer: This in not production ready code. It was just a quick and dirty test to see if it was possible.

 

Share

You may also like...