Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to replace an image within a Smart Object? #173

Open
DEV-Devound opened this issue Apr 26, 2024 · 20 comments
Open

How to replace an image within a Smart Object? #173

DEV-Devound opened this issue Apr 26, 2024 · 20 comments

Comments

@DEV-Devound
Copy link

like this:
image

image

i want to replace the image within it so that photoshop does its own filters by itself. I didnt found any reference on the documentation or maybe im too lackadaisical

@Agamnentzar
Copy link
Owner

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.

@DEV-Devound
Copy link
Author

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?

@DEV-Devound
Copy link
Author

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

@Agamnentzar
Copy link
Owner

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.

@DEV-Devound
Copy link
Author

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.

Id can be whatever i want?

@Agamnentzar
Copy link
Owner

Agamnentzar commented Apr 26, 2024

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.

@DEV-Devound
Copy link
Author

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.

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;

@Agamnentzar
Copy link
Owner

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

@DEV-Devound
Copy link
Author

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

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')

@Agamnentzar
Copy link
Owner

are you sure layerToUpdate is not undefined ?

@DEV-Devound
Copy link
Author

DEV-Devound commented Apr 26, 2024

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

@DEV-Devound
Copy link
Author

DEV-Devound commented Apr 27, 2024

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

what method can i use to update layerToUpdate.canvas?

@Agamnentzar
Copy link
Owner

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

@DEV-Devound
Copy link
Author

DEV-Devound commented Apr 27, 2024

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

`

@DEV-Devound
Copy link
Author

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?

@DEV-Devound
Copy link
Author

should it work like this?
image

@houxiaohou
Copy link

You also need to update layer.canvas by drawing your PNG image onto it with correct transform from placedLayer.transform.

hi @Agamnentzar , can you explain how to draw png to layer canvas with transform please ?

@Agamnentzar
Copy link
Owner

@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;

@Agamnentzar
Copy link
Owner

@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.

@Ilanox
Copy link

Ilanox commented Jul 12, 2024

@DEV-Devound did you figure it out?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants