New to Telerik Document ProcessingStart a free 30-day trial

Images

Updated on Jun 3, 2026

The .NET Framework version of the RadPdfProcessing library provides built-in functionality for converting images and scaling their quality. The .NET Standard version does not provide such functionality and requires manual configuration. The FixedExtensibilityManager class is exposed to address this need. The code samples later in this article demonstrate how to configure it.

Exporting Images

To reduce file size, PDF supports only a limited set of compression filters such as JPEG and JPEG2000 compression of color and grayscale images. To allow the library to export images other than JPEG and JPEG2000, you must process these images before export. The .NET Standard specification does not define APIs for converting or processing images or scaling their quality. To export images other than JPEG and JPEG2000, or to use ImageQuality other than High, PdfProcessing exposes two extensibility points through the static FixedExtensibilityManager class: ImagePropertiesResolver and JpegImageConverter.

If neither ImagePropertiesResolver nor JpegImageConverter is set, an InvalidOperationException is thrown during export of the document.

Requirements

To export images other than JPEG and JPEG2000, or to use ImageQuality other than High, add references to the following .NET Standard packages:

NuGet packageDescription
Telerik.Documents.ImageUtils
SkiaSharp.NativeAssets.* (version 3.119.1)May differ according to the used platform. For Linux use SkiaSharp.NativeAssets.Linux.NoDependencies.
SkiaSharp.Views.Blazor and wasm-toolsFor Blazor WebAssembly.

With the R2 2023 changes, SkiaSharp replaced ImageSharp as the required dependency.

ImagePropertiesResolver

The ImagePropertiesResolver property allows you to set a resolver implementation that parses the image raw data to separate its colors and alpha channel. While you can use this implementation for any type of supported image, it is required when working with PNG images so their transparency is preserved in the generated PDF document. The resolver gets the image bytes as they are and does not take into consideration the Image Quality set through the Export Settings.

Default Implementation for ImagePropertiesResolver

PdfProcessing provides a default implementation called ImagePropertiesResolver. The built-in logic depends on the SkiaSharp library to parse the image data. To use the default functionality, set an instance of the ImagePropertiesResolver class to the FixedExtensibilityManager.ImagePropertiesResolver property.

View the implementation Requirements.

Example 1: Set the default implementation of the ImagePropertiesResolver class

C#
Telerik.Documents.ImageUtils.ImagePropertiesResolver defaultImagePropertiesResolver = new Telerik.Documents.ImageUtils.ImagePropertiesResolver();
Telerik.Windows.Documents.Extensibility.FixedExtensibilityManager.ImagePropertiesResolver = defaultImagePropertiesResolver;

Custom Implementation for ImagePropertiesResolver

If you have specific requirements and the default ImagePropertiesResolver does not fit them, you can implement custom logic. To achieve this:

  1. Inherit the Telerik.Windows.Documents.Core.Imaging.ImagePropertiesResolverBase class.
  2. Implement its members.
  3. Assign an instance of the custom implementation to the FixedExtensibilityManager.ImagePropertiesResolver property.

JpegImageConverter

The JpegImageConverter property uses an implementation of the JpegImageConverterBase abstract class to convert an image to JPEG. Pass this implementation to the JpegImageConverter property of the FixedExtensibilityManager.

If you have both the ImagePropertiesResolver and JpegImageConverter properties set, ImagePropertiesResolver takes priority and is used to parse the image.

Default Implementation for JpegImageConverter

The Telerik.Documents.ImageUtils package provides a default implementation of the JpegImageConverter class that you can use when exporting a document. The default implementation depends on the SkiaSharp library to convert images to JPEG format.

View the implementation Requirements.

Example 2: Set the default implementation of the JpegImageConverter class

C#
Telerik.Windows.Documents.Extensibility.JpegImageConverterBase defaultJpegImageConverter = new Telerik.Documents.ImageUtils.JpegImageConverter();
Telerik.Windows.Documents.Extensibility.FixedExtensibilityManager.JpegImageConverter = defaultJpegImageConverter;

Custom Implementation for JpegImageConverter

The following example demonstrates how to implement a custom image converter. It depends on the SixLabors.ImageSharp library. You can follow this approach with other image processing libraries according to your specific requirements.

Required NuGet Packages

  • SixLabors.ImageSharp - version 3.1.12
  • SixLabors.ImageSharp.Drawing - version 2.1.7

The following using/imports statements are required in the project:

  • using SixLabors.ImageSharp;
  • using SixLabors.ImageSharp.Formats.Jpeg;
  • using SixLabors.ImageSharp.Formats.Png;
  • using SixLabors.ImageSharp.PixelFormats;
  • using SixLabors.ImageSharp.Processing;

Example 3: Create a custom implementation inheriting the JpegImageConverterBase abstract class

C#

// SixLabors.ImageSharp 3.1.12
// SixLabors.ImageSharp.Drawing 2.1.7

//using SixLabors.ImageSharp; 
//using SixLabors.ImageSharp.Formats.Jpeg;
//using SixLabors.ImageSharp.Formats.Png;
//using SixLabors.ImageSharp.PixelFormats;
//using SixLabors.ImageSharp.Processing;
internal class CustomJpegImageConverter : Telerik.Windows.Documents.Extensibility.JpegImageConverterBase
{
    public override bool TryConvertToJpegImageData(byte[] imageData, ImageQuality imageQuality, out byte[] jpegImageData)
    {
        jpegImageData = null;

        try
        {
            using (var imageStream = new MemoryStream(imageData))
            {
                SixLabors.ImageSharp.Image image = SixLabors.ImageSharp.Image.Load(imageStream);
                var imageFormat = image.Metadata.DecodedImageFormat;

                // Handle transparency for PNG
                if (imageFormat is PngFormat && image.PixelType.BitsPerPixel == 32)
                {
                    var background = new Image<Rgba32>(image.Width, image.Height, Color.White);
                    background.Mutate(ctx => ctx.DrawImage(image, 1f));

                    image.Dispose(); // Dispose original
                    image = background; // Assign new image
                }

                var jpegEncoder = new JpegEncoder
                {
                    Quality = (int)imageQuality
                };

                using (var ms = new MemoryStream())
                {
                    image.Save(ms, jpegEncoder);
                    jpegImageData = ms.ToArray();
                }

                image.Dispose(); // Dispose final image
            }

            return true;
        }
        catch (SixLabors.ImageSharp.UnknownImageFormatException)
        {
            return false;
        }
        catch (SixLabors.ImageSharp.ImageProcessingException)
        {
            return false;
        }
        catch (Exception)
        {
            return false;
        }

    }
}

Example 4: Set the custom implementation to the JpegImageConverter property of the FixedExtensibilityManager

C#
JpegImageConverterBase customJpegImageConverter = new CustomJpegImageConverter();
Telerik.Windows.Documents.Extensibility.FixedExtensibilityManager.JpegImageConverter = customJpegImageConverter;

A complete SDK example of a custom JpegImageConverterBase implementation is available on the GitHub repository.

See Also