---
title: "Rendering | Customer's Canvas On-Premises"
canonical: "https://customerscanvas.com/docs/on-premises/design-atoms-cs/howto/rendering/"
---

# Rendering

> The Design Atoms Framework allows you to render products to either a stream or the file cache. You can use the [IProductRenderer](https://customerscanvas.com/docs/on-premises/design-atoms-cs/reference/api/Aurigma.DesignAtoms.Rendering/IProductRenderer.md) interface to render proof images and hi-res outputs. To create an instance of this interface and all necessary dependencies, you can apply [dependency injection](https://customerscanvas.com/docs/on-premises/design-atoms-cs/getting-started.md#using-dependency-injection) as follows:

```csharp title="Creating a renderer instance"
using Aurigma.DesignAtoms.Convert;
var parser = Injector.Instance.Resolve<ITemplateParser>();
var product = parser.FromDefinition(new[] {
    new SurfaceTemplate
    {
        DesignFilename = "card.idml"
    },
    new SurfaceTemplate
    {
        Size = new SizeF(300, 300)
    }
});
```

## Rendering Proof Images

To generate a product preview, you can use the [IProductRenderer.RenderProof](https://customerscanvas.com/docs/on-premises/design-atoms-cs/reference/api/Aurigma.DesignAtoms.Rendering/IProductRenderer.md) method.

```csharp title="Rendering Proof Images"
using Aurigma.DesignAtoms.Rendering;

// Create the output file.
using (var fileStream = File.Create("thumbnail.png"))
{
    renderer.RenderProof(fileStream, product.Surfaces.First(), null);
}
```

In this example, we rendered the first page of the product. By default, the resulting image is generated in the PNG format at a size of 500 x 500 pixels. You can change these default settings as follows:

```csharp title="Rendering Thumbnails"
using Aurigma.GraphicsMill.Codecs;
using Aurigma.DesignAtoms.Configuration.RenderingConfig;

using (var fileStream = File.Create("thumbnail.jpg"))
{
    // Read the default rendering config.
    var config = RenderingConfig.GetDefault();
    // Set the JPEG image format.
    config.DefaultProofRendering.FileFormat = FileFormat.Jpeg;
    // Set the new image size.
    var maxSize = new Size(300, 300);

    renderer.RenderProof(fileStream, product.Surfaces.First(), config, maxSize);
}
```

## Rendering Hi-res Outputs

As an alternative to output streams, you can render products to the file cache.

```csharp title="Rendering Hi-res Outputs"
var hiresIds = productRenderer.RenderHiRes(product);
```

For example, the [ProductRenderer.RenderHiRes](https://customerscanvas.com/docs/on-premises/design-atoms-cs/reference/api/Aurigma.DesignAtoms.Rendering/ProductRenderer.md) method returns a collection of string identifiers of hi-res outputs in the cache. For a one-page product, the resulting collection contains only one identifier, and you can retrieve the generated image from the cache as follows:

```csharp title="Rendering Hi-res to the file cache"
using Aurigma.DesignAtoms.Storage.FileCache;

var fileCache = Injector.Instance.Resolve<IFileCache>;

using (var stream = fileCache.GetReadStream(hiresIds.First()))
using (var fileStream = File.Create("hiRes.pdf"))
    stream.CopyTo(fileStream);
```

## Variable Data Printing (VDP)

In the Design Atoms Framework, you can implement variable data printing through either changing the object model or using product-based templates. The latter aproach is described in the [following section](#vdp-using-products-as-templates).

The following example illustrates how you can render a product after changing the object model. Here, we find a text element and an image placeholder representing the employee name and photo. After changing the content of these elements, we render a proof image with the new data.

```csharp title="Variable Data Printing"
// Find elements representing the employee name and photo.
var employeeName = product.AllItems.OfType<BoundedTextItem>().FirstOrDefault(i => i.Name == "employee");
var photoPlaceholder = product.AllItems.OfType<PlaceholderItem>().FirstOrDefault(i => i.Name == "photo");
// If found, edit and render these elements.
if (employeeName != null && photoPlaceholder != null)
{
    // Change the name.
    employeeName.Text = "John Wood";
    // Assign a new photo.
    var imageLoader = Injector.Instance.Resolve<IImageLoader>();
    var image = photoPlaceholder.Content as ImageItem;
    imageLoader.LoadImage(image, new FileInfo("j.wood.jpg"), false);

    // Render a preview of the edited product.
    var renderer = Injector.Instance.Resolve<IProductRenderer>();
    using (var fileStream = File.Create("j.wood.png"))
    {
        renderer.RenderProof(fileStream, product.Surfaces.First(), null);
    }
}
```

## VDP Using Products as Templates

As an alternative to the [previous aproach](#variable-data-printing-vdp), you can use dedicated methods of [IVdpRenderer](https://customerscanvas.com/docs/on-premises/design-atoms-cs/reference/api/Aurigma.DesignAtoms.VDP/IVdpRenderer.md). In this case, you can provide a product definition, select product pages, and specify variable data. Based on these parameters, the framework generates a new personalized product and renders it to either a stream or the file cache. In these methods, you can use the same `DataSet` objects as in the [Rendering Web API](https://customerscanvas.com/docs/on-premises/design-editor/apis/personalized-rendering.md#dataset).

In the following example, we render four product pages by using two surfaces and two data sets for the personalization.

```csharp title="VDP Using Products as Templates"
// Create a two-page product.
var parser = Injector.Instance.Resolve<ITemplateParser>();
var product = parser.FromFiles("businesscard_front.psd", "businesscard_back.psd");

// Set the PNG format for hi-res outputs.
var config = RenderingConfig.GetDefault();
config.DefaultHiResOutputRendering.FileFormat = FileFormat.Png;

// Define two variable data sets.
var surfaceData = new List<ItemsData> { new ItemsData
    {
        RootItems = new ItemDataCollection
        {
            {"Name", new ItemData {Text = "Cristopher Bennet"}},
            {"Photo", new ItemData {Image = "https://example.com/images/c.bennet.jpg"}}                       
        }
    }, new ItemsData
    {
        RootItems = new ItemDataCollection
        {
            {"Name", new ItemData {Text = "John Wood"}},
            {"Photo", new ItemData {Image = "https://example.com/images/j.wood.jpg"}}
        }
    }
};

// Specify surfaces that need to be rendered with variable data sets.
var vdpData = new DataSet()
{
    SurfacesData = new SurfaceDataCollection()
};

// Here, we bind the first and second pages with the two data sets.
vdpData.SurfacesData.Add(new SurfaceData {
            SurfaceBinding = new SurfaceBinding(new[] { 0, 1 }),
            Data = surfaceData
});

// Render personalized pages to the file cache.
var renderer = Injector.Instance.Resolve<IVdpRenderer>();
var cacheIDs = renderer.RenderHiRes(product, vdpData, config);

// Copy personalized pages from the cache to files.
var fileCache = Injector.Instance.Resolve<IFileCache>();
foreach (var id in cacheIDs)
{
    using (var stream = fileCache.GetReadStream(id))
    using (var fileStream = File.Create($"{id}"))
        stream.CopyTo(fileStream);
}
```
