---
title: "Rendering Products"
canonical: https://customerscanvas.com/docs/cc6/rendering-products-in-daf.htm
archived: true
applies_to:
  - product: "Customer's Canvas On-Premises"
  - product: "Design Atoms .NET"
    versions: ["6.15.0", "6.x (may differ)"]
---

**You’re viewing outdated documentation.** [View the latest Customer’s Canvas On-Premises documentation](https://customerscanvas.com/docs/on-premises/).

# Rendering Products

**Applies to:** Customer's Canvas On-Premises; Design Atoms .NET 6.15.0, 6.x (may differ) · **Archived documentation**
 
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/cc6/T_Aurigma_DesignAtoms_Rendering_IProductRenderer.htm.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/cc6/using-dependency-injection.htm.md) as follows:
 
```csharp
var renderer = Injector.Instance.Resolve<IProductRenderer>();
```
 
## Rendering Proof Images
  
To generate a product preview, you can use the [IProductRenderer.RenderProof](https://customerscanvas.com/docs/cc6/M_Aurigma_DesignAtoms_Rendering_IProductRenderer_RenderProof_5_d06a095b.htm.md) method.
 
```csharp
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
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
var hiresIds = productRenderer.RenderHiRes(product);
```
 
For example, the [RenderHiRes(Product, RenderingConfig)](https://customerscanvas.com/docs/cc6/M_Aurigma_DesignAtoms_Rendering_ProductRenderer_RenderHiRes_2_de0d1c0b.htm.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
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.
 
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
// 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, you can use dedicated methods of **IVdpRenderer**. 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/cc6/web-api-for-rendering.htm.md).
 
In the following example, we render four product pages by using two surfaces and two data sets for the personalization.
 
```csharp
// 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);
}
```
 
## See Also
  
### Manual
 
- [Design Atoms Framework Overview](https://customerscanvas.com/docs/cc6/design-atoms-fw.htm.md)
- [Working with the Object Model](https://customerscanvas.com/docs/cc6/using-design-atoms-fw.htm.md)
- [Using Dependency Injection](https://customerscanvas.com/docs/cc6/using-dependency-injection.htm.md)

### Reference
 
- [IProductRenderer Class](https://customerscanvas.com/docs/cc6/T_Aurigma_DesignAtoms_Rendering_IProductRenderer.htm.md)

### Other
 
- [Design Atoms sample project↗](https://github.com/aurigma/DesignAtomsSamples)
