I’m interesting in creating a layered tif with Java in a way that Photoshop will recognize the layers. I was able to create a multi-page tif, but Photoshop does not recognize the pages as layers. The pages are viewable with Acrobat though. Anyone know how Photoshop stores tif layer data and how that could be generated with Java?
Thanks.
2
Answers
I have researched this for my TIFF ImageIO plugin, and as far as I understand, the way Photoshop stores layer information in TIFFs is completely proprietary and not using standard TIFF mechanisms, like multi-page documents utilizing linked or nested IFDs (
330/SubIFD
), or file types (254/NewSubFileType
), etc.Instead, it stores the layer information,
along with the layer image data, in a Photoshop specific TIFF tag;
37724/ImageSourceData
, which has typeUNDEFINED
(or “just bytes”). Luckily, the contents of this tag is documented in Adobe Photoshop®TIFF Technical Notes.
The content of this tag will always start with the 0-terminated string
"Adobe Photoshop Document Data Block"
. The rest of the contents is various Photoshop resources, identified by the Photoshop 4 byte resource identifier8BIM
, followed 4 bytes resource key and 4 bytes length for each individual resource.The interesting resource in this block, with regards to Photoshop layers, is the one identified with the resource key
Layr
. This is the same structure documented in Layer and Mask Information Section in the Photoshop File Format.There’s also a different tag,
34377/Photoshop
, which contains other image resources read and written by Photoshop. It’s also documented in the Image Resources Section of the above document. It does contain some information which is interesting in regards to layers, but I’m not sure how much of this you need to write. You will probably need a Photoshop installation and test using the “real thing”.I do have code to read both of these structures in the PSD ImageIO plugin, which might be worth looking at, but it doesn’t yet support writing.
When you can write the contents Photoshop TIFF tags, you should be able to pass it to the
TIFFImageWriter
as part of the TIFFIIOMetadata
and the writer will write it along with any other metadata and pixel data you pass.So, as you see, this is all (mostly) documented and for sure doable in Java, but still not completely trivial.
I started a solution based on TinyTIFF, the answer from @haraldK on this SO question, the TIFF spec, and the Photoshop TIFF spec. It is about the simplest possible way to write a TIFF. I put in the code to write the Photoshop section, but it is not finished.
Note that Photoshop uses the TIFF image as the “preview” image, similar to the flattened composite image at the very end of a PSD file. The Photoshop TIFF section is what contains the pixel data for all the layers (again similar to a PSD). Adobe’s use of TIFF in this way is pretty dirty. You might as well just use the (also terrible) PSD format, since smashing PSD data into the TIFF format just adds complexity for no benefit. This is why I did not finish the code below. If you do finish it, please post it here.
The Output class is from Kryo.
pixmap.getPixels()
is 4 bytes per pixel, RGBA.