Agamnentzar / ag-psd

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

Could you add (fill rule / winding) to the datastructure #157

Closed sasensi closed 11 months ago

sasensi commented 11 months ago

Hi, and once again, thank you for the great library, it helps me so much. 👍

I'm currently working on creating a .psd file from scratch, including SVG paths in it, using the library. It's working quite well so far but I recently encountered a case which I can't cover properly with the current state of the library. It is about fill rule, also sometimes called winding (https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/fill-rule). When the fill rule is non zero and when I have a compound path with children having wrong orientation, I am not able to include the shape properly into the .psd file.

Until now, I was assuming that Photoshop just didn't have such a feature and that I was blocked by this (trying all kinds of workarounds). But today, I had a new idea: I copy pasted shapes from Illustrator to Photoshop and the fill rule was respected. So it means that Photoshop seems to have this feature in the end but either I was not able to find it in the doc or the UI or it is an internal hidden feature.


To take a concrete example, I worked with the svg example from the documentation: fill-rule

We can split it into 2 cases:

And when first importing those into Illustrator and then copy / pasting the shape into Photoshop, I get those files:

We can see that the right appearance is preserved.

Now, if I parse those with the library, I get almost identical results, with no trace of a fill rule data.


So I would like to ask you if you could by any chance add this to the datastructure that we can read and write ? This would help me a ton and avoid relying on other dirty workaround 😄

Thank you in advance.

Agamnentzar commented 11 months ago

Release version 18.0.0 with added fillRule field to all vector paths, I'm no 100% sure if it's correct so let me know if anything is incorrect.

sasensi commented 11 months ago

Thank you so much for the quick change ! 🙏 I'll test it tomorrow and let you know.

sasensi commented 11 months ago

Hello, I just spend some time trying to make it work but unfortunately, I could not. When writing, the newly added fillRule property doesn't seem to have the expected effect. Here's the simplest reproduction case that I could think of:

const INPUT_FILE_PATH = './local/debug.psd';

const readBuffer = fs.readFileSync(INPUT_FILE_PATH); const readData = readPsd(readBuffer, { useImageData: true }); readData.children[0].vectorMask.paths[0].fillRule = 'non-zero'; const writeBuffer = writePsd(readData); const outputFilePath = INPUT_FILE_PATH.replace('.psd', -updated-${Date.now()}.psd); fs.writeFileSync(outputFilePath, Buffer.from(writeBuffer)); open(outputFilePath);



- the generated .psd file should open automatically in Photoshop and you should see this:
![Capture d’écran 2023-10-26 101743](https://github.com/Agamnentzar/ag-psd/assets/11247504/6b446eac-a586-469a-b439-e4f87138d144)
This is exactly the same appearance as the input, while the hole of the star should be filled

I also tried writing the data that you added as a new test case here: `test/read/winding-non-zero/data.json` and the result is the same.

Hope you can help ;)
Agamnentzar commented 11 months ago

It was indeed incorrect, I released new version 18.0.1 with a fix

sasensi commented 11 months ago

This works now, thank you so much and keep up the awesome work ! 👍