PSD Layers

Started by
4 comments, last by phantomus 18 years, 3 months ago
I've been poking around the PSD format for a couple of days now; I'm mainly looking for a way to rip apart the PSD file as an offline tool, saving out each sub-layer as a seperate PNG file, and tracking the basic layer information (layer ordering, layer name, layer bounding box). The original format is here; I suppose I could spend some time implementing it, but I'd rather not (it's just a small tool to optimize a workflow path, so I don't want to invest too much time in it.) http://www.fileformat.info/format/psd/egff.htm There are a number of libraries and source-code that read PSD files, but most of them stop at the pattern bitmap (basically the merged image), which isn't very usefull: Perhaps best example is DevIL http://sourceforge.net/projects/openil/ There's also a more isolated code-base here: http://www.codeproject.com/bitmap/MyPSD.asp Finally I've looked at using an offline tool to do the job; something like Magick, for example: http://studio.imagemagick.org/script/index.php This might in the end be the best solution; this is a workflow issue, after all, so an off the shelf tool might be a better fix. I'll throw the idea out there, and see if anyone has other suggestions.. Allan
------------------------------ BOOMZAPTry our latest game, Jewels of Cleopatra
Advertisement
If you can buy it, buy it.

If you can't, then cringing just because you have to write a little code seems kind-of counter-productive :-)
enum Bool { True, False, FileNotFound };
Quote:Original post by hplus0603
If you can buy it, buy it.


Now, if I knew WHAT to buy.. :)

Quote:Original post by hplus0603
If you can't, then cringing just because you have to write a little code seems kind-of counter-productive :-)


Well, as I said before, the other option is to tell the artist in question to go off and do this the old-fashioned way [i.e. by hand]:) If I find that the work involved exceeds the potential gains, he'll get that message. Unlike a AAA studio we don't have a dedicated tools team, and so I have to balance my time between final polish/testing on the current project, prototyping the next project, and supporting the artists, when possible, with an improved pipeline.

In other words: cheap is good, free is better... ;)

Allan
------------------------------ BOOMZAPTry our latest game, Jewels of Cleopatra
Photoshop is scriptable, you can write a VBA (or another language) script to mess with the file in Photoshop, this includes taking layers and saving them as seperate files. Alternately you can ask him to save the file in a format that does preserve layers better. Also, did you try opening the PSD files in Gimp? Last time I checked Gimp had the ability to read PSD.
Thanks for the suggestion, SiCrane; that's what I ended up doing in the end.

Since an inital trawl through google often raised the question, but never the answer, I'll post the final solution for us.

1. Downloaded the free 30day trial from Adobe
http://www.adobe.com.sg/products/photoshop/tryout.html

2. Hacked together a quick script for exporting each layer as a seperate PNG file, maintaining transparency. It's setup for our specific toolchain (so we keep our images in PNGs, stored in the top-left corner of a pow2 image). If that's not important to you, don't worry about it :)

// enable double clicking from the Macintosh Finder or the Windows Explorer#target photoshopapp.bringToFront();	// in case we double clicked the file$.level = 0;	        // debug level: 0-2 (0:disable, 1:break on error, 2:break at beginning)//debugger;		// launch debugger on next line// call the functionmain()function main() {	// no documents.. 	if (app.documents.length == 0)	{		// no image, no fun		alert( strAlertDocumentMustBeOpened );		return;	}	// the current document	var docRef = app.activeDocument;	// keep original units, or the artists will be most unhappy	var startRulerUnits = app.preferences.rulerUnits	var startTypeUnits = app.preferences.typeUnits		// then force PSD to use PIXELS as the units for the duration	app.preferences.typeUnits = TypeUnits.PIXELS;		app.preferences.rulerUnits = Units.PIXELS;        // for each layer in the file	for (var i=0; i<docRef.layers.length; i++)	{		var	ThisLayer = docRef.layers;		app.activeDocument = docRef;	    docRef.activeLayer = ThisLayer;	    		if ( ThisLayer.kind == LayerKind.NORMAL &&	ThisLayer.visible)		{				//$.write("Layer Name " + ThisLayer.name + "\n");			try {			// Copy the contents of the layer to the clipboard.			ThisLayer.copy();			var	X = ThisLayer.bounds[0];			var	Y = ThisLayer.bounds[1];			var	Width = ThisLayer.bounds[2];			var	Height = ThisLayer.bounds[3];			var ImageWidth = PadSize(Width, 16);	// we're padding it to the nearest Pow2.				var ImageHeight = PadSize(Height, 16);	// needed for later stage			$.write("[" + X + ", " + Y + ", " + ImageWidth + "["+ Width + "]," + ImageHeight + "["+ Height + "],"+ "]\n");			//Cleanup the name			//Replace ".", ":","/" with blank character			var newFileName = ThisLayer.name;			newFileName = newFileName.replace(/:/g,' ');			newFileName = newFileName.replace(/\./g,' '); 			newFileName = newFileName.replace(/\//g, ' ');			// create new document			var docRef2 = documents.add(ImageWidth,ImageHeight,docRef.resolution,										newFileName );			// Paste the contents of the clipboard to the new file.			// we're pasting to the top-left side			var selRegion = Array(Array(0, 0),			Array(Width, 0),			Array(Width, Height),			Array(0, Height),			Array(0, 0))			docRef2.selection.select(selRegion)			docRef2.paste(true);						docRef2.layers[1].visible = false;	// hide the background			// output to file						SaveImage(docRef2, newFileName);						// close the window after we're done			docRef2.close(SaveOptions.DONOTSAVECHANGES)			}				catch (e) {}	// don't care about feedback		}	}    //Deselect the last layer selected	app.activeDocument = docRef;    docRef.selection.deselect();    // Set the objects to nothing to release to the system.    docRef = null    docRef2 = null	app.preferences.typeUnits = startTypeUnits;	// restore	app.preferences.rulerUnits = startRulerUnits;}function	PadSize(ImageSize, Pad){	if (ImageSize <= Pad) return Pad;	if (Pad >= 1024) return Pad;	return PadSize(ImageSize, Pad*2);}function	SaveImage(docRef, Name){	var saveFile = new File(Name + ".png");	var SaveOptions = new ExportOptionsSaveForWeb();	SaveOptions.format = SaveDocumentType.PNG;	SaveOptions.PNG8 = false;	SaveOptions.transparency = true;	docRef.exportDocument(saveFile, ExportType.SAVEFORWEB, SaveOptions);}


There might be some bugs in there (blame the champagne), but it appears to work :) I'll spend some more time cleaning it up and handling exceptional cases later.

Allan

------------------------------ BOOMZAPTry our latest game, Jewels of Cleopatra
I recently worked on a similar problem. I used PaintLib: http://www.paintlib.de/paintlib . It effortlessly reads PSD files and gives you access to inidividual layers. I use it to create tga's from arbitrary layers and combinations of layers, as our game requires many combinations of source art and we didn't want to store all permutations.

This topic is closed to new replies.

Advertisement