Security News
Research
Supply Chain Attack on Rspack npm Packages Injects Cryptojacking Malware
A supply chain attack on Rspack's npm packages injected cryptomining malware, potentially impacting thousands of developers.
A general purpose PSD parser written in Coffeescript. Based off of PSD.rb. It allows you to work with a Photoshop document in a manageable tree structure and find out important data such as:
Runs in both NodeJS and the browser (using browserify). There are still some pieces missing that are present in PSD.rb, such as layer comp filtering, a built-in renderer, and many layer info blocks. The eventual goal is full feature parity with PSD.rb.
PSD.js has no native dependencies. Simply add psd
to your package.json or run npm install psd
.
PSD.js works almost exactly the same in the browser and NodeJS.
var PSD = require('psd');
var psd = PSD.fromFile("path/to/file.psd");
psd.parse();
console.log(psd.tree().export());
console.log(psd.tree().childrenAtPath('A/B/C')[0].export());
// You can also use promises syntax for opening and parsing
PSD.open("path/to/file.psd").then(function (psd) {
return psd.image.saveAsPng('./output.png');
}).then(function () {
console.log("Finished!");
});
var PSD = require('psd');
// Load from URL
PSD.fromURL("/path/to/file.psd").then(function(psd) {
document.getElementById('ImageContainer').appendChild(psd.image.toPng());
});
// Load from event, e.g. drag & drop
function onDrop(evt) {
PSD.fromEvent(evt).then(function (psd) {
console.log(psd.tree().export());
});
}
To access the document as a tree structure, use psd.tree()
to get the root node. From there, work with the tree using any of these methods:
root()
: get the root node from anywhere in the treeisRoot()
: is this the root node?children()
: get all immediate children of the nodehasChildren()
: does this node have any children?childless()
: opposite of hasChildren()
ancestors()
: get all ancestors in the path of this node (excluding the root)siblings()
: get all sibling tree nodes including the current one (e.g. all layers in a folder)nextSibling()
: gets the sibling immediately following the current nodeprevSibling()
: gets the sibling immediately before the current nodehasSiblings()
: does this node have any siblings?onlyChild()
: opposite of hasSiblings()
descendants()
: get all descendant nodes not including the current onesubtree()
: same as descendants but starts with the current nodedepth()
: calculate the depth of the current node (root node is 0)path()
: gets the path to the current nodeIf you know the path to a group or layer within the tree, you can search by that path. Note that this always returns an Array because layer/group names do not have to be unique. The search is always scoped to the descendants of the current node, as well.
psd.tree().childrenAtPath('Version A/Matte');
psd.tree().childrenAtPath(['Version A', 'Matte']);
To get data such as the name or dimensions of a layer:
node = psd.tree().descendants()[0];
node.get('name');
node.get('width');
PSD files also store various pieces of information in "layer info" blocks. See this file for all of the possible layer info blocks that PSD.js parses (in LAYER_INFO
). Which blocks a layer has varies from layer-to-layer, but to access them you can do:
node = psd.tree().descendants()[0]
node.get('typeTool').export()
node.get('vectorMask').export()
When working with the tree structure, you can recursively export any node to an object. This does not dump everything, but it does include the most commonly accessed information.
console.log(psd.tree().export());
Which produces something like:
{ children:
[ { type: 'group',
visible: false,
opacity: 1,
blendingMode: 'normal',
name: 'Version D',
left: 0,
right: 900,
top: 0,
bottom: 600,
height: 600,
width: 900,
children:
[ { type: 'layer',
visible: true,
opacity: 1,
blendingMode: 'normal',
name: 'Make a change and save.',
left: 275,
right: 636,
top: 435,
bottom: 466,
height: 31,
width: 361,
mask: {},
text:
{ value: 'Make a change and save.',
font:
{ name: 'HelveticaNeue-Light',
sizes: [ 33 ],
colors: [ [ 85, 96, 110, 255 ] ],
alignment: [ 'center' ] },
left: 0,
top: 0,
right: 0,
bottom: 0,
transform: { xx: 1, xy: 0, yx: 0, yy: 1, tx: 456, ty: 459 } },
image: {} } ] } ],
document:
{ width: 900,
height: 600,
resources:
{ layerComps:
[ { id: 692243163, name: 'Version A', capturedInfo: 1 },
{ id: 725235304, name: 'Version B', capturedInfo: 1 },
{ id: 730932877, name: 'Version C', capturedInfo: 1 } ],
guides: [],
slices: [] } } }
You can also export the PSD to a flattened image. Please note that, at this time, not all image modes + depths are supported.
png = psd.image.toPng(); // get PNG object
psd.image.saveAsPng('path/to/output.png').then(function () {
console.log('Exported!');
});
This uses the full rasterized preview provided by Photoshop. If the file was not saved with Compatibility Mode enabled, this will return an empty image.
FAQs
A general purpose Photoshop file parser.
The npm package psd receives a total of 885 weekly downloads. As such, psd popularity was classified as not popular.
We found that psd demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 3 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Research
A supply chain attack on Rspack's npm packages injected cryptomining malware, potentially impacting thousands of developers.
Research
Security News
Socket researchers discovered a malware campaign on npm delivering the Skuld infostealer via typosquatted packages, exposing sensitive data.
Security News
Sonar’s acquisition of Tidelift highlights a growing industry shift toward sustainable open source funding, addressing maintainer burnout and critical software dependencies.