SaaS CMS has officially launched! Learn more now.

Focal point based image cropping for EPiServer using ImageResizing.NET

Vote:
 

https://world.episerver.com/blogs/stephan-lonntorp/dates/2016/9/focal-point-based-image-cropping-for-episerver-using-imageresizing-net/

Does anyone have information how to use this plugin. Simply installing it and creating a ImageFile media type does not seem to do anything.

[ContentType(DisplayName = "ImageFile", GUID = "nquid", Description = "")]
[MediaDescriptor(ExtensionString = "jpg,jpeg,jpe,ico,gif,bmp,png,svg")]
public class ImageFile : FocalPointImageData
{
        /// <summary>
        /// Gets or sets the copyright.
        /// </summary>
        /// <value>
        /// The copyright.
        /// </value>
        public virtual string Copyright { get; set; }

        [Editable(false)]
        public virtual string FileSizeKb { get; set; }
}

When implementing I've tried:

[Display(GroupName = SystemTabNames.Content, Order = 10)]
[UIHint(UIHint.Image)]
[CultureSpecific]
public virtual ContentReference MainImage { get; set; }

//

[UIHint(UIHint.Image)]
[Display(GroupName = SystemTabNames.Content, Order = 10)]
public virtual Url SiteLogotypeUrl { get; set; }

If you read this: https://github.com/defsteph/EPiFocalPoint

It's just supposed to work...

#205858
Jul 25, 2019 14:53
Vote:
 

Have you definately got the config in your web.config

 <resizer>
 	<plugins>
 		<add name="EPiFocalPointPlugin" />
 	</plugins>
 </resizer>
#205862
Jul 25, 2019 17:07
Carl S - Jul 26, 2019 9:26
Yes. There is also the "EPiServerBlobReaderPlugin".
Vote:
 

FYI I moved our base build projects uver to ImageProcessor after years of using ImageResizer. https://world.episerver.com/blogs/vincent-baaij/dates/2019/1/episerver-and-imageprocessor-new-crop-addition/

This has multiple benefits

  1. As shown in the blog post it comes with cropping support in editor
  2. ImageResizer doesn't cache files locally without paying for essentials. If you've got diskcache enable and you've not got a licence you'll notice a red dot in all pictures whereas imageprocessor has it for free.
  3. Comes with a load of processer extensions methods that can be chained in the views allowing you to give front end developers access.

On the whole the expereince of using it for us has been far better since transitioning.

#205863
Jul 25, 2019 17:17
Carl S - Jul 29, 2019 6:59
That is a nice plugin. But as far as I can see it doesn't come with focal point editing? That is the key feature we want.
Vote:
 

There are some code related to focal point in ImageProcessor package - https://github.com/vnbaaij/ImageProcessor.Web.Episerver/pull/18

haven't gone through PR. So - no comments

#206063
Aug 01, 2019 15:46
Vote:
 

When installing ImageResizer focal point plugin following things should happen / actions need to be taken in order to make package working:

1) New files in "/ClientResources/focalpoint/" (editor.js, widgettemplate.css, widgettemplate.html)

2) add section in root modules.config file

<dojo>
    <paths>
      <add name="focal-point" path="focalpoint" />
    </paths>
</dojo>

3) implement new interface on your media content definition `IFocalPointData`

4) add new property to media content type definition

[BackingType(typeof(PropertyFocalPoint))]
public virtual FocalPoint FocalPoint { get; set; }
#206064
Aug 01, 2019 15:54
Carl S - Aug 05, 2019 8:36
All that is well and good. The changes are there. And I implemented the abstract class instead.
Vote:
 

After I 'borrowed' some code from ImageResizer and the FocalPoint plugin, I got it to work.

If any one have a nicer solution would be great.

1) In HtmlHelper extension class:

