Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
0

Looking for script to change "save as" actions..

New Here ,
Oct 07, 2009 Oct 07, 2009

I've been working on a way to avoid having to re-record 400+ save as actions.  The nutshell is that I'm saving game art from a master file.  The master file has elements common to other pieces.  So the actions turn on the appropriate layers, save then turn off those layers and repeat the process for all 400+ pieces.   This way when changes effect all pieces it's a simple operation to resave.  Creating 400 separate files seemed like an even more cumbersome way to go and having all the art in one file made more sense.

The problem I'm running into is that I've had to change hard drives often and it means the "save as" locations of the actions are no longer available.

I've tried every way I could think of to create a workaround but there's no answer that I've found so far.  Batch processing won't work because all of the 400 pieces come from one file.  I'm hoping that scripting will allow me to at least process the "record again" actions automatically.  I want to put in the new location the "save as" actions should point to and hit "OK" and have all new "save as" actions saved.

Any thoughts?  Possibly scripts available that do this very thing?  Am I wasting my time by trying to get scripting to do this and should just bite the bullet and spend 3 or 4 hours re-recording the save as actions every time I want to save the art to a new location?

TOPICS
Actions and scripting
8.7K
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Guru , Oct 09, 2009 Oct 09, 2009

But to answer your main question. Yes the script needs both the highlighted functions and the load symbols at the bottom in order to run.

Translate
Adobe
Community Expert ,
Oct 07, 2009 Oct 07, 2009

xbytor provides a Script that lets You transform recorded Actions into Scripts in his xtools (»ActionToJavascript.jsx«).

In those Scripts You should be able to easily amend the target-folder-positions.

http://sourceforge.net/projects/ps-scripts/files/

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Oct 08, 2009 Oct 08, 2009

Sweet!  Thanks!  I'll have a look and post back with the outcome.

On my soap box:

Unless I'm missing some finer point this might be a possible candidate for upgrade or enhancement for Adobe to make to the next version(s) of PS. 

Maybe my situation or approach has created a unique situation that never was considered in PS's design?    Maybe I'm misunderstanding and this and similar problems is what scripting is intended to address?   Assuming the thinking being rather than write code for every conceivable situation allow a powerful tool for users to do what they need on their own while providing an amazing base program to build on with scripting.  I can see the virtue in that and Photoshop successfully achieves that.  But it's a pretty complicated way to address problems with the base program. 

I'm not saying scripting should be done away with.  I love the idea and aspire to become proficient with it.   It just seems that the features that are included in PS could use some tweaking.  Specifically more flexibility or power in managing or changing actions.  I consider actions to be an intermediate level way of addressing what the more advanced power of scripting addresses so therefore actions are more accessible to beginning and intermediate users.  For that reason I feel actions are necessary. 

I'm thinking of a billion other angles that support and contradict my point and I'm realizing I don't know the full picture so I'll stop.  Just wanted to put it out there in the hopes I'll see some improvements and depth added to the PS actions features in the future.  Maybe I should make a formal contribution to be sure it gets considered.

:Stepping off soap box.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advisor ,
Oct 08, 2009 Oct 08, 2009

Another option (from xtools) is to translate the Action(s) into XML, edit the paths in the XML file, then translate back to an action file.

-X

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Oct 08, 2009 Oct 08, 2009

Ah ok excellent.  Plenty of options.  I came to the right place.   Thanks!

Was thinking about this when I was out running errands.  Contemplating the best option given my limited (read: zilch) knowledge of scipting.   I've read through the intro to PS scripting and done some web site java programming in the past, it all makes sense and I've remembered most of it.

So simple is likely the best route to make sure I don't miss my deadline.  A little bit of manual work using the find and replace function in my near future.

Ideally I'd like to be able to have a dialog pop up before the actions run that asks me for the destination path and filename prefix file type (TGA 16bit in this case) for all the subsequent save actions I run in that particular session.  Because I've named the actions according to the corresponding game file serial number I'd like it to grab that serial and add it to a prefix filename for each save.  Example: The path would be <hardrive location>:<project folder name>:saves:<prefix><serial from action name>.tga  where I'd add the hardrive location, project folder name, prefix, file type and bit depth (any other pertinent info) in the initial dialog then the action or script would add the serial from the actions name.

If all the files were sequential with no jumps it wouldn't matter because I'd use the batch processor to rename them.  But because during development files have gotten added for one side then added for the other then back to adding for the first side and so on, files are not sequential for each sides master file.  The first 150 are sequential there's a gap of 120 or so then back to sequential for 30 then gap, etc.  I suppose I could merge both master files and actions but no telling what that'd screw up.

