Personalizing PSD Templates

PsdProcessor is a special Graphics Mill class designed for rendering PSD files. Its key features are:

Render PSD with Two Lines of Code

To render a PSD file using PsdProcessor you only need two lines of code: the first line creates a PsdProcessor instance and the second one renders the image using the Render method.

The following code reads a PSD file and merges all layers to a plain TIFF file:

var psdProcessor = new PsdProcessor();
psdProcessor.Render(@"Images\BusinessCard.psd", @"Images\Output\BusinessCard.pdf");

Getting Missing Fonts

When processing PSD files created by multiple designers, the serious problem arise - missing fonts. On practice, not so many designers would use standard Arial or Verdana. Stunning designs are typically created with some unusual fonts and you cannot rely that all of them are installed on your server.

Graphics Mill includes a mechanism which allows getting missing fonts automatically. Whenever it detects that text layers in a PSD file contain a fonts that are not presented in your system, it automatically downloads missing fonts, and you even do not need to specify font names, because they are detected automatically too.

The GetMissingFonts method allows downloading fonts from different sources:

To add a font source to PsdProcessor use the PsdProcessor.FontResolver property and its AddSource(IFontSource) method.

The following code reads a PSD file, downloads missing fonts, and renders the merged image to TIFF, if all missing fonts were downloaded correctly:

//Create a font fetcher and specify a local folder to download fonts to.
var fontResolver = new FontResolver(@"Fonts");

//Set font source for the fetcher.
//Add a local font source.
fontResolver.AddSource(new FileSystemSource(@"D:\Fonts"));
//Add Google font source.
fontResolver.AddSource(new GoogleFontSource("xxxxxxxxxxxxxx-yyyyyyyyyyyyyy-zzzzzzzzz"));
//Add Squirrel font source.
fontResolver.AddSource(new SquirrelFontSource());

var psdProcessor = new PsdProcessor(fontResolver);

var file = @"Images\BakeryBusinessCard.psd";

//Get missing fonts from the sources specified before.
var missingFonts = psdProcessor.GetMissingFonts(file);

//If there are any fonts not found in the given sources,
//output their names to the console.
if (missingFonts.Count() > 0)
    Console.WriteLine("The following fonts are not found in the given font sources: ");

    foreach (var font in missingFonts)
        Console.WriteLine("  {0}", font);
//If all fonts used in the design are available now, render the image.
    psdProcessor.Render(file, @"Images\output\BakeryBusinessCard.pdf");

You can create your own font sources by implementing the IFontSource interface.

Personalizing PSD Layers

Before PsdProcessor, you could read a PSD file, iterate through each layer and modify its content, for example, change text in text layers. As a result, you had to write a lot of code and sometimes it became overcomplicated.

The PsdProcessor implements an alternative approach. Instead of iterating through the Frames collection, you can use the PsdProcessor callbacks. Just pass a function which receives a current frame and concentrate on the logic which decides what content to insert. No need to mix this code with PSD parsing and rendering - PsdProcessor does it for you.

Let us to demonstrate this approach by personalizing a business card. We will take the same business card as described in the Merging Layers, and in the end you can compare how easier is to use PsdProcessor instead of the old approach.

Business card template with empty placeholders.

The template contains placeholders. The personalization means that these placeholders will be replaced with actual data. The business card containing person's name and position instead of the FullName and Position placeholders will look as follows:

Result image (placeholder [FullName] is replaced by the actual data).

The following code loads a PSD template and fills the placeholders with actual name, position and logo:

//Specify text personalization data
var updateTextLayers = new Dictionary<string, string>()
    {"FullName", "Andrew Simontsev"},
    {"Position", "Vice President"}

//Specify image personalization data
var updateImageLayers = new Dictionary<string, string>()
    {"CompanyLogo", @"Images\logo.png"}

var psdProcessor = new PsdProcessor();

var file = @"Images\BusinessCard.psd";

//Set the callback for rendering text frames.
psdProcessor.StringCallback = (processor, textFrame) =>
    if (updateTextLayers.ContainsKey(textFrame.Name))
        string placeholder = updateTextLayers[textFrame.Name];

        return placeholder;

    return textFrame.Text;

//Set the callback for rendering image frames.
psdProcessor.FrameCallback = (processor, frame) =>
    if ((frame.Type != FrameType.Raster) || (!updateImageLayers.ContainsKey(frame.Name)))
        return processor.ProcessFrame(frame);

    return frame.ToGraphicsContainer(ImageReader.Create(updateImageLayers[frame.Name]), ResizeMode.ImageFill);

//Render a PSD file.
psdProcessor.Render(file, @"Images\Output\BusinessCard.tif");

PsdProcessor provides three callbacks:

Besides parameters listed above each of the callback functions accepts an alias of the calling PsdProcessor object as a first parameter. This alias gives access to the calling object from a callback function.

It is convenient to use lambda expressions as demonstrated above.

See Also