public static UrlBuilder FocalPointImage(this HtmlHelper helper, ContentReference image)
{
	if (image == null) throw new ArgumentNullException(nameof(image));
   
	var contentLoader = ServiceLocator.Current.GetInstance<IContentLoader>();
	ImageFile imageData;

	try
	{
		imageData = contentLoader.Get<ImageFile>(image);
	}
	catch (TypeMismatchException)
	{
		throw new ArgumentNullException(nameof(image));
	}

	if (imageData == null) throw new ArgumentNullException(nameof(image));
	var urlResolver = ServiceLocator.Current.GetInstance<IUrlResolver>();
	return new UrlBuilder(urlResolver.GetUrl(image)).Add("crop", CropDimensions.Parse(imageData, null).ToString());
}

2) In CropDimensions class:

public class CropDimensions
{
	public int X1 { get; set; }
	public int Y1 { get; set; }
	public int X2 { get; set; }
	public int Y2 { get; set; }

	public override string ToString()
	{
		return $"{X1},{Y1},{X2},{Y2}";
	}

	public static CropDimensions Parse(IFocalPointData focalPointData, ResizeSettings resizeSettings)
	{
		var sourceWidth = focalPointData.OriginalWidth ?? 1;
		var sourceHeight = focalPointData.OriginalHeight ?? 1;
		var focalPointY = (int) Math.Round(sourceHeight * (focalPointData.FocalPoint.Y / 100));
		var focalPointX = (int) Math.Round(sourceWidth * (focalPointData.FocalPoint.X / 100));
		var sourceAspectRatio = (double) sourceWidth / sourceHeight;
		double targetAspectRatio = 1.0f;
		if (resizeSettings != null)
		{
			//Calculate target aspect ratio from resizeSettings.
			if (resizeSettings.Width > 0 && resizeSettings.Height > 0)
			{
				targetAspectRatio = (double) resizeSettings.Width / resizeSettings.Height;
			}
			else
			{
				targetAspectRatio = sourceAspectRatio;
			}
		}

		var x1 = 0;
		var y1 = 0;
		int x2;
		int y2;
		if (targetAspectRatio.Equals(sourceAspectRatio))
		{
			x2 = focalPointData.OriginalWidth ?? 0;
			y2 = focalPointData.OriginalHeight ?? 0;
		}
		else if (targetAspectRatio > sourceAspectRatio)
		{
			// the requested aspect ratio is wider than the source image
			var newHeight = (int) Math.Floor(sourceWidth / targetAspectRatio);
			x2 = sourceWidth;
			y1 = Math.Max(focalPointY - (int) Math.Round((double) newHeight / 2), 0);
			y2 = Math.Min(y1 + newHeight, sourceHeight);
			if (y2 == sourceHeight)
			{
				y1 = y2 - newHeight;
			}
		}
		else
		{
			// the requested aspect ratio is narrower than the source image
			var newWidth = (int) Math.Round(sourceHeight * targetAspectRatio);
			x1 = Math.Max(focalPointX - (int) Math.Round((double) newWidth / 2), 0);
			x2 = Math.Min(x1 + newWidth, sourceWidth);
			y2 = sourceHeight;
			if (x2 == sourceWidth)
			{
				x1 = x2 - newWidth;
			}
		}

		return new CropDimensions {X1 = x1, X2 = x2, Y1 = y1, Y2 = y2};
	}
}
#206167
Aug 06, 2019 8:31
Vote:
 

should be part of libraries. not customer code

#206168
Aug 06, 2019 8:36
Carl S - Aug 06, 2019 8:39
I know but until someone fixes the plugin.. :)
Vote:
 

if you are up to PR, think we will be happy to merge.

#206173
Aug 06, 2019 9:31
Carl S - Aug 07, 2019 8:21
I have committed my updated changes. But I cannot push (403) or create PR.
First time doing PR in Github, have done it in VS Git without problem.
valdis - Aug 07, 2019 8:24
no problem. I can help you out. what's your github username? if you can point to your fork - I can take a look..
Carl S - Aug 07, 2019 8:41
https://github.com/carsjo/EPiFocalPoint
valdis - Aug 07, 2019 9:34
PR looks oridnary. https://github.com/defsteph/EPiFocalPoint/pull/16
let's see Stephan's next steps
This topic was created over six months ago and has been resolved. If you have a similar question, please create a new topic and refer to this one.
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.