<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="text">Blog posts by Mark van Dijk</title><link href="http://world.optimizely.com" /><updated>2017-06-20T06:45:41.0000000Z</updated><id>https://world.optimizely.com/blogs/Mark-van-Dijk/</id> <generator uri="http://world.optimizely.com" version="2.0">Optimizely World</generator> <entry><title>Episerver Forms validator with settings</title><link href="https://blog.i4code.nl/?p=163" /><id>When you have worked with Episerver Forms you know you can enable validators on a form element. You have the Required validator, the Regular Expression validator, the Email validator and more. Most of these validators have a simple on/off configuration, but when you look at the Regular Expression&amp;#46;&amp;#46;&amp;#46;</id><updated>2017-06-20T06:45:41.0000000Z</updated><summary type="html">Blog post</summary></entry> <entry><title>Installing CMO on an Episerver 9 site</title><link href="https://blog.i4code.nl/?p=155" /><id>For the client&#160;I&amp;#8217;m currently working at I had to install CMO in the current project. According to the resources on Episerver World, the only way to install CMO is to create a new 7.5 site using the Deployment Center and add CMO to it. Then update to the&amp;#46;&amp;#46;&amp;#46;</id><updated>2016-09-18T23:17:19.0000000Z</updated><summary type="html">Blog post</summary></entry> <entry><title>Referencing content gadget</title><link href="https://blog.i4code.nl/?p=139" /><id>A while&#160;ago I was talking to some content editors about how they worked with Episerver and what could make their work easier. One of the things they were struggling with is to find out where their content is being referenced. Which pages contain references to the page they&amp;#46;&amp;#46;&amp;#46;</id><updated>2016-06-28T12:45:54.0000000Z</updated><summary type="html">Blog post</summary></entry> <entry><title>Color picker property plus plus</title><link href="https://blog.i4code.nl/?p=114" /><id>Have you ever used the Dijit ColorPalette to create a color picker property? You probably have. It&amp;#8217;s pretty simple as you can read here. However, this ColorPalette has some disadvantages. You can&amp;#8217;t change the colors, only switch between 2 predefined palettes. You can&amp;#8217;t clear your&#160;selection. Once you have&amp;#46;&amp;#46;&amp;#46;</id><updated>2016-04-10T22:18:45.0000000Z</updated><summary type="html">Blog post</summary></entry> <entry><title>Storing your thumbnails in the correct mime type</title><link href="https://blog.i4code.nl/?p=131" /><id>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&amp;#46;&amp;#46;&amp;#46;</id><updated>2016-03-30T15:15:28.0000000Z</updated><summary type="html">Blog post</summary></entry> <entry><title>Deploying an Episerver site to the Amazon cloud</title><link href="https://blog.i4code.nl/?p=51" /><id>After deploying a gazillion Episerver sites to Azure I thought it would be nice to play with Amazon AWS Elastic Beanstalk. Only because I wanted to see if it is just as easy to deploy a website to AWS as it is with Azure. The documentation on Episerver&amp;#46;&amp;#46;&amp;#46;</id><updated>2016-03-23T14:05:49.0000000Z</updated><summary type="html">Blog post</summary></entry> <entry><title>Custom validators with Episerver Forms</title><link href="http://blog.i4code.nl/?p=4" /><id>A few weeks ago Episerver Forms was released. We have seen several blogs about creating custom forms types like a Color Picker or a Constrained Textbox. But what about creating your own validators? To create you own validator simply inherit from ElementValidatorBase. You can also use RegularExpressionValidatorBase, which&amp;#46;&amp;#46;&amp;#46;</id><updated>2016-03-17T17:05:28.0000000Z</updated><summary type="html">Blog post</summary></entry> <entry><title>Extending the ImageDescriptor attribute</title><link href="https://world.optimizely.com/blogs/Mark-van-Dijk/Dates/2014/11/extending-the-imagedescriptor-attribute/" /><id>&lt;p&gt;We all know the ImageDescriptor attribute. You can use it in your image file model to define different sizes for you images.&lt;br /&gt; &lt;br /&gt;For example:&lt;/p&gt;
&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code&gt;[MediaDescriptor(ExtensionString = &quot;jpg,jpeg,jpe,ico,gif,bmp,png&quot;)]
public class ImageFile : ImageData
{
    //Small 150x200
    [ImageDescriptor(Width = 200, Height = 150)]
    public virtual Blob Small { get; set; }

