For a project I need to to parse an Adobe Photoshop PSD file, programatically find and replace an image layer and then save it back to a PSD file and/or export it as PNG (or JPEG). I do not have a lot of experience with Adobe Photoshop but I think these types of layers are called 'smart layers'.

The use case:

Render mockup preview image

  • User uploads image to Node HTTP server
  • Replace layer in PSD with uploaded image (image fill layer)
  • Render as PNG/JPEG and write to HTTP response

The replacement layer is 3d skewed over x and y for a mockup template. I have included an image to illustrate what this means. Additional mockup templates will be created in the future which is why I think labeling the replacement layer with a constant value is the way to implement this.

The template file: template file

The uploaded image: uploaded image

The final rendered image output image

I don't need help with the HTTP server/authentication etc, that part is trivial. I am only looking for a method to replace the image layer.

The PSD files are/will be custom made for this particular project. To identify the right layer to replace based on the layer name (label) is an acceptable implementation.

I have had a look at several NPM packages to do this job but was not able to get a functioning prototype. This package seems the most promising.

https://www.npmjs.com/package/psd

I currently have the following code:

/* mockup.js */
var PSD = require('psd')
var psd = PSD.fromFile("mockup.psd")
var fs = require('fs')

psd.parse()

/* For easier reference */
var replacementLayer, file, fileBuffer

let tree = psd.tree()

let layers = tree.layer.node._children

for(let layer of layers) {
    /* i named the layer 'replacementLayer' */
    if(layer.name == 'replacementLayer') { 
        replacementLayer = layer 
        file = replacementLayer.layer.file
        fileBuffer = replacementLayer.layer.file.data
    }
}

/* replacementLayer = instanceof Layer
   file = instanceof File with a property 'data' (data is a buffer)
   fileBuffer = instanceof Buffer */   

I tried various ways of opening an image file and replacing the replacementLayer in the PSD but I can't get it to work. Simply overwriting the property with a new Buffer object is not enough.

Saving the image as a PNG is as simple as

psd.image.saveAsPng('./output.png')

Ideally, the image that is used to replace the replacementLayer should 'fill' to the width and height of the layer.

Any ideas?

1

There are 1 answers

2
Yipu Xie On

ag-psd can handle this, but the saved PSD does not render the outermost layer