Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Yet Another PSD Parser

0.00/5 (No votes)
10 Oct 2006 1  
Read/write Photoshop PSD files, serialize to XML, extract layer bitmaps, and more.

Main window

A simple host application for testing the API. Main window: Drag'n'drop a PSD file, select which layer to inspect (or Global for the merged image and global data).

Xml window

XML inspector: For viewing all data in the document. Shows info about the selected layer or global info.

Introduction

This is a work in progress that aims to give .NET developers full control over Photoshop PSD files. All features aren't covered by the library, and there are, without doubt, some documents it will choke on, but with good feedback from users, this will hopefully be fixed over time.

The main usage of the API is for reading and writing PSD files from your own applications. It can also be used as a reference for writing parsers for non-.NET languages. Thanks to the XML serializing feature, it can easily be used for investigating unknown tags (or for implementing a zip-style file format; XML settings plus PNG files for channel data).

Examples of PSD sections it can handle:

  • Individual layers, including extracting their bitmaps, transparencies and masks
  • Global channels
  • Slices, Grid/Guides, Thumbnails
  • Vector Paths
  • Layer effects (shadows, glows etc.)
  • Adjustment layers (Brightness/Contrast, Curves, Levels etc.)
  • Text layers (well, not really; there's an ocean of data for a simple text layer, and I don't know what half of it is for, but strictly speaking they're being parsed)

Note that it is not a PSD renderer; this library is for manipulating the files themselves. I will implement the most important rendering features in PaintLab, and possibly make it available as a DLL for immediate rendering (i.e. without opening the paint app itself).

Background

A few years back, I wanted to decode parts of the PSD format in order to speed up the production pipeline for a project. I looked at the available parsers, both commercial and open source, but none of them had the features I needed, nor a design I felt comfortable with, so I decided to write my own by using the SDK. But after finding out how closely Adobe guarded the secrets of their format, and that I wouldn't be able to sign their harsh SDK license agreement, I knew I would have to do it the hard way.

Reverse engineering is a tedious process (thus slow), and with the project where I needed the parser gone by, I didn't put much time on it.

Then I started working on the paint application PaintLab, and I realized that PSD support was probably one of the most important features - without it, there is no chance of Photoshop users even considering using the program. So, instead of working with the interesting features of PaintLab, I've had to put a fair amount of time into examining the PSD format, while cursing the fact that such a widely used format has no decent open source codec. I hope my work here can save other people's time, and help them being creative instead of dealing with the boring details of a file format.

With this project, I think I've managed to create a decent architecture, but there's still work to be done before it has a 100% compatibility with PSD files.

Using the code

As the code is part of the Endogine project, and uses several of the its classes, Endogine.dll has to be available for referencing. The host app also uses Endogine.Editors.dll for the XML editor.

The API is currently a pretty straightforward reflection of the PSD file structure:

using Endogine.Codecs.Photoshop;
using Endogine.Codecs.Photoshop.ImageResources;
using Endogine.Codecs.Photoshop.LayerResources;

Document psd = new Document("somefile.psd");

int documentHeight = psd.Header.Rows;
//get the height of the document


//get GridGuidesInfo ImageResource

GridGuidesInfo guidesInfo = 
  (GridGuidesInfo)psd.GetResource(typeof(GridGuidesInfo));
Console.WriteLine("Guide location: " + 
        guidesInfo.Guides[0].LocationInPixels);

Bitmap bmp = psd.Layers[0].Bitmap;
//get layer 0 bitmap


//get transparency bitmap of layer 1

Bitmap bmpChannel = psd.Layers[1].Channels[-1].Bitmap;
BrightnessContrast bc = (BrightnessContrast)
   psd.Layers[2].GetResource(typeof(BrightnessContrast));
Console.WriteLine("Layer 2 (Adjustment layer) Brighness: " + 
                  bc.Brightness);

psd.SaveXml("somefile.xml", true);
//save as XML file, and export layer bitmaps as PNGs

Points of Interest

The newer Photoshop SDKs, which include the file format specifications, are protected by a license agreement that compromises the usability of code produced by anyone who has signed it. That's why I've had to use reverse engineering for creating many parts of the code, and why it's taking so long to complete it.

If you want to contribute to the project, please understand that I won't accept code from anyone who has signed an Adobe SDK agreement. That could potentially mean trouble ahead, the day evil Adobe wants to shut down this subversive operation.

If the program fails to load a document, please add a note about it in the comments section below and keep the file around - if I have time, I'll ask you to send it to me for closer inspection. Note that I currently only have interest in documents created with Photoshop version 6 or later.

TODO

  • Understand the properties of text layer tags (TySh and Txt2). They seem extremely bloated; help with these would be very welcome.
  • Better access of data in Descriptor tags
  • Implement write functionality in all classes
  • Make sure it always writes correct PSD files
  • Deserialize from XML / PNGs
  • Implement ICC parser
  • Investigate what the tags marked as Unknown are for
  • Error handling

So far, I've only cared about RGB, 8-bit per channel images. Other formats are implicitly supported (channel data is treated the same way), but there's no specific functionality for them, like converting to RGB color space. Should you need color space conversion, there are classes for that in the Endogine.ColorEx namespace.

License

This project uses the BSD license. You are free to use the code or the binaries however you want, including commercially, as long as the copyright notice and license text are included as specified in LICENSE.txt (comes with the zip files). 

History

  • 2006-10-08 - First draft of the library.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here