Copied to clipboard

Flag this post as spam?

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


  • Chris Speakman 17 posts 151 karma points
    Feb 19, 2021 @ 16:03
    Chris Speakman
    0

    Using image crops in Blocklist custom views

    I've been using custom views with the blocklist editor for some time now to get live content previews in the backoffice which is awesome.

    One thing I'm struggling with though, is showing image crops. I'm currently using the entityResource service to fetch media but the returned object only contains a url to the full image.

    Does anyone know of a way to retrieve crop urls through the backoffice API?

    Thanks!

  • Marc Goodson 2141 posts 14344 karma points MVP 8x c-trib
    Feb 20, 2021 @ 09:33
    Marc Goodson
    1

    Hi Chris

    There is the imageUrlGeneratorResource that you can use in your custom block implementation, but it might not be exactly what you need.

    angular.module("umbraco").controller("customBlockController", function ($scope, mediaResource,imageUrlGeneratorResource) {
    
        //your media picker property is called image so the following will contain the udi:
            var imageUdi = $scope.block.data.image;
        //the mediaResource has a getById method:
            mediaResource.getById(imageUdi)
                .then(function (media) {
                    imageUrlGeneratorResource.getCropUrl(media.mediaLink, 150, 150).then(function (cropUrl) {
                    console.log(cropUrl);
                    $scope.imageUrl = cropUrl;
                });
        });    
    });
    

    So it feels like it's what your expected to use except if you look at the implementation:

    https://github.com/umbraco/Umbraco-CMS/blob/34e80d86e8c0b754f6b7a02e307f53cb32806bbe/src/Umbraco.Web.UI.Client/src/common/resources/imageurlgenerator.resource.js

    it doesn't have an overload for you to specify the crop, it will take a width and height and a CropMode to determine whether to resize or to crop - which might be ok for what you need, but if there is a specific crop you display in your block, then perhaps not!

    The resource itself makes requests to a backoffice api controller, where you can again see the limitations of the overloads do not allow a crop

    https://github.com/umbraco/Umbraco-CMS/blob/34e80d86e8c0b754f6b7a02e307f53cb32806bbe/src/Umbraco.Web/Editors/ImageUrlGeneratorController.cs

    but you can see the controller again just passes on the width, height CropMode to the underlying GetCropUrl String extension - which does have the ability to specify a crop alias!

    https://github.com/umbraco/Umbraco-CMS/blob/2bfef741914297c802bc6c77cc48780d7534f920/src/Umbraco.Web/ImageCropperTemplateCoreExtensions.cs#L211

    So unless I've missed something obvious, if you have a specific need for a specific crop, and using the basic implementation of the imageUrlGeneratorResource isn't enough, then you could create your own UmbracoAuthorizedJsonController Api endpoint (copying ImageUrlGeneratorController), that does have a parameter that will take in the crop alias, that you can then pass on to the GetCropUrl String extension, and make a GET request from your angularJS controller in order to make use of it.

    But hopefully you just need to resize - basic crop an image and the ImageUrlGeneratorResource is all you need.

    regards

    marc

  • Chris Speakman 17 posts 151 karma points
    Feb 22, 2021 @ 16:49
    Chris Speakman
    102

    Hi Marc,

    Thanks for all the info, I never spotted the imageUrlGeneratorResource but as it happens I'm using named crops anyway.

    In the end I switched from using entityResource to mediaResource to fetch the image, which returns much more data including the details of named crops (width, height, focal point). Then I wrote my own getGropUrl function and put it in a service (where I make shared functions available to all my custom views). The result is pretty basic and could easily be improved but it does the job for now and hopefully may help someone else:

    function getCropUrl(media, cropName) {
                    var baseUrl = media.mediaLink;
                    var querystring = "";
                    var config = media.tabs[0].properties.find(x => x.alias === "umbracoFile").value;
    
                    if (config) {
                        var focalPoint = config.focalPoint, crop = config.crops.find(x => x.alias === cropName);
    
                        //If no crop with cropName exists return the base url of the media.
                        if (!crop)
                            return baseUrl;
    
                        if (focalPoint) {
                            if (focalPoint.left == 0.5 && focalPoint.top == 0.5) {
                                querystring += "anchor=center&mode=crop&";
                            }
                            else {
                                querystring += `center=${focalPoint.top},${focalPoint.left}&mode=crop&`;
                            }
                        } else {
                            //if no focal point data found assume center.
                            querystring += "anchor=center&mode=crop&";
                        }
    
                        //add width & height
                        querystring += `width=${crop.width}&height=${crop.height}`;
    
                    } else {
                        //if no config object exists return base url of media object.
                        return baseUrl;
                    }
    
                    return baseUrl + "?" + querystring;
                }
    
  • Ulrich Wagner Gade Ebsen 127 posts 277 karma points
    May 29, 2021 @ 00:50
    Ulrich Wagner Gade Ebsen
    1

    Hi Chris,

    Very nice.. :D

    You can add the following if you want the actual crop and not just the size:

    if (crop.coordinates) {
    querystring += `crop=${crop.coordinates.x1},${crop.coordinates.y1},${crop.coordinates.x2},${crop.coordinates.y2}&cropmode=percentage&`;}
    

    /ulrich

Please Sign in or register to post replies

Write your reply to:

Draft