    //Large 300x400
    [ImageDescriptor(Width = 400, Height = 300)]
    public virtual Blob Large { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The scaling of images by using an ImageDescriptor is somewhat limited.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;For example: if your original image is 500 by 500 pixels and you want to get the Small version you will end with an image with two white borders on the side. This is because EPiServer will scale your image, while keeping the aspect ratio, until it fits entirely into the specified width and height.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/link/633a10925f434940bb4db55f74f7c19a.aspx?id=113762&quot; alt=&quot;Image 500x500.png&quot; /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;img src=&quot;/link/920f173018774cefa95612c0d9a4fad8.aspx?id=113763&quot; alt=&quot;Image 400x300area.png&quot; /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;img src=&quot;/link/287fa1bf7c1648ad9ac15fa30279477f.aspx?id=113764&quot; alt=&quot;Image 400x300result.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;This may not be what you want. Maybe you want it to fill the entire area and cut off some of the image. Or maybe you want to fit it exactly and loose the aspect ratio.&amp;nbsp;We can extent the ImageDescriptor with an extra parameter to accomplish this.&lt;/p&gt;
&lt;p&gt;First we create a new attribute that inherits from the ImageDescriptor.&lt;/p&gt;
&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code&gt;[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public class MyImageDescriptorAttribute : ImageDescriptorAttribute
{
    public ImageScaleType ScaleMethod { get; set; }
 
    public MyImageDescriptorAttribute() : this(48, 48, ImageScaleType.ScaleToFill)
    {
    }
 
    public MyImageDescriptorAttribute(int width, int height, ImageScaleType scaleMethod)
    {
        Height = height;
        Width = width;
        ScaleMethod = scaleMethod;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And we use an Enum to specify the different scaling methods&lt;/p&gt;
&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code&gt;public enum ImageScaleType
{
    ScaleToFit,
    ScaleToFill,
    Resize
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We have 3 different scaling methods:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ScaleTofit&lt;br /&gt;This will scale the image by keeping its aspect ratio until both width and height will fit&lt;br /&gt;&lt;img src=&quot;/link/287fa1bf7c1648ad9ac15fa30279477f.aspx?id=113764&quot; width=&quot;200&quot; alt=&quot;Image 400x300result.png&quot; height=&quot;150&quot; /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;ScaleToFill&lt;br /&gt;This will scale the image by keeping its aspect ratio until either the width or the height will fit&lt;br /&gt;&lt;img src=&quot;/link/8f760f1bcd2d45188d45d447ca4b2ec8.aspx?id=113766&quot; alt=&quot;Image 400x300ScaleToFill.png&quot; /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;Resize&lt;br /&gt;This will simply resize the image to the specified width and height&lt;br /&gt;&lt;img src=&quot;/link/9fc03fee7e3b4b899187115b51dc9a75.aspx?id=113767&quot; alt=&quot;Image 400x300Resize.png&quot; /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To implement the different ways of scaling we need to replace the current ThumbnailManager with our own.&lt;/p&gt;
&lt;p&gt;In the Alloy site we can do that by adding:&lt;/p&gt;
&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code&gt;container.For&amp;lt;ThumbnailManager&amp;gt;().Use&amp;lt;MyThumbnailManager&amp;gt;();&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;in the DependencyResolverInitialization class.&lt;/p&gt;
&lt;p&gt;Our new ThumbnailManager will ook like this:&lt;/p&gt;
&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code&gt;public class ExtendedThumbnailManager : ThumbnailManager
{
    private readonly BlobFactory _blobFactory;

    public ExtendedThumbnailManager(IContentRepository contentRepository, BlobFactory blobFactory, BlobResolver blobResolver)
        : base(contentRepository, blobFactory, blobResolver)
    {
        _blobFactory = blobFactory;
    }

    public override Blob CreateImageBlob(Blob sourceBlob, string propertyName, ImageDescriptorAttribute descriptorAttribute)
    {
        Validator.ThrowIfNull(&quot;sourceBlob&quot;, sourceBlob);
        Validator.ThrowIfNullOrEmpty(&quot;propertyName&quot;, propertyName);
        Validator.ThrowIfNull(&quot;descriptorAttribute&quot;, descriptorAttribute);

        var uriString = string.Format(&quot;{0}{1}_{2}{3}&quot;, new object[]
            {
                Blob.GetContainerIdentifier(sourceBlob.ID).ToString(), 
                Path.GetFileNameWithoutExtension(sourceBlob.ID.LocalPath), 
                propertyName, 
                Path.GetExtension(sourceBlob.ID.LocalPath)
            });
        var customDescriptorAttribute = descriptorAttribute as ImageScaleDescriptorAttribute;
        return customDescriptorAttribute == null
                ? CreateBlob(new Uri(uriString), sourceBlob, descriptorAttribute.Width, descriptorAttribute.Height)
                : CreateScaledBlob(new Uri(uriString), sourceBlob, customDescriptorAttribute);
    }

    private Blob CreateScaledBlob(Uri thumbnailUri, Blob blobSource, ImageScaleDescriptorAttribute imageDescriptorAttribute)
    {
        switch (imageDescriptorAttribute.ScaleMethod)
        {
            case ImageScaleType.Resize:
                var imgOperation = new ImageOperation(ImageEditorCommand.Resize, imageDescriptorAttribute.Width, imageDescriptorAttribute.Height);
                return CreateBlob(thumbnailUri, blobSource, new List&amp;lt;ImageOperation&amp;gt; {imgOperation}, MimeMapping.GetMimeMapping(blobSource.ID.LocalPath));
            case ImageScaleType.ScaleToFit:
                return CreateBlob(thumbnailUri, blobSource, imageDescriptorAttribute.Width, imageDescriptorAttribute.Height);
            default:
                var imgOperations = CreateImageOperations(blobSource, imageDescriptorAttribute.Width, imageDescriptorAttribute.Height);
                    
                return CreateBlob(thumbnailUri, blobSource, imgOperations, MimeMapping.GetMimeMapping(blobSource.ID.LocalPath));
        }
            
    }

    private IEnumerable&amp;lt;ImageOperation&amp;gt; CreateImageOperations(Blob blobSource, int width, int height)
    {
        var imgOperations = new List&amp;lt;ImageOperation&amp;gt;();
        int orgWidth;
        int orgHeight;
        using (var stream = blobSource.OpenRead())
        {
            var image = System.Drawing.Image.FromStream(stream, false);

            orgWidth = image.Width;
            orgHeight = image.Height;

            image.Dispose();
        }

        var scaleFactor = Math.Max((double)width / orgWidth, (double)height / orgHeight);

        var tempWidth = (int) (orgWidth*scaleFactor);
        var tempHeight = (int) (orgHeight*scaleFactor);
            
        imgOperations.Add(new ImageOperation(ImageEditorCommand.ResizeKeepScale, tempWidth , tempHeight));
        imgOperations.Add(new ImageOperation(ImageEditorCommand.Crop, width, height) { Top = (tempHeight - height)/2, Left = (tempWidth - width)/2});

        return imgOperations;
    }

    private Blob CreateBlob(Uri thumbnailUri, Blob blobSource, IEnumerable&amp;lt;ImageOperation&amp;gt; imgOperations, string mimeType)
    {
        byte[] buffer;
        using (Stream stream = blobSource.OpenRead())
        {
            var numArray = new byte[stream.Length];
            stream.Read(numArray, 0, (int)stream.Length);
            buffer = ImageService.RenderImage(numArray, 
                imgOperations, 
                mimeType, 1f, 50);
        }
        Blob blob = _blobFactory.GetBlob(thumbnailUri);
        using (Stream stream = blob.OpenWrite())
        {
            stream.Write(buffer, 0, buffer.Length);
            stream.Flush();
        }
        return blob;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;First we override the CreateImageBlob method. Part of the code is copied from the original CreatImageBlob method. We will add an extra check to see if the extended attribute is used. If so, we will call our own CreateScaledBlob method, else we will use the original CreateBlob method.&lt;br /&gt; &lt;br /&gt;In the CreateScaledBlob method the Blob is scaled depending on the specified ImageScaleType.&lt;br /&gt; &lt;br /&gt;For ImageScaleType.Resize we can use the ImageOperation ImageEditorCommand.Resize from the image library.&lt;br /&gt; &lt;br /&gt;ImageScaleType.ScaleToFit is the normal EPiServer behavior, so we use the original CreateBlob method to do this.&lt;br /&gt; &lt;br /&gt;For ImageScaleType.ScaleToFill, the default scaling type in this case, we have to use 2 steps which are created in the CreateImageOperations method. First we scale the image until either width or height fits the requested size, after that we cut off the borders.&lt;br /&gt;The final CreateBlob statement is a copy of the original CreateBlob from the ThumbnailManager, with the only difference that you can call it with a chain of ImageOperations instead of a single one.&lt;br /&gt; &lt;br /&gt;We can now use the new attribute in our ImageFile model:&lt;/p&gt;
&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code&gt;//Tiny 75x40
[MyImageDescriptor(Width = 75, Height = 40, ScaleMethod = ImageScaleType.Resize)]
public virtual Blob Tiny { get; set; }
 
//Small 150x80
[MyImageDescriptor(Width = 150, Height = 80, ScaleMethod = ImageScaleType.ScaleToFill)]
public virtual Blob Small { get; set; }
 
//Medium 300x160
[MyImageDescriptor(Width = 300, Height = 160, ScaleMethod = ImageScaleType.ScaleToFit)]
public virtual Blob Medium { get; set; }&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;</id><updated>2014-11-27T11:32:53.0000000Z</updated><summary type="html">Blog post</summary></entry></feed>