Skip to main content
November 19, 2011
Answered

Setting variable "Frame Delay" for animation.

  • November 19, 2011
  • 1 reply
  • 1432 views

I am trying to set frame delay in an animation I am working on. There are a lot of frames and they all have different delays. I am not sure if scripting is the best way but here is what I have so far (using VBA because that is what I am familiar with): I am erroring out at line 23 saying it is a "type mismatch"

  1. Sub Set_Frame_Delay()
  2.     Dim appPS As Photoshop.Application
  3.     Dim docPS As Photoshop.Document
  4.     Dim NewLay  As Photoshop.ArtLayer
  5.     Dim LaySet As Photoshop.LayerSet
  6.     Dim ref1 As Photoshop.ActionReference
  7.     Dim actPS
  8.    
  9.    
  10.     Set appPS = CreateObject("Photoshop.Application")
  11.     appPS.Visible = True
  12.    
  13.     Set docPS = appPS.ActiveDocument
  14.     Set LaySet = docPS.LayerSets("Text")
  15.     Set ref1 = CreateObject("Photoshop.ActionReference")
  16.    
  17.    
  18.     For Each NewLay In LaySet.ArtLayers
  19.             Select Case NewLay.Name
  20.        
  21.             Case "Test1"
  22.        
  23.                 actPS = ref1.PutName("Frame Delay", 0.540769)
  24.                 NewLay.Application.ExecuteAction (actPS)
  25.        
  26.             Case "Test2"
  27.                 actPS = ref1.PutName("Frame Delay", 1.013942)
  28.                NewLay.Application.ExecuteAction (actPS)
  29.           End Select
  30.       Next NewLay
  31.    
  32.     MsgBox "frame set"
  33.    
  34. End Sub

This topic has been closed for replies.
Correct answer

Yeah Ive used the script listener before, but was hoping to avoid it because I didn't understand everything that it spits out. But I think I broke it down and I came up with below. I tweeked my original solution to use a text file.

Sub Set_Frame_Delay3()

    Dim appPS As Photoshop.Application

    Dim ActDescPS1 As Photoshop.ActionDescriptor, ActDescPS2 As Photoshop.ActionDescriptor, ActDescPS3 As Photoshop.ActionDescriptor

    Dim ActRefPS1 As Photoshop.ActionReference, ActRefPS2 As Photoshop.ActionReference

    Dim dialogMode

    Dim idsetd, idnull, idOrdn, idTrgt, idT, idslct

    Dim idAniFrClass, idAniFrDelay

    Dim sFileName As String

    Application.ScreenUpdating = False

    Set appPS = New Photoshop.Application

    appPS.Visible = True

    dialogMode = 3

    With appPS

        idsetd = .CharIDToTypeID("setd")

        idnull = .CharIDToTypeID("null")

        idOrdn = .CharIDToTypeID("Ordn")

        idTrgt = .CharIDToTypeID("Trgt")

        idT = .CharIDToTypeID("T   ")

        idslct = .CharIDToTypeID("slct")

        idAniFrClass = .StringIDToTypeID("animationFrameClass")

        idAniFrDelay = .StringIDToTypeID("animationFrameDelay")

    End With

    sFileName = Application.GetOpenFilename("Textfiles (*.txt),*.txt", , "Open a textfile...")

    oIndex = 0

    iFileNum = FreeFile()

    Open sFileName For Input As iFileNum

    Do While Not EOF(iFileNum)

        oIndex = oIndex + 1

        Line Input #iFileNum, oDelay

        Set ActDescPS1 = New Photoshop.ActionDescriptor

        Set ActRefPS1 = New Photoshop.ActionReference

        ActRefPS1.PutIndex idAniFrClass, oIndex

        ActDescPS1.PutReference idnull, ActRefPS1

        appPS.ExecuteAction idslct, ActDescPS1, dialogMode

        Set ActDescPS2 = New Photoshop.ActionDescriptor

        Set ActRefPS2 = New Photoshop.ActionReference

        ActRefPS2.PutEnumerated idAniFrClass, idOrdn, idTrgt

        ActDescPS2.PutReference idnull, ActRefPS2

        Set ActDescPS3 = New Photoshop.ActionDescriptor

        ActDescPS3.PutDouble idAniFrDelay, oDelay

        ActDescPS2.PutObject idT, idAniFrClass, ActDescPS3

        appPS.ExecuteAction idsetd, ActDescPS2, dialogMode

        Set ActDescPS1 = Nothing

        Set ActRefPS1 = Nothing

        Set ActDescPS2 = Nothing

        Set ActRefPS2 = Nothing

        Set ActDescPS3 = Nothing

    Loop

    Application.ScreenUpdating = True

    Set appPS = Nothing

    MsgBox "Frames Delays have been set!"

End Sub

The text file only needs to list the times in seconds in order of frames. In case someone else wants to copy the code. Such as :

0.916303

0.826175

0.660941

1.374455

1 reply

Inspiring
November 20, 2011

I don't often do much with any flavor of VB. but this looks all wrong to me. For one thing the arguments for putName are not correct. putName requires the class as ID and a string for the name. Your first agrument is a string and your second is a number. However changing that will not help becuase frames don't have names so you can not reference them by name. executeAction requres an actionDescriptor. You are either using an actionReference or just the VBA version of undefined being returned by the putName call. I could go on but I think you can see now that your approach is wrong.

