Agamnentzar / ag-psd

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

Add ability to get un-transformed image data / canvas on layers with Smart Object #122

Open ericallam opened 1 year ago

ericallam commented 1 year ago

It would be great to be able to get the un-transformed image data or canvas of a layer with a Smart Object. I'd like to be able to apply a transformation (mainly the rotation) on the image data of a layer myself, mainly to drive an animation system.

Currently, the image/canvas data ag-psd provides for a smart object layer is the already transformed image data. I've attached an example PSD file and the image data of the layer inside.

rotated-smart-object.psd.zip Rectangle 1

What I'd really like is another property, maybe inside the placeLayer property, with a canvas that included the following contents for the layer:

CleanShot 2022-10-11 at 12 23 42@2x
Agamnentzar commented 1 year ago

In placedLayer you have an id property that points to psd.linkedFiles array, which contains source files for smart objects, if the file is embedded you can read the contents from data property of the linked file.

ericallam commented 1 year ago

Ah nice, that looks like it could work! Is there a documented way to go from the Uint8Array to a rendered canvas, like the other layers?

ericallam commented 1 year ago

Nevermind, I see that you can actually just read the data as a PSD file like described here

Agamnentzar commented 1 year ago

In your case you just read it as PSD. If you want to handle more general case, you can check type property to make sure it's PSD and not PNG or JPG image

ericallam commented 1 year ago

After reading the linkedFile.data as a PSD I can't seem to get a canvas with the image data. This is how I'm reading the data from the linked file and reparsing it:

const smartObject = await parse(Buffer.from(linkedFile.data));

My parse function calls readPsd with passing the buffer with the following options:

{
    skipThumbnail: false,
    skipCompositeImageData: false,
    logMissingFeatures: true,
    useImageData: false,
  }

In the Psd object that is returned, the top-level canvas data url just returns a blank white image:

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAK4AAADjCAYAAAAcyi9cAAAABmJLR0QA/wD/AP+gvaeTAAACc0lEQVR4nO3SQQ0AIBDAMMC/58MDH7KkVbDH9szMgpjzOwBeGJck45JkXJKMS5JxSTIuScYlybgkGZck45JkXJKMS5JxSTIuScYlybgkGZck45JkXJKMS5JxSTIuScYlybgkGZck45JkXJKMS5JxSTIuScYlybgkGZck45JkXJKMS5JxSTIuScYlybgkGZck45JkXJKMS5JxSTIuScYlybgkGZck45JkXJKMS5JxSTIuScYlybgkGZck45JkXJKMS5JxSTIuScYlybgkGZck45JkXJKMS5JxSTIuScYlybgkGZck45JkXJKMS5JxSTIuScYlybgkGZck45JkXJKMS5JxSTIuScYlybgkGZck45JkXJKMS5JxSTIuScYlybgkGZck45JkXJKMS5JxSTIuScYlybgkGZck45JkXJKMS5JxSTIuScYlybgkGZck45JkXJKMS5JxSTIuScYlybgkGZck45JkXJKMS5JxSTIuScYlybgkGZck45JkXJKMS5JxSTIuScYlybgkGZck45JkXJKMS5JxSTIuScYlybgkGZck45JkXJKMS5JxSTIuScYlybgkGZck45JkXJKMS5JxSTIuScYlybgkGZck45JkXJKMS5JxSTIuScYlybgkGZck45JkXJKMS5JxSTIuScYlybgkGZck45JkXJKMS5JxSTIuScYlybgkGZck45JkXJKMS5JxSTIuScYlybgkGZck45JkXJKMS5JxSTIuScYlybgkGZck45JkXJKMS5JxSTIuScYlybgkGZck45JkXJKMS5JxSTIuScYlybgkGZck45JkXJKMS5JxSTIuScYlybgkGZekC5w1BcK3t6sbAAAAAElFTkSuQmCC

The single child layer also does not have any canvas property:

CleanShot 2022-10-11 at 14 44 25@2x
ericallam commented 1 year ago

If I save out the linkedFile.data buffer to a psd file and open it all looks good though

ericallam commented 1 year ago

Looks like the child layer in the linkedFile.data PSD didn't render a canvas because it was a vector shape. Rasterizing that layer fixed the issue and I now have a canvas I can work with 👍