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.
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?
ag-psd can handle this, but the saved PSD does not render the outermost layer