Skip to main content
Participant
March 15, 2013
Question

Script: convert layer comps to spritesheet

  • March 15, 2013
  • 1 reply
  • 1569 views

The goal: Given a file containing multiple layer comps, copy these comps into a new image to make a spritesheet.

The problem: Random errors. The code throws an error on when i run the script through the menu

Error 8800: General Photoshop error occurred. This functionality may not be available in this version of Photoshop.

- The command “Get” is not currently available.

Line: 64

->          sprite.activeHistoryState = sprite.historyStates[curHistory-1];

I have no clue what i am doing wrong, any help appreciated!

My code:

#target photoshop

// Save the current preferences

var startRulerUnits = app.preferences.rulerUnits

var startTypeUnits = app.preferences.typeUnits

var startDisplayDialogs = app.displayDialogs

// Set Adobe Photoshop CS6 to use pixels and display no dialogs

app.preferences.rulerUnits = Units.PIXELS

app.preferences.typeUnits = TypeUnits.PIXELS

app.displayDialogs = DialogModes.NO

var sprite = app.activeDocument

var spritesheet = '';

function main(){

// get the sprite dimensions

    var spWidth =  sprite.width;

    var spHeight = sprite.height;

// get its base history to revert to after merging layers

    var curHistory = sprite.historyStates.length  

   

// create the spritesheet file at the right dimensions

    spritesheet = app.documents.add(sprite.layerComps.length * sprite.width,sprite.height, 72, "Sprite", NewDocumentMode.RGB, DocumentFill.TRANSPARENT);   

   

// loop through the layercomps in the original sprite file

    for( var c = 0; c < sprite.layerComps.length; c++ ){

       

// set the active document to the sprite

        app.activeDocument = sprite

// set the approriate layer comp       

        sprite.layerComps.apply();

// attempt to merge the visible elements

        try{

            sprite.mergeVisibleLayers();

        }catch(e){

           

        }

// select the sprite and copy the merged content   

        sprite.selection.selectAll();

        sprite.selection.copy() ; 

// work out the correct coords for a selection on the spritesheet      

        var xPos = spWidth * c;

        var selRegion = Array(Array(xPos,0),

        Array(xPos + spWidth, 0),

        Array(xPos + spWidth,  spHeight),

        Array(xPos, spHeight),

        Array(xPos , 0));

// change the active doc to the spritesheet, add a new layer set and paste the copied data into it       

        app.activeDocument = spritesheet

        var newLayer = spritesheet.layerSets.add();

        spritesheet.selection.select(selRegion);

        spritesheet.paste() ;

       

// set the active document back to the sprite and then revert the history to the state when we started       

        app.activeDocument = sprite;

        sprite.activeHistoryState = sprite.historyStates[curHistory-1];

// keep looping if need be

    }

}

main();

// Reset the application preferences

app.preferences.rulerUnits = startRulerUnits

app.preferences.typeUnits = startTypeUnits

app.displayDialogs = startDisplayDialogs

This topic has been closed for replies.

1 reply

Paul Riggott
Inspiring
March 15, 2013

You could try getting/setting the history states like this..


var savedState = activeDocument.activeHistoryState;
activeDocument.activeHistoryState = savedState;

Also I would change:-
spritesheet.paste(); to  spritesheet.paste(true);
So that it pastes into the selection.

drbroadAuthor
Participant
March 22, 2013

Hi Paul,

Thank you for your response on this - the history state heads up was particularly useful.

I ran into another issue which probably deserves its own post. But as it pertains to this task i will post it here first.

The problem occurs when copying layers that contain transparency. If the layer comp movements occur within the bounds of the sprite - it isnt a problem.

An over simplified description: We have a circle that starts in the top left, and over say 10 frames, is moved to the bottom right. When I copy this layer - the bounds of the sprite havent changed, but the position has. Photoshop trims the selection to exclude the transparent pixels of that layer.

When i paste it into my selection in the spritesheet file - it centers the circle. You end up with 10 frames that all look the same!

If anyone knows a way we can force photoshop to honour the position / not trim the transparent pixels - I would love to know.

Paul Riggott
Inspiring
March 22, 2013

Yes I have had the same problem, what I did was colour a pixel at each corner and set the opacity very low so it isn't visible but it is still honoured.

N.B. make sure you have rulerunits set to pixels.

function pinCorners(){

var Width =activeDocument.width.value;

var Height =activeDocument.height.value;

var fillColour = new SolidColor;

fillColour.rgb.hexValue = 'ffffff';

activeDocument.selection.select([[0,0],[1,0],[1,1],[0,1]], SelectionType.REPLACE, 0, false);

activeDocument.selection.fill(fillColour,undefined,1);

activeDocument.selection.deselect();

activeDocument.selection.select([[(Width-1),0],[Width,0],[Width,1],[(Width-1),1]], SelectionType.REPLACE, 0, false);

activeDocument.selection.fill(fillColour,undefined,1);

activeDocument.selection.deselect();

activeDocument.selection.select([[(Width-1),(Height-1)],[Width,(Height-1)],[Width,Height],[(Width-1),Height]], SelectionType.REPLACE, 0, false);

activeDocument.selection.fill(fillColour,undefined,1);

activeDocument.selection.deselect();

activeDocument.selection.select([[0,(Height-1)],[1,(Height-1)],[1,Height],[0,Height]], SelectionType.REPLACE, 0, false);

activeDocument.selection.fill(fillColour,undefined,1);

activeDocument.selection.deselect();

}