How to replace an image within a Smart Object?
DEV-Devound opened this issue · 21 comments
See section on smart objects: https://github.com/Agamnentzar/ag-psd/blob/master/README_PSD.md#smart-objects
Be aware that updating smart objects has the same issues that updating text or vector layers, PSD file keep s prerendered version of the layer and you have to update that bitmap yourself, the library will not do that for you.
See section on smart objects: https://github.com/Agamnentzar/ag-psd/blob/master/README_PSD.md#smart-objects
Be aware that updating smart objects has the same issues that updating text or vector layers, PSD file keep s prerendered version of the layer and you have to update that bitmap yourself, the library will not do that for you.
and how can i update it?
See section on smart objects: https://github.com/Agamnentzar/ag-psd/blob/master/README_PSD.md#smart-objects
Be aware that updating smart objects has the same issues that updating text or vector layers, PSD file keep s prerendered version of the layer and you have to update that bitmap yourself, the library will not do that for you.
i saw that but i cant figure out how can i insert a PNG image into that code
You need to add the file to psd.linkedFiles
like this:
psd.linkedFiles = [
{
"id": "20953ddb-9391-11ec-b4f1-c15674f50bc4",
"name": "cat.png"
"data": fileContentsAsUint8Array,
}
];
and then refer to that file by the id
in placedLayer
field like this:
layer.placedLayer = {
"id": "20953ddb-9391-11ec-b4f1-c15674f50bc4", // id that matches linkedFiles ID
"placed": "20953dda-9391-11ec-b4f1-c15674f50bc4", // unique id for this object
"type": "raster", // one of the 'unknown', 'vector', 'raster' or 'image stack'
"transform": [ // x, y of 4 corners of the transform box
29,
28,
83,
28,
83,
82,
29,
82
],
"width": 32, // width and height of the target image
"height": 32,
"resolution": {
"value": 299.99940490722656,
"units": "Density"
}
};
You also need to update layer.canvas
by drawing your PNG image onto it with correct transform from placedLayer.transform
.
You need to add the file to
psd.linkedFiles
like this:psd.linkedFiles = [ { "id": "20953ddb-9391-11ec-b4f1-c15674f50bc4", "name": "cat.png" "data": fileContentsAsUint8Array, } ];and then refer to that file by the
id
inplacedLayer
field like this:layer.placedLayer = { "id": "20953ddb-9391-11ec-b4f1-c15674f50bc4", // id that matches linkedFiles ID "placed": "20953dda-9391-11ec-b4f1-c15674f50bc4", // unique id for this object "type": "raster", // one of the 'unknown', 'vector', 'raster' or 'image stack' "transform": [ // x, y of 4 corners of the transform box 29, 28, 83, 28, 83, 82, 29, 82 ], "width": 32, // width and height of the target image "height": 32, "resolution": { "value": 299.99940490722656, "units": "Density" } };You also need to update
layer.canvas
by drawing your PNG image onto it with correct transform fromplacedLayer.transform
.
Id can be whatever i want?
I don't know, it seems photoshop puts GUIDS there, so I'd advise to use something in the same format, in case Photoshop expects it to be like that.
You need to add the file to
psd.linkedFiles
like this:psd.linkedFiles = [ { "id": "20953ddb-9391-11ec-b4f1-c15674f50bc4", "name": "cat.png" "data": fileContentsAsUint8Array, } ];and then refer to that file by the
id
inplacedLayer
field like this:layer.placedLayer = { "id": "20953ddb-9391-11ec-b4f1-c15674f50bc4", // id that matches linkedFiles ID "placed": "20953dda-9391-11ec-b4f1-c15674f50bc4", // unique id for this object "type": "raster", // one of the 'unknown', 'vector', 'raster' or 'image stack' "transform": [ // x, y of 4 corners of the transform box 29, 28, 83, 28, 83, 82, 29, 82 ], "width": 32, // width and height of the target image "height": 32, "resolution": { "value": 299.99940490722656, "units": "Density" } };You also need to update
layer.canvas
by drawing your PNG image onto it with correct transform fromplacedLayer.transform
.
A friend of mine helped me with the code but when i debugged it, it didnt worked, what maybe wrong here?
const newImageBuffer = fs.readFileSync('Profile.png');
const newImageId = "20953ddb-9391-11ec-b4f1-c15674f50bc4"; // Este ID debe ser único
psd.linkedFiles = [{
id: newImageId,
name: "Profile.png",
data: newImageBuffer
}];
const layerToUpdate = psd.children.find(layer => layer.name === "profile");
layerToUpdate.placedLayer.id = newImageId;
data
should be Uint8Array, you also will not see the new image unless you update the smart object in Photoshop. To see the change right away you need to update layerToUpdate.canvas
data
should be Uint8Array, you also will not see the new image unless you update the smart object in Photoshop. To see the change right away you need to updatelayerToUpdate.canvas
new code
` const newImageBuffer = fs.readFileSync('Profile.png');
const newImage8Array = new Uint8Array(newImageBuffer);
console.log(newImage8Array)
const newImageId = "20953ddb-9391-11ec-b4f1-c15674f50bc4"; // Este ID debe ser único
psd.linkedFiles = [{
id: newImageId,
name: "Profile.png",
data: newImage8Array
}];
const layerToUpdate = psd.children.find(layer => layer.name === "profile");
layerToUpdate.placedLayer.id = newImageId;
layerToUpdate.canvas
`
and this is the new error
Server started on port 3000
Michael
Jackson
Uint8Array(64757) [
137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13,
73, 72, 68, 82, 0, 0, 4, 176, 0, 0, 4, 176,
8, 6, 0, 0, 0, 235, 33, 179, 207, 0, 0, 0,
4, 103, 65, 77, 65, 0, 0, 177, 143, 11, 252, 97,
5, 0, 0, 0, 32, 99, 72, 82, 77, 0, 0, 122,
38, 0, 0, 128, 132, 0, 0, 250, 0, 0, 0, 128,
232, 0, 0, 117, 48, 0, 0, 234, 96, 0, 0, 58,
152, 0, 0, 23, 112, 156, 186, 81, 60, 0, 0, 0,
6, 98, 75, 71,
... 64657 more items
]
TypeError: Cannot read properties of undefined (reading 'placedLayer')
are you sure layerToUpdate
is not undefined ?
are you sure
layerToUpdate
is not undefined ?
thanks, that was the problem, but now its having the same error of the text layer, can something be done to solve this?
I did the layerToUpdate.canvas
but isnt working like intended
data
should be Uint8Array, you also will not see the new image unless you update the smart object in Photoshop. To see the change right away you need to updatelayerToUpdate.canvas
what method can i use to update layerToUpdate.canvas
?
You just assign it a new canvas, node-canvas has the same api as regular javascript canvas: https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API
You just assign it a new canvas, node-canvas has the same api as regular javascript canvas: https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API
should this work?
`const newImageBuffer = fs.readFileSync('Profile.png');
const newImage8Array = new Uint8Array(newImageBuffer);
console.log(newImage8Array)
const newImageId = "20953ddb-9391-11ec-b4f1-c15674f50bc4"; // Este ID debe ser único
psd.linkedFiles = [{
id: newImageId,
name: "Profile.png",
data: newImage8Array
}];
const layerToUpdate = psd.children.find(layer => layer.name === "profile");
layerToUpdate.placedLayer.id = newImageId;
canvasUpdated = layerToUpdate
`
You just assign it a new canvas, node-canvas has the same api as regular javascript canvas: https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API
do you have any code doing so? Or how can i implement what you just said into my code?
You also need to update
layer.canvas
by drawing your PNG image onto it with correct transform fromplacedLayer.transform
.
hi @Agamnentzar , can you explain how to draw png to layer canvas with transform please ?
@DEV-Devound You need to assign new canvas to layer.canvas
:
const newCanvas = createCanvas(width, height);
// TODO: draw image to newCanvas with correct transform
layer.canvas = newCanvas;
@houxiaohou placedLayer.transform
field specifies 4 corners of transformed image, there's no ready-made operation in regular canvas API that handles that. In a lot of cases transform is just move+scale+rotation, so in that situation you can just use standard operations on canvas with translate
, rotate
and scale
functions. But it free transform or perspective transform was used then you can't do that and you'd have to write the transform yourself or find some library that does that.
@DEV-Devound did you figure it out?