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

PSD: Support writing layers #724

Open
QAQrz opened this issue Jan 3, 2023 · 3 comments
Open

PSD: Support writing layers #724

QAQrz opened this issue Jan 3, 2023 · 3 comments

Comments

@QAQrz
Copy link

QAQrz commented Jan 3, 2023

Is there any plan to support writing PSD layers?

@haraldk
Copy link
Owner

haraldk commented Jan 3, 2023

I don't need it at the moment, so there is no plan as of now. If you want to implement it yourself, I can offer some guidance. Or, you can hire me to do it for you.

The PSD format is rather complex though, so we should probably focus on a subset that's needed for the use case at hand.

@phunghv
Copy link

phunghv commented Jun 12, 2024

@haraldk I also need to write PSD layers. Could you please provide me with some instructions?

@haraldk haraldk changed the title PSD: support writing layers PSD: Support writing layers Jun 12, 2024
@haraldk
Copy link
Owner

haraldk commented Jun 12, 2024

Hi @phunghv!

If you want to implement PSD layer writing, that is great!

Most of what you need can be found in the Adobe Photoshop File Formats Specification. See the Layer and Mask Information Section for the specific data that needs to be written for the layer section and each separate layer.

The actual writing of raster data, can probably be refactored from the existing write method of the PSDImageWriter.

You probably want to refactor the write method to look like this:

    @Override
    public void write(final IIOMetadata streamMetadata, final IIOImage image, final ImageWriteParam param) throws IOException {
        prepareWriteSequence(streamMetadata); // Set stream byte order, and initial state for sequenced writing
        writeToSequence(image, param); // ...but the header needs to be deferred to the first write, as it depends on image data
        endWriteSequence(); // Reset internal state
    }

...and split the existing method into these methods. The above methods are all part of the ImageWriter API. See the TIFFImageWriter for an example implementation on how to manage state, exceptions etc.

You also need to override canWriteSequence:

    @Override
    public boolean canWriteSequence() {
        return true;
    }

Now, the tricky parts...

In PSD, layers are written in a separate section, apart from the "merged" or "composite" image (this composite image is what the current write implementation writes). So you might need to split this and the actual layer writing.

Ideally, for the best compatibility with the writer, the first image should be the composite image, and the layers should follow (this is not a hard requirement, but highly preferable). But in the actual file format, the order is "layer 0", "layer 1" ... "layer N", "composite", which complicates things, as you don't know the number or size of the layers up front.

In a PSD document, all layers and composite image shares certain properties (ie. color model, bit depth, etc), this probably has to be validated for each write, to make sure we write valid PSDs.

There's also image and stream metadata to take into account, if you want to preserve/specify things like layer names, visibility etc, or global settings. Unfortunately, the current metadata implementation is not suited for this, and needs to be completely refactored to a stream metadata (document globals and other shared data) and image metadata (composite and layer specifics). This is probably more work than simply writing the layers, so if you don't need it, just skip it and write minimal layer info.

Hope that gives you some pointers on how to start, and where to find the info you need. 😀

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

No branches or pull requests

3 participants