Use Node.js (and NPM package 'psd') to parse Adobe PSD file, programatically replace image layer and then save/render as PNG
Asked Answered
S

1

11

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?

Strengthen answered 31/8, 2017 at 18:0 Comment(4)
do you have the algorithm for skewing the image ? because simple "replacing" layers will not do the job in this instanceLetti
Did you ever figure this out in Node?Jessabell
@Jessabell no, I did not.Strengthen
@JochemStoel have you, by any chance, resolved the issue? I am looking for something similar. Thanks.Overlong
D
0

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

Detradetract answered 4/9, 2021 at 1:18 Comment(2)
Please provide additional details in your answer. As it's currently written, it's hard to understand your solution.Interlining
This does not provide an answer to the question. Once you have sufficient reputation you will be able to comment on any post; instead, provide answers that don't require clarification from the asker.Ultramundane

© 2022 - 2024 — McMap. All rights reserved.