Jump to content
  • Advertisement
Sign in to follow this  
__ODIN__

PSD Layers

This topic is 4527 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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

Share this post


Link to post
Share on other sites
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 :-)

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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 photoshop
app.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 function
main()

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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!