skip to Main Content

When I play the animation in photoshop, it looks fine. Every layer is in the correct position. When I run my script that saves each group to a png, the results have some layers offset.

I believe layers have weird issues with positions in animations. An image in a layer could have a different position in one frame and not another frame. I believe I’d have to get the script to step the frame in the animation to get the correct position, but I’m not sure how I would do that.

var set;
var layer;
var count = 0;
for(var i = 0; i < app.activeDocument.layerSets.length; i ++)
{
    set = app.activeDocument.layerSets[i];
    set.visible = false;
    count ++;
}
for(var i = 0; i < app.activeDocument.layerSets.length; i ++)
{
    set = app.activeDocument.layerSets[i];
    set.visible = true;

    // save
    var fileName = set.name.replace(/[\*/?:"|<> ]/g,'');
    if(fileName.length ==0) fileName = "autoname";
    var handle = File(app.activeDocument.path + "/" + fileName + ".png");
    pngSaveOptions = new PNGSaveOptions();
    activeDocument.saveAs(handle, pngSaveOptions, true, Extension.LOWERCASE);

    set.visible = false;
}

alert("Saved " + count + " images.");

The correct animation plays in photoshop. The resulting .pngs are incorrect.
https://imgur.com/a/y9PLPUX

2

Answers


  1. Chosen as BEST ANSWER

    Figured it out. This script has a function that can go to another frame in the animation. I use it to render all sub-groups of the animation to their own separate .pngs

    var set;
    var layer;
    
    for(var docI = 0; docI < app.documents.length; docI ++) {
        var doc = app.documents[docI];
        for (var frameIndex = 1; frameIndex <= 8; frameIndex++) {
            goToFrame(frameIndex);
            for (var i = 0; i < doc.layerSets.length; i++) {
                set = doc.layerSets[i];
                if (set.visible) {
                    for (var setI = 0; setI < set.layerSets.length; setI++) {
                        var innerSet = set.layerSets[setI];
                        innerSet.visible = false;
                    }
                    for (var setI = 0; setI < set.layerSets.length; setI++) {
                        var innerSet = set.layerSets[setI];
                        innerSet.visible = true;
                        var fileName = innerSet.name.replace(/[\*/?:"|<> ]/g, '');
                        if (fileName.length == 0) fileName = "autoname";
                        var handle = File(doc.path + "/output/" + doc.name.replace("player", fileName).replace(".psd", '') + (doc.layerSets.length - i) + ".png");
                        pngSaveOptions = new PNGSaveOptions();
                        activeDocument.saveAs(handle, pngSaveOptions, true, Extension.LOWERCASE);
                        innerSet.visible = false;
                    }
    
                }
            }
        }
    }
    
    alert("Saved images.");
    
    function goToFrame(index) {
        var jumpToFrameNumber = index; // counts from 1
    
        var desc = new ActionDescriptor();
        var ref1 = new ActionReference();
        ref1.putIndex( stringIDToTypeID( "animationFrameClass" ), jumpToFrameNumber );
        desc.putReference( charIDToTypeID( "null" ), ref1 );
        executeAction( charIDToTypeID( "slct" ), desc, DialogModes.NO );
    }
    

  2. If your animation is already in Photoshop timeline, maybe it’s easier just to render the animation to frames? Go to File > Export > Render Video..., Chose Photoshop Image Sequence as a renderer, PNG as a format and in Render Options don’t forget to select Straight Alpha Channel. This will render all frames to PNGs with transparency.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search