What I would recommend it that you install the scriptListener plug-in and set the delay of a frame then look in the VB log. You should get something like this.

REM =======================================================

DIM objApp

SET objApp = CreateObject("Photoshop.Application")

REM Use dialog mode 3 for show no dialogs

DIM dialogMode

dialogMode = 3

DIM idsetd

idsetd = objApp.CharIDToTypeID( "setd" )

    DIM desc22

    SET desc22 = CreateObject( "Photoshop.ActionDescriptor" )

    DIM idnull

    idnull = objApp.CharIDToTypeID( "null" )

        DIM ref12

        SET ref12 = CreateObject( "Photoshop.ActionReference" )

        DIM idanimationFrameClass

        idanimationFrameClass = objApp.StringIDToTypeID( "animationFrameClass" )

        DIM idOrdn

        idOrdn = objApp.CharIDToTypeID( "Ordn" )

        DIM idTrgt

        idTrgt = objApp.CharIDToTypeID( "Trgt" )

        Call ref12.PutEnumerated( idanimationFrameClass, idOrdn, idTrgt )

    Call desc22.PutReference( idnull, ref12 )

    DIM idT

    idT = objApp.CharIDToTypeID( "T   " )

        DIM desc23

        SET desc23 = CreateObject( "Photoshop.ActionDescriptor" )

        DIM idanimationFrameDelay

        idanimationFrameDelay = objApp.StringIDToTypeID( "animationFrameDelay" )

        Call desc23.PutDouble( idanimationFrameDelay, 3.000000 )

    DIM idanimationFrameClass

    idanimationFrameClass = objApp.StringIDToTypeID( "animationFrameClass" )

    Call desc22.PutObject( idT, idanimationFrameClass, desc23 )

Call objApp.ExecuteAction( idsetd, desc22, dialogMode )

I know that is VBS and needs editing to use in VBA but it will give you a better idea of how to construct a executeAction argument.

Correct answer
November 22, 2011

Yeah Ive used the script listener before, but was hoping to avoid it because I didn't understand everything that it spits out. But I think I broke it down and I came up with below. I tweeked my original solution to use a text file.

Sub Set_Frame_Delay3()

    Dim appPS As Photoshop.Application

    Dim ActDescPS1 As Photoshop.ActionDescriptor, ActDescPS2 As Photoshop.ActionDescriptor, ActDescPS3 As Photoshop.ActionDescriptor

    Dim ActRefPS1 As Photoshop.ActionReference, ActRefPS2 As Photoshop.ActionReference

    Dim dialogMode

    Dim idsetd, idnull, idOrdn, idTrgt, idT, idslct

    Dim idAniFrClass, idAniFrDelay

    Dim sFileName As String

    Application.ScreenUpdating = False

    Set appPS = New Photoshop.Application

    appPS.Visible = True

    dialogMode = 3

    With appPS

        idsetd = .CharIDToTypeID("setd")

        idnull = .CharIDToTypeID("null")

        idOrdn = .CharIDToTypeID("Ordn")

        idTrgt = .CharIDToTypeID("Trgt")

        idT = .CharIDToTypeID("T   ")

        idslct = .CharIDToTypeID("slct")

        idAniFrClass = .StringIDToTypeID("animationFrameClass")

        idAniFrDelay = .StringIDToTypeID("animationFrameDelay")

    End With

    sFileName = Application.GetOpenFilename("Textfiles (*.txt),*.txt", , "Open a textfile...")

    oIndex = 0

    iFileNum = FreeFile()

    Open sFileName For Input As iFileNum

    Do While Not EOF(iFileNum)

        oIndex = oIndex + 1

        Line Input #iFileNum, oDelay

        Set ActDescPS1 = New Photoshop.ActionDescriptor

        Set ActRefPS1 = New Photoshop.ActionReference

        ActRefPS1.PutIndex idAniFrClass, oIndex

        ActDescPS1.PutReference idnull, ActRefPS1

        appPS.ExecuteAction idslct, ActDescPS1, dialogMode

        Set ActDescPS2 = New Photoshop.ActionDescriptor

        Set ActRefPS2 = New Photoshop.ActionReference

        ActRefPS2.PutEnumerated idAniFrClass, idOrdn, idTrgt

        ActDescPS2.PutReference idnull, ActRefPS2

        Set ActDescPS3 = New Photoshop.ActionDescriptor

        ActDescPS3.PutDouble idAniFrDelay, oDelay

        ActDescPS2.PutObject idT, idAniFrClass, ActDescPS3

        appPS.ExecuteAction idsetd, ActDescPS2, dialogMode

        Set ActDescPS1 = Nothing

        Set ActRefPS1 = Nothing

        Set ActDescPS2 = Nothing

        Set ActRefPS2 = Nothing

        Set ActDescPS3 = Nothing

    Loop

    Application.ScreenUpdating = True

    Set appPS = Nothing

    MsgBox "Frames Delays have been set!"

End Sub

The text file only needs to list the times in seconds in order of frames. In case someone else wants to copy the code. Such as :

0.916303

0.826175

0.660941

1.374455