Anyway, for now I'm grateful there's a solution that's better than the alternative I was using before. Thanks for your help with this and all the effort you've put into creating these tools.  Quite awesome!

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Oct 08, 2009 Oct 08, 2009

After looking at the javascript of the actions the scripting stuff I read is all making a lot more sense.  I'm nearly able to see what I need to do.  The big hangup right now is finding the right commands and understanding what I need to type in.  I'll dig around in the support materials in hopes of finding what I'm looking for.

If I can initiate a dialog to input the info I need I'm fairly certain I can create the script and necessary variables to transfer that info to the right spots in the actions.

I would imagine that means I'd have to leave the converted actions as a script rather than converting them back to actions.  Unless the conversion tool creates actions pointing to scripts where no equivalent action exists?  i.e. a dialog box for input.

I'll try it out to see if it works.  Will be a good learning exercise.

Thanks again for the help!

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Oct 08, 2009 Oct 08, 2009

So I'm guessing I misunderstood.  Is there no way to convert script to actions?  I've got the file converted to script and all the values I want changed but am not able to figure out how to convert it back to Photoshop actions. 

Running the script made from converted actions generates a fault so I know that doesn't work.

Please tell me there's a way.  The upshot is that having to do it over again but in XML won't take long.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guru ,
Oct 08, 2009 Oct 08, 2009

The basic step are:

1 Save your action to an atn file.

2 Use Xbytor's ActionFileToXML.jsx to convert the atn file to xml

3 Edit the paths in the xml to the new paths you would like

4 Use ActionFileFromXML.jsx to convert the edited xml back into an atn file

5. Load the atn in Photoshop

Or you could use ActionFileToJavascript.jsx to convert the action into javascript. You could then edit that javascript to change the paths.

If the action runs in Photoshop the javascript created from the action should also run without error. What error are you getting?

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Oct 09, 2009 Oct 09, 2009

I appreciate that Michael.  I was able to figure that part out but editing in XML is a lot more confusing that editing in javascript.  Perhaps because I was using a word editor rather than say Safari or some website type editor.  So I opted to convert to jsx and do my editing in Extended Tool Kit.  Apparently the wrong choice since it would appear there's no way to convert that back into actions once in jsx.

In case I didn't mention it I tried running the converted script after editing my save locations and it presented an error on the very first line.  See attached.  I'm assuming it's because the name "000" has not been identified as a variable?

FYI - you're looking at the actions converted to javascript by xtool exactly as it was converted.  The only stuff I changed was the save locations  i.e. from File("") to File("<my HD save location>").  Not sure if the expectation was that the converted actions would run as script right out of the box or if I was to make some alterations to the converted actions.

Will have to redo it in XML?

Thanks for the help!!

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guru ,
Oct 09, 2009 Oct 09, 2009

You will want to edit javascript in Extended Tool Kit or a plain text editor.

And no, you will not be able to convert you javascript back to action. But from what you have posted I think that scripting is the way you want to go. You may need help but a scirpt can prompt for paths and filename components.

If you stick with actions every time you change folders you will need to redo the atm/xml/atm cycle.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Oct 09, 2009 Oct 09, 2009

Thanks again Michael.  Ok was what I was thinking.  Not sure why the current script isn't working as actions converted to javascript.

Was I expected to add some script at the beginning of the converted actions?  For some reason I'd thought xtool would've done that.  Incorrect assumption?

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guru ,
Oct 09, 2009 Oct 09, 2009

I'm not sure how it happened but I think the problem is the first funtion's name. Javascript functions can not start with a digit. Try renaming the function and it call to something like step0 or action0.

I would guess the call would be somewhere near the botton of the script.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Oct 09, 2009 Oct 09, 2009

Ok thanks.  Will give it a try and report back.  Thanks for sticking with this.

The reason those are named that way is because my actions were named that way.  Perhaps a loophole in the action > javascript conversion tool?  Maybe a line of code would need to be added to the xtool to add a character at the beginning of the action name string?  Just a guess.  Not sure what that would screw up from having done that.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Oct 09, 2009 Oct 09, 2009

Yeah that works great.  To keep the steps in each action separate from the actions themselves I named each one action### and left the step names alone.  That way I have another visual cue to see where each action starts and ends.  The comments that xtool added does this as well but just another level of visual cueing.

