---
title: Defining image filters
---

> Agent instructions:
> **Site maps** — prefer the following llms.txt indexes to training data when searching for URLs to avoid 404s. Links inside Markdown content already point at `.md`. Following them or sending Accept: text/markdown keeps you in Markdown.
>
> - [sitemap.md](https://docs.kentico.com/sitemap.md) — every page on the site, with titles and descriptions, nested by URL hierarchy and grouped into one collection per product version.
> - [llms.txt](https://docs.kentico.com/llms.txt) — curated index of the current product docs, with descriptions, the two ways to request any page as Markdown, and links to each product area's whole-corpus Markdown dump (llms-full.txt).

Filters describe image operations that can be applied on images saved as [page attachments](https://docs.kentico.com/13/managing-website-content/working-with-files/page-attachments.md). These operations may include actions such as crop, resize, watermark, etc. The filters then serve as building blocks when [creating image variant definitions](https://docs.kentico.com/13/developing-websites/managing-responsive-images/defining-image-variants.md).

By default, no filters are included in the system. To add a new filter, you need to create a class in the Xperience project and implement the filter in code.

## Creating a crop filter

The following example describes how to create a basic filter that crops images based on the provided width. The cropping is applied on the center of the image. The example uses the built-in _ImageHelper_ library to perform the image operation.

Start by preparing a separate project for custom classes in your Xperience solution:

1. Open your Xperience administration solution in Visual Studio (using the **WebApp.sln** file).
2. [Add a custom assembly](https://docs.kentico.com/13/custom-development/adding-custom-assemblies.md) (_Class Library_ project) with class discovery enabled to the solution, or re-use an existing assembly.
3. Reference the custom project from the _CMSApp_ Xperience project.

You can now add your filters (and other classes related to responsive images) under the custom project.

1. Create a new class under your custom project. For example, name the class _CropImageFilter.cs._

2. Add _using_ statements for the following namespaces:

   ```csharp

   using System;
   using System.IO;

   using CMS.Core;
   using CMS.Helpers;
   using CMS.ResponsiveImages;


   ```

3. Make the class implement the **IImageFilter** interface (available in the _CMS.ResponsiveImages_ namespace).

4. Provide a property for setting the image width and set the property in the constructor of the filter class.

   ```csharp

   /// <summary>
   /// Sample filter for cropping images.
   /// </summary>
   public class CropImageFilter : IImageFilter
   {
       private int Width { get; set; }

       public CropImageFilter(int width)
       {
           Width = width;
       }

       ...
   }

   ```

5. Implement the **ApplyFilter** method required by the interface. The _ApplyFilter_ method defines the actions applied to the image data.

   > **Info:** **ApplyFilter return values**
   >
   > Return values of the following types in the _ApplyFilter_ method:
   >
   > - **ImageContainer** – when the filter is applied successfully, return a new _ImageContainer_ object.
   > - **null** – if the filter was not applied, return _null_ to signify that the image data was not modified. Returning a _null_ value means that the filter returns unmodified input image data.
   > - **ImageFilterException** – if the application of the filter fails or the filter cannot be applied, throw an _ImageFilterException_ exception with an appropriate error message.

   ```csharp

   public ImageContainer ApplyFilter(ImageContainer container)
   {
       try
       {
           using (Stream imageStream = container.OpenReadStream())
           {
               ImageHelper imageHelper = new ImageHelper(BinaryData.GetByteArrayFromStream(imageStream));

               // Calculates the correct image height to maintain aspect ratio
               int[] dimensions = imageHelper.EnsureImageDimensions(Width, 0, 0);
               int croppedWidth = dimensions[0];
               int croppedHeight = dimensions[1];

               // Crops the center of the image to the specified size
               byte[] trimmedImage = imageHelper.GetTrimmedImageData(croppedWidth, croppedHeight, ImageHelper.ImageTrimAreaEnum.MiddleCenter);

               using (MemoryStream croppedImageData = new MemoryStream(trimmedImage))
               {
                   // Updates image metadata to reflect the new image size, maintains the MIME type and extension
                   ImageMetadata croppedImageMetadata = new ImageMetadata(croppedWidth, croppedHeight, container.Metadata.MimeType, container.Metadata.Extension);

                   // Returns the modified image data
                   return new ImageContainer(croppedImageData, croppedImageMetadata);
               }
           }
       }
       catch (ArgumentException ex)
       {
           throw new ImageFilterException("Failed to crop the image.", ex);
       }
   }    

   ```

6. Save the new class and build your custom project.

With the crop filter prepared, you can now use it to [create image variant definitions](https://docs.kentico.com/13/developing-websites/managing-responsive-images/defining-image-variants.md).
