Agamnentzar / ag-psd

Javascript library for reading and writing PSD files
Other
496 stars 66 forks source link

After updating smart object data, I can't render whole psd. #147

Closed tech-White-Snow closed 1 year ago

tech-White-Snow commented 1 year ago

Thank you for this package. It is awesome. I have some issues in using this ag-psd. I want to update my old mock-up by updating smart object data. I can see that smart object data is updated in psd file, but whole image is not updated. How can I solve this problem?

This is my code snippet.

function loadCanvasFromFile(filePath1) { const img = new Image(); img.src = fs.readFileSync(filePath1); const canvas = createCanvas(img.width, img.height); canvas.getContext("2d").drawImage(img, 0, 0); return canvas; }

async function main() { const buffer = fs.readFileSync("./data/test1.psd");

// read only document structure const psd1 = readPsd(buffer, {}); const smart_object_layer = psd1.children.find((layer) => layer.name === "mm_img:Your Image"); const linked_layer = psd1.linkedFiles.find((layer) => layer.id === smart_object_layer.placedLayer?.id); linked_layer.data = loadCanvasFromFile('./data/image2.jpg').toBuffer(); const new_buffer = writePsdBuffer(psd1, {}); fs.writeFileSync("output_psd.psd", new_buffer);

}

main();

Agamnentzar commented 1 year ago

This library doesn't support re-rendering the document, as it would require re-implementing entire rendering engine of photoshop. This library only does reading and writing the data from the file. If you want to update the layer bitmap or the composite bitmap, you have to do it by yourself using something like node-canvas, sorry.

tech-White-Snow commented 1 year ago

Thank you so much for the quick response and support.

I want to implement to update mock-up in my site. How can I do? Can I implement this by using ag-psd package?

Agamnentzar commented 1 year ago

You need to draw the new image to a canvas with correct transform and then replace smart_object_layer.canvas with it in order to update layer bitmap. If you need composite bitmap updated (not needed if you just want to open it in photoshop) then you need to re-render all the layers into a canvas with correct blending modes and other effects and update psd1.canvas.

tech-White-Snow commented 1 year ago

Thank you for your great assistance.

I want to create new mock-ups by using JS code, not manual in Photoshop. How can I do? Excuse me, Can you provide simple code snippet about that?

Agamnentzar commented 1 year ago

If you just want to generate an image then you can just use node-canvas to draw an image from shapes and images, there's no need to use PSD file at all. If you want to render PSD file depending on the transforms and effects you're using you may have to write really complicated code for rendering layers pixel by pixel.

For examples of drawing with canvas you can check these tutorials: https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial

tech-White-Snow commented 1 year ago

"If you want to render PSD file depending on the transforms and effects you're using you may have to write really complicated code for rendering layers pixel by pixel." What does this mean? Please provide some advices about this.

Agamnentzar commented 1 year ago

If you just have regular layers with standard set of blending modes then you can easily just draw them using canvas api, but if you're using something like warp transform or layer effect then canvas doesn't support it out of the box and you'd have to implement that yourself.

If you want to just draw the layers then you can just create new canvas with the size of the document and then use canvas.drawImage(layer.canvas, layer.left, layer.top) function to draw each layer. For smart object layer you'll have to apply correct transform that you can read from smart_object_layer.placedLayer.

tech-White-Snow commented 1 year ago

what kind of transforms can smart_object_layer.placedLayer apply?

Agamnentzar commented 1 year ago

You can see full description here: https://github.com/Agamnentzar/ag-psd/blob/master/README_PSD.md#smart-objects

but placedLayer.transform contains coordinates of 4 corners of the transform box, so when you're drawing the smart layer you need to make sure you transform the image you're drawing in a way where it fits into that transform. This is the simple case if you just use regular smart object without any fancy warps, if you do then the information about the warp will be contained in placedLayer.warp, but in that case the drawing will be very complicated and I don't really know how to draw those.

tech-White-Snow commented 1 year ago

I just use regular smart object. Only one thing I need is to show updated image on the book cover, image is already prepared.

Agamnentzar commented 1 year ago