Thanks!

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advisor ,
Oct 09, 2009 Oct 09, 2009
Perhaps a loophole in the action > javascript conversion tool?

I wouldn't call it a loophole. I just never dealt with action/set names that begin with numbers.

Maybe a line of code would need to be added to the xtool to add a character at the beginning of the action name string?

Look for a function called JSWriter.massageName(). Add this line of code just before the 'return' statement. It should fix your problem.

  n = n.replace(/^(\d)/g, '_$1');  // add '_' prefix to names begining with a number
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Oct 09, 2009 Oct 09, 2009

Sweet!  Thanks!  Will do.  Hoping you didn't take offense to my comments. None intended.  I assumed there was a reason beyond my understanding.

Because there are 2500+ lines of code in the converted actions ETK is pausing every 10 seconds or so to chew on data apparently.  So changing each line is taking forever.  Adding the line(s) you suggested will help tremendously.

For the future if this is unavoidable what can I do?  I've tried turning off all the features I could think of that might be causing this (auto fill, etc.) but nothing really helps.  It's just too large I guess.  I'm even working with an 8 core 2.6ghz machine and 16GB of ram. LOL  Lots of characters in that script.

Last thing: I was trying to eliminate actions that are not part of the actions I'm trying to modify but were in the set I converted.  What does the highlighted part in the attached do?  Is it part of "reduce tanks" action or is it something I need to keep that xtools added?  How about load symbols at the bottom?  I see the brackets to the left but didn't want to assume one way or the other since I don't know for sure.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guru ,
Oct 09, 2009 Oct 09, 2009

I wouldn't think the size of the script would cause ESKT any problems.

However one thing you can do now that you have the action as a script is go through it and replace the contevted action manager code to DOM calls. For example you should be able to replace the first two functions, step1 and step2, with the following

app.activeDocument.layers.getByName( "USA bkgnd" ).visible = true;// step1
app.activeDocument.layers.getByName( "Infantry" ).visible = true;// step2

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Oct 09, 2009 Oct 09, 2009

However one thing you can do now that you have the action as a script is go through it and replace the contevted action manager code to DOM calls. For example you should be able to replace the first two functions, step1 and step2, with the following

app.activeDocument.layers.getByName( "USA bkgnd" ).visible = true;// step1
app.activeDocument.layers.getByName( "Infantry" ).visible = true;// step2

Yeah, okay, makes sense.  Is this a call that anytime step1 is found it performs that action?  In which case if a step1 turns on a different named layer that wouldn't work?

Or are you saying I could replace the quoted part in each action to make the script more efficient and tidy?:

//

//==================== 000 ==============

//

