PSD Metadata and Real time GUI updates.

It might not be the absolute best solution, but I have been able to put into practice my idea of storing the tool settings in the PSD metadata, and it actually works pretty well.

The current setup works like this:

  • On export, go through a dictionary of controls inside the GUI and check the settings. 
  • Store each object name and it's setting as a text block with easily splittable characters. For this I chose to use ~ and | as neither of these are used for windows file or directory names. 
  • Write this text block to the PSD metadata. 
  • Meanwhile, in the export, use the GUI's current settings to determine output locations, formats and files to include.  
To reload the settings:
  • A background thread is constantly listening for any changes in the current active Photoshop document. 
  • If the name of the document changes, it automatically kicks off a function that reads the metadata out of the active PSD and splits it into objectName, setting value pairs. 
  • If no data is found, it kicks off a process to apply default settings. 
  • This data is passed to another function that finds these QT objects, and applies the relevant setting recast as the applicable object type- eg bool, int, string.
  • These settings are only saved when the document is exported. I'm expecting a little grief from the artists about this if they switch documents before exporting them at least once, so I might try to fix it. 
The Stored Metadata, ready to be read back by the tool. 
With the listener process working on a pretty short timer and a very simple function, it's possible to get what feels like real time feedback in the tool without experiencing any lag or hangs. This is the first time I've made a tool where it's a two way street- usually it's just my tool telling Photoshop what to do. It's actually pretty satisfying to click between documents in Photoshop and watch all the checkboxes of Texture Monkey light up and change. 

Main settings to be saved are the different maps and resolutions associated with the various LODs, although settings for format and destination folders are saved as well. 




Texture Monkey... version"some big number"

We are now getting Perforce. Oh how I  missed thee Perforce! And what a fantastic opportunity to revisit my favorite pet project, Texture Monkey! Be be honest, I'm kinda sick of re-writing this tool, but I've got it to a point where it meets a couple of extra prerequisites that it was sucking at before, mainly:

  • It's written at a point where I actually feel I can competently write functional and readable code.  
  • It's UI uses the QT framework. Which it MUCH nicer to work with than the previous WX. 
  • It's been built around the premise that it  should easily be portable across projects without having to change any of the source code- provided afew assumptions about project structure are met. 
  • It does more than texture exporting, and now supports Perforce integration as well. 
  • Most importantly, it is written in a modular fashion, and can be expanded upon or cut back without too much trouble. 
Now with extra stuff!
Behind the scenes:
  • It stores and loads tool settings as metadata in each PSD file, so you don't have to select those settings again when opening the file later. In addition to that, if you change the settings, then export the file, these new settings are saved to the PSD for later use. 
  • It supports exporting multiple LOD textures for different asset bundles. This is an experimental feature, and may be cut. But its fun to play around with. The idea behind this is that Unity doesn't make a distinction between different IOS devices, and instead lumps them all into one category in it's asset settings, even though there is a significant difference in specs between devices. 
  • It brings Perforce into the tool chain. When it checks out whatever active document is in Photoshop, it also brings along with it all the associated exported texture maps, basing it's search on the export locations stored in the Metadata and the source file name. 
  • I'm still thinking about adding a check in function... I kind of want to get people to check in via the P4 client, just so they have an overview of exactly what they are checking in before they actually commit it (especially if things like models are dependent on the texture changes, but fall out of the purview of this tool) For now, I have just added a function that brings the P4 client to the foreground. 
  • I have tried to add a little flexibility for other artists to be able to use this tool. It's mainly aimed at people working on textures for models, but by adding custom destinations and formats hopefully it will be of some use to export to custom locations in different formats. 
  • The configuration is all stored as an .ini file, and contains all the file naming rules, default destination folders and stuff like that. It can be hand edited, but I don't think I'm going to bother with a custom UI at this point. 
  • The Style is one billion times better, mainly due to LoneWolf's dark orange stylesheet he has provided on tech-artists.org

Writing Metadata to a PSD file using Python

I want to save some tool specific information about a PSD file, but I don't want to have another pesky metadata file floating about to bloat my source texture folder.

Luckily, the PSD file format supports writing custom MetaData within it, which is perfect for what I want to do. In this particular example, I want my tool to be able to remember which folder the flattened image associated with this PSD will eventually be put into, the format the image will be in and the resolution.

There are many fields you can write to, but I have chosen to write to the Instructions information, because that just makes the most sense. Usually in Photoshop, you can see this fields available by going to the file info panel and going to the advanced tab:

In Python, we can access and write to the PSD's metadata very easily.

import win32com.client.dynamic as w32dynamic
w32 = w32dynamic.Dispatch

psApp = w32('Photoshop.Application')
doc = psApp.activeDocument

# When I pull this info out of the Metadata I split the | into
# a list of toolObjectName~setting pairs and then
# split these pairs into a tuple of strings (toolObjectName, setting)

settings = "chkBox_res_1024~True|export_dir~c:/test/my_doc.tga|rBtn_format_tga~True"

# Now to write this to the metadata
doc.Info.Instructions = settings

# If I want to get it back out...
settings = doc.Info.Instructions
print settings


I'm still experimenting with ways of storing the settings data in a prettier way, but so far this is working well for me, although the format and information I'm saving is *very* specific to the particular tool I am writing. Still early days... but hopefully the whole Metadata thing will be handy to other people out there.