As I said before, this library doesn't support rendering, so it can't really be used this way, sorry.

tech-White-Snow commented 1 year ago

Thank you for your Sincerity.

jaankoppe commented 1 year ago

@tech-White-Snow But you can render the mockup with our Mediamodifier Mockup API. As I see from the code example, you got the mockup from us anyway, so why not use the API? :)

tech-White-Snow commented 1 year ago

can you describe more detail about the API?

jaankoppe commented 1 year ago

can you describe more detail about the API?

The docs can follow you through. There is also a link to a guide (which is a bit outdated currently, updated soon - we do not support base64 data for input/output anymore, only URL-s)

Basically it works like this:

  1. Upload your correctly formatted PSD inside Mediamodifier's Mockup API dashboard.
  2. Retrieve the nr of that mockup.
  3. Use it to find detailed information about that mockup (layer id, type, etc) with Get Single mockup endpoint
  4. Use that information to call Render Mockup endpoint.

https://docs.mediamodifier.com/docs/mockup-api/8ddd28e1d7dd2-getting-started-guide

tech-White-Snow commented 1 year ago

Can I try free version?

jaankoppe commented 1 year ago

Sure, you can start free with 1 mockup and 100 renders / month.

tech-White-Snow commented 1 year ago

how can i use this api in my code?

jaankoppe commented 1 year ago

I sent the link to the docs: https://docs.mediamodifier.com/docs/mockup-api/8ddd28e1d7dd2-getting-started-guide

tech-White-Snow commented 1 year ago

in free version, how much mock-ups can i use?

jaankoppe commented 1 year ago

Like I already said: 1 mockup & 100 renders / month.

tech-White-Snow commented 1 year ago

where can i see images which i can render?

jaankoppe commented 1 year ago

where can i see images which i can render?

I don't understand the questions.

You will upload your PSD file from the API dashboard. Then you will get the mockup's nr. Then make a get request like described in the docs. Then use that information to make a POST request to the render endpoint. The post request takes in the mockup template nr, then inputs as an array where each object inside the array described the changed to the layer you want to change -> image or color layer. Also available to check/uncheck other layers.

When successful, you get a JSON response, which includes the URL of the rendered image. The docs have all the examples.

tech-White-Snow commented 1 year ago

I include my image URL in get request and test in workplace. But the URL in response is the URL of mock-up image, not rendering with my image. Plz describe more detail how to use rendering API with POST request.

jaankoppe commented 1 year ago

This video was also included in the API guide: https://www.youtube.com/watch?v=cPw4bVeG_iQ

Again, the guide: https://mediamodifier.com/blog/mockup-api-guide

Get information: GET https://api.mediamodifier.com/mockup/nr/{nr} Render mockup: POST https://api.mediamodifier.com/v2/mockup/render

tech-White-Snow commented 1 year ago

where can i include my image URL?

jaankoppe commented 1 year ago
image

inside layer_inputs array, you create an object that described the smart object layer:

{
    "id": "<The placeholder layer ID you got from the GET request>",
    "data": "<Your image URL>",
    ...
}
tech-White-Snow commented 1 year ago

but it doesn't work. This is my request. { "nr": 127256, "layer_inputs": [ { "id": "f579b00b-9841-4d33-bcc7-d6dab6606998", "data": "data:image/jpeg;base64,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", "crop": { "x": 0, "y": 0, "width": 647, "height": 1400 }, "checked": true }, { "id": "ea18e8f6-1e41-4a5e-bbe2-a469e2fea45d", "checked": true, "color": { "red": 254, "green": 186, "blue": 227 } } ] }

This is response. { "success": true, "message": "Image rendered successfully", "url": "https://mediamodifier.com/temporary/UKTG9VsZFuFwcePl.jpeg" }

plz give me a feedback.

jaankoppe commented 1 year ago

layer ID should be: 9856aa41-81eb-4920-961f-3b184c01596e <-- This one you get from the single mockup request!

And please don't use base64, only publicly accessible URLs!

tech-White-Snow commented 1 year ago

Hello, @jaankoppe. I have a issue in using Mediamodifier Mockup API. Can you tell me about your contact information?