function 000() {

  // Show

  function step1(enabled, withDialog) {

    if (enabled != undefined && !enabled)

      return;

    var dialogMode = (withDialog ? DialogModes.ALL : DialogModes.NO);

    var desc1 = new ActionDescriptor();

    var list1 = new ActionList();

    var ref1 = new ActionReference();

    ref1.putName(PSClass.Layer, "USA bkgnd");

    list1.putReference(ref1);

    desc1.putList(PSString.Null, list1);

    executeAction(PSEvent.Show, desc1, dialogMode);

  };

So if I wanted to turn on the "Brit bkgnd" layer I'd replace the corresponding British highlighted portion above with?:
app.activeDocument.layers.getByName( "Brit bkgnd" ).visible = true;// step1
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Oct 09, 2009 Oct 09, 2009

LOL after studying it for a few minutes I think I answered my own question.  I think it's the latter.

//

//==================== 000 ==============

//

function _000() {

  // Show

  function step1(enabled, withDialog) {

    if (enabled != undefined && !enabled)

      return;

    var dialogMode = (withDialog ? DialogModes.ALL : DialogModes.NO);

    var desc1 = new ActionDescriptor();

    var list1 = new ActionList();

    var ref1 = new ActionReference();

    ref1.putName(PSClass.Layer, "USA bkgnd");

    list1.putReference(ref1);

    desc1.putList(PSString.Null, list1);

    executeAction(PSEvent.Show, desc1, dialogMode);

  };

// are comments to understand the script.
Red creates the variables of each command that follows the = sign.
There's an IF>THEN statement at the beginning that I don't exactly understand every part but I get the overall gist.  Not sure what the ! mark does before or after enabled.
So

//

//==================== 000 ==============

//

function _000() {

  // Show USA bkgnd

  function step1()

     app.activeDocument.layers.getByName( "USA bkgnd" ).visible = true;// step1
//
Would do the same thing?           
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guru ,
Oct 09, 2009 Oct 09, 2009

That was an example of how you could edit the script to convert 11 lines of code to one line. All the code in function step1 does is make sure the layer with the name "USA bkgnd" is visible.

And you would need to edit either to work with a different layer. I should note that if the layers are in layersets you will need to change the one line I posted. It only works if all the layers are not in layersets.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guru ,
Oct 09, 2009 Oct 09, 2009

The if statement lets you skip the function much like the checkbox in the action panel

The ! means not so the statments read if enabled is not equal to undefined and is not true return without doing anything.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Oct 09, 2009 Oct 09, 2009

Ok cool.  Got it.

They are in separate layer sets.  I'll try looking through the help files to find the answer for this.  Would prefer learning this as opposed to relying on someone providing the answers.  Unfortunately currently in a position of needing the answer immediately but I think I can find this one quickly as I seem to recall where to find it.  Maybe I'll be posting back in a few minutes.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Oct 10, 2009 Oct 10, 2009

Posted by: Michael Hale

I wouldn't think the size of the script would cause ESKT any problems.

However one thing you can do now that you have the action as a script is go through it and replace the contevted action manager code to DOM calls. For example you should be able to replace the first two functions, step1 and step2, with the following

app.activeDocument.layers.getByName( "USA bkgnd" ).visible = true;// step1
app.activeDocument.layers.getByName( "Infantry" ).visible = true;// step2

That was an example of how you could edit the script to convert 11 lines of code to one line. All the code in function step1 does is make sure the layer with the name "USA bkgnd" is visible.

And you would need to edit either to work with a different layer. I should note that if the layers are in layersets you will need to change the one line I posted. It only works if all the layers are not in layersets.

So I was thinking I'd go ahead and do this.  It would take my script down to below a couple thousand lines and make editing less time consuming.

Could you tell me what I'd need to do if the layers I was turning on and off are in layer sets?  Or where to look to find the info?  I was browsing the object model viewer provided with ESTK but it is a bit difficult to understand the convention used in the explanations.  Not sure the answer is there anyway.

Thanks!

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guru ,
Oct 10, 2009 Oct 10, 2009

Scripting layers and layerset it not straight forward and there are several ways to handle them.

One simple way is if the script works with a doc where the layer structure is know is to just hard code the reference. For example let's say you have a layerset named 'bkground' and that set has layers named ' USA bkground' and 'UK bkground'. To reference the USA layer you could do something like this:

activeDocument.layers.getByName('bkground').layers.getByName('USA bkground').visible = true;

You could also rewrite the line above like this:

var doc = activeDocument;

var bkSet = doc.layers.getByName('bkground');

bkSet.layers.getByName('USA bkground').visible = true;

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Oct 10, 2009 Oct 10, 2009
LATEST

Scripting layers and layerset it not straight forward and there are several ways to handle them.

One simple way is if the script works with a doc where the layer structure is know is to just hard code the reference. For example let's say you have a layerset named 'bkground' and that set has layers named ' USA bkground' and 'UK bkground'. To reference the USA layer you could do something like this:

activeDocument.layers.getByName('bkground').layers.getByName('USA bkground').visible = true;

You could also rewrite the line above like this:

var doc = activeDocument;

var bkSet = doc.layers.getByName('bkground');

bkSet.layers.getByName('USA bkground').visible = true;

Ok that makes perfect sense.  So the command getByName() (or function?) can apply to any Photoshop thing (object?) such as layer, layer set, mask, channel, action, path, etc.?  And I recall that you have to mind the class(?) hierarchy by calling the uppermost object first then the stuff nested within.  Just as your example did.

If I was looking through the Object Model Viewer the description of getByName() would indicate what valid entries are that can go inside the parenthesis.  String would be one valid entry correct?  And as the intro PDF stated any string such as a layer name would need to go between quote marks.

I know the function names are designed to indicate what they do but they're still pretty confusing to me at this point.  I'm sure it'll make more sense after I've used them a while and can draw parallels between them and a verbal description I'd come up with that'd be the everyday english equivalent.  i.e. as in the example you gave above "Select the layer set named "bkground" and the layer contained within that set the layer named "USA bkground" and make that layer visible."

I'll bet Applescript is designed to move in that direction but I work with both PC and Mac so I'd like to keep functionality options open by using JavaScript.

Thanks for the lesson!

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines