Monday, November 18, 2019

Uploading SVGs to the Media Library

There are a number of blog posts that cover the upload of SVG files into the Media Library. What I ran into was a little different, so I figured I would blog about it for future reference.

The issue was pertaining to the height and width of the uploaded asset and it not being the same as the actual size of the original media.

Below you'll find the code snippet that solves this issue for the situation I was dealing with. The code uses Svg Nuget package to read the structure of SVG XML and extract the width and height parameters either from the document size properties or from the properties of the Bounds one.


using System;
using Sitecore.Data.Items;
using Sitecore.Diagnostics;
using Sitecore.Resources.Media;
using Sitecore.SecurityModel;
using Svg;

namespace JCore.Foundation.SitecoreExtensions.Resources.Media
{
    public class SvgMedia : ImageMedia
    {
        /// clone.
        public override Sitecore.Resources.Media.Media Clone()
        {
            Assert.IsTrue(this.GetType() == typeof(SvgMedia), "The Clone() method must be overridden to support prototyping.");
            return new SvgMedia();
        }

        /// The update meta data. 
        /// The media stream.
        protected override void UpdateImageMetaData(MediaStream mediaStream)
        {
            var mediaItem = mediaStream?.MediaItem;
            if (mediaItem != null)
            {
                try
                {
                    SvgDocument document = SvgDocument.Open(mediaItem.GetMediaStream());
                    if (document != null)
                    {
                        using (new SecurityDisabler())
                        {
                            using (new EditContext(mediaItem))
                            {
                                mediaItem.InnerItem["Width"] = !document.Width.ToString().Contains("%") ? ((int)document.Width.Value).ToString() : ((int)document.Bounds.Width).ToString() ;
                                mediaItem.InnerItem["Height"] = !document.Height.ToString().Contains("%") ? ((int)document.Height.Value).ToString() : ((int)document.Bounds.Height).ToString();
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    Log.Error(ex.Message,ex, this);
                }
            }
        }
    }
}

And a config file:

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
      <medialibrary>
          <mediatypes>
              <mediatype extensions="svg" name="SVG image">
                  <prototypes>
                      <media type="Sitecore.Resources.Media.SvgMedia, Sitecore.Kernel">
                          <patch:delete>
                      </patch:delete></media>
                      <media type="JCore.Foundation.SitecoreExtensions.Resources.Media.SvgMedia, JCore.Foundation.SitecoreExtensions">
                  </media></prototypes>
              </mediatype>
          </mediatypes>
      </medialibrary>
  </sitecore>
</configuration>