Copied to clipboard

Flag this post as spam?

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


  • Jon R. Humphrey 164 posts 455 karma points c-trib
    Feb 01, 2016 @ 14:27
    Jon R. Humphrey
    0

    Changing Media Image Type and using ImageProcessor with external images

    Hey all,

    Two questions for everyone:

    1. I'm trying to pass an image processor crop to an external image as per the usage examples on the ImageProcessor Site but it doesn't seem to be working?
      • I'm able to use the ".GetCropUrl" perfectly on internal images thanks to the manual change to the Media Type I've put in place based on the examples here and here [Thanks Jan!]

    var thumbnail = (thumb.Id == null) ? string.Format("{0}{1}",thumb.Url, "?crop=0,0,400,250") : Umbraco.TypedMedia((int)thumb.Id).GetCropUrl(400, 250);

    1. In the kit I'm developing I now need to ensure this Media Type change is actually set on install of the kit and wondered if anyone could point me in the right direction to be able to do this via events and which one?
  • Jeavon Leopold 3072 posts 13628 karma points MVP 10x admin c-trib
    Feb 01, 2016 @ 19:10
    Jeavon Leopold
    0

    Hi Jon,

    What do you mean by "media type", format, jpg, png etc...?

    Jeavon

  • Jon R. Humphrey 164 posts 455 karma points c-trib
    Feb 01, 2016 @ 19:34
    Jon R. Humphrey
    0

    Jeavon, Thanks for responding, time is running out for development and I'm hoping to sort this out tonight!

    In response, I've changed the standard media image type umbracoFile property to use the image cropper instead of upload data type so the kit can benefit from the power as shown in the links in my op. 😎 As I had to do this manually I wasn't sure if the change would be packaged up In the kit for distribution and want to ensure that this is able to be done or think of something else.😖 As I can't see anywhere to choose the modified media type in the package creation process so wondered if it could be done in code? 🤔

    Does that help clarify things? Cheers, J

  • Jeavon Leopold 3072 posts 13628 karma points MVP 10x admin c-trib
    Feb 01, 2016 @ 19:38
    Jeavon Leopold
    0

    Ok, so you want to create a package which when installed checks the default "Image" media type to see if the umbracoFile property is a Cropper or a Upload type and if it's a Upload type convert it to a Cropper (likely creating a Cropper data type first)?

  • Jon R. Humphrey 164 posts 455 karma points c-trib
    Feb 01, 2016 @ 19:58
    Jon R. Humphrey
    0

    That's the ticket!! As I said I've done all the code in my instance but need it to be part of the package install?

    I just need to see an example or link for a package install event and how to check media type properties then eh?

  • Jeavon Leopold 3072 posts 13628 karma points MVP 10x admin c-trib
    Feb 01, 2016 @ 20:17
    Jeavon Leopold
    0

    The good news it that it can be done using a Package Action, however I can't find much documentation at the moment. Here is a example which used to execute XDT files on config file. It is then referenced in the package.xml shipped with the package here.

    Once you have a package action executing you will need to use the ContentTypeType (for MediaTypes) & DataType Services to do the checking/modification described.

  • Jon R. Humphrey 164 posts 455 karma points c-trib
    Feb 01, 2016 @ 20:51
    Jon R. Humphrey
    0

    Thank you Jeavon! Sorry for the delay, had to read to the kids! I'm on my way back to my office now and will read up and sort this out!

    h5yr!

  • Jeavon Leopold 3072 posts 13628 karma points MVP 10x admin c-trib
    Feb 01, 2016 @ 20:54
    Jeavon Leopold
    0

    No problem, what does your package contain aside from switching Upload to Cropper?

  • Jon R. Humphrey 164 posts 455 karma points c-trib
    Feb 01, 2016 @ 22:06
    Jon R. Humphrey
    0

    Thanks Jeavon,

    First, I've been in to check the links now, and thankfully I'm already using a package actions for the kit which checks to make sure the default content is added and/or reloads the content tree:

     public bool Execute(string packageName, XmlNode xmlData)
    {
      var contentService = ApplicationContext.Current.Services.ContentService;
    
      try
      {
        var homeNode = contentService.GetRootContent().FirstOrDefault();
        if (homeNode == null  || !contentService.HasPublishedVersion(homeNode.Id))
        {
          contentService.PublishWithChildrenWithStatus(homeNode);
          LogHelper.Info<NgUskInstaller>("INSTALLER: Home Node and children were just added to the site");
        }
        else
        {
          contentService.RePublishAll();
          contentService.RebuildXmlStructures();
          LogHelper.Info<NgUskInstaller>("INSTALLER: Home Node and children were just refreshed and the xml tree was rebuilt");
        }
    
        return true;
      }
      catch (Exception exception)
      {
        LogHelper.Error<NgUskInstaller>("INSTALLER: Error at execute NgUskInstaller package action", exception);
    
        return false;
      }
    }
    

    I now need to work out where to add this into there; I've not used the data service so this should be fun!

    Second, did you have any thoughts on the Image cropper issue I mentioned with external images?

    @{
      var latestNews = Model.Content.AncestorOrSelf(1).Children.Where(x => x.ContentType.Alias.InvariantEquals("NG_USK_LatestNews"));
      var articles = latestNews.DescendantsOrSelf("NG_USK_NewsArticle").OrderBy("SortOrder desc").Take(3);
    }
    <ul class="listing clearfix">
      @foreach (var article in articles)
      {
        var alt = (article.Id % 2 == 0) ? "even" : "odd";
        <li class="listing--item @alt">
          @if (article.HasValue("NG_USK_HeroBannerImage") && article.GetPropertyValue<string>("NG_USK_HeroBannerImage") != string.Empty)
          {
            var thumbnailPicker = article.GetPropertyValue<MultiUrls>("NG_USK_HeroBannerImage");
            if (thumbnailPicker.Any())
            {
              foreach (var thumb in thumbnailPicker)
              {
                <figure class="widescreen">
                  <!-- feature image -->
                  <a href="@article.Url">
                    @{
                      var thumbnail = (thumb.Id == null) ? string.Format("{0}{1}",thumb.Url, "?crop=0,0,400,250") : Umbraco.TypedMedia((int)thumb.Id).GetCropUrl(400, 250);
                    }
                    <img src="@thumbnail" alt="@thumb.Name" />
                  </a>
                </figure>
              <!-- /feature image -->
              }
            }
          }
          @if (!string.IsNullOrEmpty(article.Name))
          {
            <h3>@article.Name</h3>
          }
          @if (article.HasValue("NG_NEWS__ArticleExcerpt") && article.GetPropertyValue<string>("NG_NEWS__ArticleExcerpt") != string.Empty)
          {
            @Html.Raw(HttpUtility.HtmlDecode(@article.GetProperty("NG_NEWS__ArticleExcerpt").Value.NullSafeToString()).Truncate(250))
          }
          else
          {
            if (article.HasValue("NG_NEWS__ArticleContents") && article.GetPropertyValue<string>("NG_NEWS__ArticleContents") != string.Empty)
            {
              @Html.Raw(HttpUtility.HtmlDecode(@article.GetProperty("NG_NEWS__ArticleContents").Value.NullSafeToString()).Truncate(250))
            }
          }
          <a class="listing--link" href="@article.Url">Read More</a>
        </li>
      }
    </ul>
    

    I've watched your uHangout ep30 and probably missed it but I've followed the examples on the ImageProcessor website but the "external" thumbnail is still the "bigger" image squashed into the space?

    J

  • James Jackson-South 489 posts 1747 karma points c-trib
    Feb 02, 2016 @ 03:16
    James Jackson-South
    0

    Hey Jon,

    I see you and Jeavon have been busy so I'll attempt to answer the non-ish-umbraco part.

    As far as I'm aware .GetCropUrl() only works with IPublishedContent referencing a media item.

    By external images do you mean images outwith the domain? i.e ones that should be prefixed with remote.axd? The method will not work out of the box with those at all.

    If you mean images stored on a cloud service like Azure you will need to use an IFileSystem implementation that stores the relative path for the method to work.

    Hope that helps.

    James

  • Jon R. Humphrey 164 posts 455 karma points c-trib
    Feb 02, 2016 @ 09:40
    Jon R. Humphrey
    0

    James,

    The .GetCropUrl does work fine with the local IPublishedContent, by remote I mean hosted on another site as my client has many satellite branches and they share media.

    So in the example code above we're using the RJP MultiUrlPicker to be able to link to the satellite site content, however passing in the http://www.external.url/path/to/remote/image?crop=top,left,width,height query string as per the "pixel" example on the imageprocessor.org site isn't cropping the image at all; neither is the www.external.url/path/to/remote/image?crop=left,top,right,bottom&cropmode=percentage percentage example?

    Also, out of curiosity, with either of the linked examples quoted above, can the position points be percentages? For example: http://www.external.url/path/to/remote/image?crop=40%,25%,width,height

    Thanks for the help! :-D

  • Jeavon Leopold 3072 posts 13628 karma points MVP 10x admin c-trib
    Feb 02, 2016 @ 10:19
    Jeavon Leopold
    0

    Unless your remote server also happens to have ImageProcessor installed I think you are after the Remote Files feature.

    e.g. /remote.axd/www.external.url/path/to/remote/image?crop=left,top,right,bottom&cropmode=percentage

    Umbraco GetCropUrl uses percentage mode cropping so you would need to add cropmode=percentage as I have done in the example above if you want it to crop the external image in a similar way. See the crop documentation for more info

  • Jon R. Humphrey 164 posts 455 karma points c-trib
    Feb 02, 2016 @ 11:21
    Jon R. Humphrey
    0

    Thanks Jeavon,

    I'm guessing then somehow I'll need to be able to add a url "whitelist" to the services.service.whitelist section in the security config to be able to link to said remote images? I'll discuss this with the client then.

    With the Media Type change I've ended up with the following method in my StarterKitInstaller.cs code:

    public static bool ChangeImageMediaType()
    {
      var success = false;
      try
      {
    
        var contentTypeService = ApplicationContext.Current.Services.ContentTypeService;
        var dataTypeService = ApplicationContext.Current.Services.DataTypeService;
        var mediaService = ApplicationContext.Current.Services.MediaService;
    
        //Given a `DataTypeService` object get the DataType by propertyEditorAlias
        var generalCropper = dataTypeService.GetDataTypeDefinitionByPropertyEditorAlias("Umbraco.ImageCropper");
        //Given a 'ContentTypeService' object get the MediaType that we're changing,
        var mediaImageType = contentTypeService.GetMediaType("Image");
        //Given a `MediaService` object get MediaType by its Id, 
        var mediaImage = mediaService.GetById(mediaImageType.Id);
        //Set the value of the propertyTypeAlias to the new dataType
        mediaImage.SetValue("umbracoFile", generalCropper);
        //and saves the Media through the `MediaService`
        mediaService.Save(mediaImage);
        LogHelper.Info<NgUskInstaller>("INSTALLER: Updating Image Media Type to use Image Cropper succeeded!");
        success = true;
      }
      catch (Exception exception)
      {
        success = false;
        LogHelper.Error<NgUskInstaller>("INSTALLER: USK installation failed. An issue occured updating Image Media Type to use Image Cropper.", exception);
      }
      return success;
    }
    

    But I need to set up a new instance to test this and will report back! :-D

  • Jeavon Leopold 3072 posts 13628 karma points MVP 10x admin c-trib
    Feb 02, 2016 @ 11:30
    Jeavon Leopold
    0

    Looks good. Yes whitelist configuration is documented here. Most people won't have security.config with their Umbraco installs though so you may need to think about that.

  • Jon R. Humphrey 164 posts 455 karma points c-trib
    Feb 02, 2016 @ 11:50
    Jon R. Humphrey
    0

    Jeavon,

    Right then! I'll make sure to add this to the growing list of third-party plugins to add to the install! :-D

    #standingontheshouldersofgiants!


    With the remote images I've added the following for now:

    var thumbnail = (thumb.Id == null) ? string.Format("/remote.axd/{0}{1}", thumb.Url.Substring(thumb.Url.IndexOf("://", StringComparison.Ordinal)+3), "?crop=0,0,400,250") : Umbraco.TypedMedia((int)thumb.Id).GetCropUrl(400, 250);

    While I think the comparison ordinal is a little OTT, I've added it to be on the safe side!

    J

  • Jon R. Humphrey 164 posts 455 karma points c-trib
    Feb 03, 2016 @ 02:46
    Jon R. Humphrey
    0

    James & Jeavon,

    Just wanted to say thanks for the responses from both of you!

    With everything else (including BT) I simply missed responding until now, you both were absolutely correct in the remote.axd call being the key!

    Once I installed the full ImageProcessor package, and manually added the test "lorempixel.com" url to the whitelist the thumbnails loaded perfectly!

    #h5yr! x2

    [Now to add a dashboard to the developers area to enable backoffice updates to the config file ... but that can wait]


    Sadly I can't say the same for my ImageMediaTypeSwap code.

    I'm receiving the following error and have chopped and changed my code to try everything I can see but still to no avail on the ImageCropper PropertyEditorType update.

    INSTALLER: ChangeImageMediaType failed. An issue occurred updating Image Media Type to use Image Cropper. System.NullReferenceException: Object reference not set to an instance of an object. at NG.USK.PackageActions.ImageMediaTypeChange.ChangeImageMediaType() in E:\Users\jon\Documents\Visual Studio 2015\Projects\NGS\src\NG.USK\PackageActions\ImageMediaTypeChange.cs:line 46

    Line 46 is: mediaImage.SetValue("umbracoFile", generalCropper);

    I'm posting my code below and going to bed, maybe someone can see what I'm not:

    using System;
    using System.Linq;
    using System.Xml;
    
    using umbraco.interfaces;
    using Umbraco.Core;
    using Umbraco.Core.Logging;
    
    using umbraco.BusinessLogic;
    using umbraco.cms.businesslogic.packager.standardPackageActions;
    using Umbraco.Core.Models;
    
    namespace NG.USK.PackageActions
    {
      public class ImageMediaTypeChange : IPackageAction
      {
    
        public static bool ChangeImageMediaType()
        {
          var success = false;
          try
          {
            //Create the `DataTypeService` object for later use
            var dataTypeService = ApplicationContext.Current.Services.DataTypeService;
            //Create the other services we need
            var mediaService = ApplicationContext.Current.Services.MediaService;
            var contentTypeService = ApplicationContext.Current.Services.ContentTypeService;
            //Given a `DataTypeService` object get the DataType by propertyEditorAlias
            var generalCropper = dataTypeService.GetDataTypeDefinitionByPropertyEditorAlias("Umbraco.ImageCropper");
            //Check if the DataType is null
            if (generalCropper == null) return false;
            //Given a 'ContentTypeService' object get the MediaType that we're changing,
            var mediaImageType = contentTypeService.GetMediaType("Image");
            //PropertyType propertyType = mediaImageType.PropertyTypes.First(x => x.Alias == "umbracoFile");
            mediaImageType.RemovePropertyType("umbracoFile");
    
            contentTypeService.Save(mediaImageType);
    
            var mediaImage = mediaService.GetById(mediaImageType.Id);
    
            var noCropper = false;
            foreach (var property in mediaImage.PropertyTypes.Where(property => property.PropertyEditorAlias != "Umbraco.ImageCropper"))
            {
              noCropper = true;
            }
    
            if (noCropper == true)
            {
              mediaImage.SetValue("umbracoFile", generalCropper);
            }
    
            //and saves the Media through the `MediaService`
            mediaService.Save(mediaImage);
            LogHelper.Info<NgUskInstaller>("INSTALLER: Updating Image Media Type to use Image Cropper in ChangeImageMediaType.cs succeeded!");
            success = true;
    
          }
          catch (Exception exception)
          {
            success = false;
            LogHelper.Error<NgUskInstaller>("INSTALLER: ChangeImageMediaType failed. An issue occurred updating Image Media Type to use Image Cropper.", exception);
          }
          return success;
        }
    
    
        public string Alias()
        {
          return "ImageMediaTypeChange";
        }
    
        public bool Execute(string packageName, XmlNode xmlData)
        {
          try
          {
            return ChangeImageMediaType();
          }
          catch (Exception doh)
          {
            LogHelper.Error<NgUskInstaller>("INSTALLER: Error at execute ChangeImageMediaType package action", doh);
    
            return false;
          }
    
        }
    
    
        public bool Undo(string packageName, XmlNode xmlData)
        {
          return true;
        }
    
        public XmlNode SampleXml()
        {
          const string sample = "<Action runat=\"install\" undo=\"true\" alias=\"ImageMediaTypeChange\" />";
          return ParseStringToXmlNode(sample);
        }
    
        private static XmlNode ParseStringToXmlNode(string value)
        {
          var xmlDocument = new XmlDocument();
          var xmlNode = AddTextNode(xmlDocument, "error", "");
    
          try
          {
            xmlDocument.LoadXml(value);
            return xmlDocument.SelectSingleNode(".");
          }
          catch
          {
            return xmlNode;
          }
        }
    
        private static XmlNode AddTextNode(XmlDocument xmlDocument, string name, string value)
        {
          var node = xmlDocument.CreateNode(XmlNodeType.Element, name, "");
          node.AppendChild(xmlDocument.CreateTextNode(value));
          return node;
        }
      }
    }
    

    Until the daylight...

    J

Please Sign in or register to post replies

Write your reply to:

Draft