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

Possible to script palette menus Save and Load Curves?

Explorer ,
Aug 13, 2013 Aug 13, 2013

Copy link to clipboard

Copied

Is it possible to script CS4 Photoshop's palette menus? Specifically, the "Save Curves Preset ..." and "Load Curves Preset" ... of the Adjustments Palette.

I have 600 images, some of which have layer>new adjustment layer>curves applied.

I want to save the curves using the image name. Later, I want to be able to load the appropriate curve.

E.g., for image001.tif, the curve would be image001.acv

(I already have a loop set up to iterate through the files and get the file names.)



TOPICS
Actions and scripting

Views

1.5K

Translate

Translate

Report

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 , Aug 13, 2013 Aug 13, 2013

I can't help with Applescript( or even know if it is possible to do this with Applescript alone ). And to my knowledge you can't script things in dialogs like load or save curve directly. But here is  code in javascript that will load and save the settings.

First the easy part, setting an adjustment layer from a file.

function loadCurves( file ) {

    var desc = new ActionDescriptor();

        var ref = new ActionReference();

        ref.putEnumerated( charIDToTypeID( "AdjL" ), charIDToTypeID( "Ordn"

...

Votes

Translate

Translate
Adobe
Enthusiast ,
Aug 13, 2013 Aug 13, 2013

Copy link to clipboard

Copied

Hi Joesick,

For this kind of work where you need different adjustments I advise you to create an action.

First you open an image of the 600 taht you have to work then you open the Actions panel and click on the small icon at the bottom right (similar to new level) and it open a wizard that invites you to nominate future action then click records ... Run the workings of levels curves, contrast and so on and when you are done, hit stop.

You can use the same action for all pics with freedom to make new adjustments if and where you need!

Votes

Translate

Translate

Report

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
Explorer ,
Aug 13, 2013 Aug 13, 2013

Copy link to clipboard

Copied

The curves are different for each image, and have to be named differently for each image.

I want to be able to batch through 600 images and save each existing curve with a name based on the image name. Actions cannot do that.

Votes

Translate

Translate

Report

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
Enthusiast ,
Aug 13, 2013 Aug 13, 2013

Copy link to clipboard

Copied

I did not understand.

want you to save a series of curves with different adjustments and name them with an appropriate name for each type so as to be able to load the curve more right for each type of image ?

If is it so I don't think that there is a scripit to create what you want, but maybe someone else knows things that I don't know

Votes

Translate

Translate

Report

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
Explorer ,
Aug 13, 2013 Aug 13, 2013

Copy link to clipboard

Copied

I am experimenting with ScriptListener, which will probably work eventually, but I was hoping there was a more straightforward way.

Votes

Translate

Translate

Report

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 ,
Aug 13, 2013 Aug 13, 2013

Copy link to clipboard

Copied

To rephrase your question, you want to save the curve settings from an existing adjustment layer to an .acv file and then later set an adjustment layer from an .acv file?

If so I have code that does that. It's not that straightforward because of the way Photoshop stores the settings in the adjustment layer but it does work.

Let me know if I understood your question correctly and I will post the code.

Votes

Translate

Translate

Report

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
Explorer ,
Aug 13, 2013 Aug 13, 2013

Copy link to clipboard

Copied

Yes, but the code has to be able to use a variable (the current file name) when saving or retrieving the .acv file.

Here's what I have so far:

tell application "Finder"

          set TheFolder to choose folder

          set FileList to every file of entire contents of TheFolder as alias list

end tell

repeat with theFile in FileList

          set thefilename to theFile as string

          set text item delimiters to ":"

          set thefilename to last text item of thefilename --remove path

          set text item delimiters to "."

          set thefilename to first text item of thefilename --remove extension

          tell application "Adobe Photoshop CS4"

  open theFile

  -- CODE HERE to save or load thefilename.acv --

          end tell

end repeat

I've been using ScriptListener to generate Javascripts that are then inserted in the above Applescript. Some stuff works, but so far I haven't been able to get "Save Curves Preset" and "Load Curves Preset" to work.

A purely Applescript script would be preferable, but Applescript can pass variables (e.g., thefilename) to Javascript functions and then execute them.

Votes

Translate

Translate

Report

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 ,
Aug 13, 2013 Aug 13, 2013

Copy link to clipboard

Copied

I can't help with Applescript( or even know if it is possible to do this with Applescript alone ). And to my knowledge you can't script things in dialogs like load or save curve directly. But here is  code in javascript that will load and save the settings.

First the easy part, setting an adjustment layer from a file.

function loadCurves( file ) {

    var desc = new ActionDescriptor();

        var ref = new ActionReference();

        ref.putEnumerated( charIDToTypeID( "AdjL" ), charIDToTypeID( "Ordn" ), charIDToTypeID( "Trgt" ) );

    desc.putReference( charIDToTypeID( "null" ), ref );

        var desc1 = new ActionDescriptor();

        desc1.putPath( charIDToTypeID( "Usng" ), new File( file ) );

    desc.putObject( charIDToTypeID( "T   " ), charIDToTypeID( "Crvs" ), desc1 );

    executeAction( charIDToTypeID( "setd" ), desc, DialogModes.NO );

};

The code to write the .acv file from an adjustment layer is bit more involved and doesn't work with all color modes

// Works with RGB or CMYK images.

// Does not work at all with greyscale, or indexColor

// Does not work correctly with Lab

File.prototype.writeByte = function(b) {

  this.write(String.fromCharCode(b));

};

File.prototype.writeShort = function(ET,s) {

  var self = this;

if(ET == "BE"){

  self.writeByte(s & 0xFF);

  self.writeByte((s >> 8) & 0xFF);

}else{

  self.writeByte((s >> 8) & 0xFF);

  self.writeByte(s & 0xFF);

}

  return self;

};

function convertBCD( num ){

    var res = new Array;

    if(num > 16 ){

        res.unshift(1);

        num = num - 16;

    }else{

        res.unshift(0);

    }

    if(num > 8 ){

        res.unshift(1);

        num = num - 8;

    }else{

        res.unshift(0);

    }

    if(num > 4 ){

        res.unshift(1);

        num = num - 4;

    }else{

        res.unshift(0);

    }

    if(num > 2 ){

        res.unshift(1);

        num = num - 2;

    }else{

        res.unshift(0);

    }

    if(num == 1 ){

        res.unshift(1);

    }else{

        res.unshift(0);

    }

    return res;

};

function getCurve( numberOfPoints ){

    this.getPoints = function(){

        this.tempArray = new Array;

        this.tempArray.push( rawDesc.charCodeAt( pointer ) );

        pointer = pointer + 2;// set pointer to next point

        this.tempArray.push( rawDesc.charCodeAt( pointer ) );

        return this.tempArray;

    }

   

    this.pointsArray = new Array;

    for( var i = 0; i < numberOfPoints; i++ ){

        pointer = pointer + 2;// next point

        this.pointsArray.push( this.getPoints() );

    }

    pointer = pointer + 2;// next curve

    return this.pointsArray;

};

var ref = new ActionReference();

ref.putEnumerated( charIDToTypeID( 'Lyr ' ), charIDToTypeID( 'Ordn' ), charIDToTypeID( 'Trgt' ) );

var rawDesc = executeActionGet( ref ).getList( stringIDToTypeID( 'adjustment' ) ).getObjectValue( 0 ).getData( stringIDToTypeID( 'legacyContentData' ) );

var pointer = 2;// used to read rawData similar to reading a file

var flag = rawDesc.charCodeAt( pointer );// char at offset 2 always == 1 so use to validate data

if( flag != 1 ) forceError;// unknown problem with rawData

    pointer = 6;// update pointer to BCD byte

    var bcd = rawDesc.charCodeAt( pointer );

    if( bcd < 0 || bcd > 31 ) forceError;// check for valid value

    if( bcd == 0 ) forceError;// an empty adjustment - no curves to process

    var bcdArray = convertBCD( bcd );

    var numberOfCurves = bcdArray.toString().match(/(1)/g).length;

    var curvesArray = new Array;

    pointer = 8;// set pointer to start of curve data

    for(var i = 0; i < numberOfCurves; i++ ){

        var numberOfPoints = rawDesc.charCodeAt( pointer );

        curvesArray.push( getCurve( numberOfPoints ) );

    }

// now need to map rawData curves in curvesArray to known channel curves

var acvArray = new Array;

if( bcdArray[0] == 1 ) {

    acvArray.push( curvesArray.shift() );

} else {

    acvArray.push( [ [0,0],[255,255] ] );

}

if( bcdArray[1] == 1 ) {

    acvArray.push( curvesArray.shift() );

} else {

    acvArray.push( [ [0,0],[255,255] ] );

}

if( bcdArray[2] == 1 ) {

    acvArray.push( curvesArray.shift() );

} else {

    acvArray.push( [ [0,0],[255,255] ] );

}

if( bcdArray[3] == 1 ) {

    acvArray.push( curvesArray.shift() );

} else {

    acvArray.push( [ [0,0],[255,255] ] );

}

if( bcdArray[4] == 1 ) {

    acvArray.push( curvesArray.shift() );

} else {

    acvArray.push( [ [0,0],[255,255] ] );

}

var myACV = new File('~/desktop/myCurve.acv');

myACV.open('w');

myACV.writeShort( 'LE','4' );// acv header

myACV.writeShort( 'LE','5' );// acv header

for( var i = 0; i< 5; i++ ) {

    var numberOfPoints = acvArray.length;

    myACV.writeShort( 'LE', numberOfPoints.toString() );

    for( var p = 0; p < numberOfPoints; p++ ){

        myACV.writeShort( 'LE', acvArray

[0].toString() );

        myACV.writeShort( 'LE', acvArray

[1].toString() );

    }

}

myACV.close();

I wrote this a while back. It might be possible to just write the acv header then add the raw data from the descriptor to work with other modes.

Also neither checks that the selected layer is a curves adjustment layer and will fail if it is not.

Votes

Translate

Translate

Report

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
Explorer ,
Aug 13, 2013 Aug 13, 2013

Copy link to clipboard

Copied

Thank you.

I got both scripts working without JS or AS errors, but, when trying to load .acv files generated by the second script, CS4 Photoshop gave an error:

"Could not load the curves because the file is not compatible with this version of Photoshop"

(The loading script works fine when loading .acv files created directly from Photoshop.)

The only change I made to your Save Curves code was:

FROM: var myACV = new File('~/desktop/myCurve.acv')

TO: var myACV = new File(file);

and made the code a function:

saveCurves(file)

{

YOUR CODE HERE

}


so that I could incorporate it into the Applescript.

Maybe that was naive (I'm not very knowledgeable about JS).

-------------

Here are the scripts I'm using:

SAVE CURVES:

set gammaFolder to "/Users/me/Desktop/myproject/gamma/"

tell application "Finder"

          set TheFolder to choose folder

          set FileList to every file of entire contents of TheFolder as alias list

end tell

repeat with theFile in FileList

          set thefilename to theFile as string

          set text item delimiters to ":"

          set thefilename to last text item of thefilename --remove path

          set text item delimiters to "."

          set thefilename to first text item of thefilename --remove extension

          tell application "Adobe Photoshop CS4"

  activate

  open theFile

                    tell current document

                              if exists layer "Curves 1" then

                                        set current layer to layer "Curves 1"

                                        do javascript "saveCurves('" & gammaFolder & thefilename & ".acv');

function saveCurves(file) {

-- SAVE CURVES JAVASCRIPT HERE

};" --show debugger on runtime error

                              end if

                    end tell

          end tell

end repeat

-------------

LOAD CURVES:

set gammaFolder to "/Users/me/Desktop/myproject/gamma/"

tell application "Finder"

          set TheFolder to choose folder

          set FileList to every file of entire contents of TheFolder as alias list

end tell

repeat with theFile in FileList

          set thefilename to theFile as string

          set text item delimiters to ":"

          set thefilename to last text item of thefilename --remove path

          set text item delimiters to "."

          set thefilename to first text item of thefilename --remove extension

          set acvFile to gammaFolder & thefilename & ".acv"

          tell application "Finder" to set acvExists to exists my POSIX file acvFile

          if acvExists then

                    tell application "Adobe Photoshop CS4"

  activate

  open theFile

                              tell current document

                                        if not (exists layer "Curves 1") then

                                                  do action "Create Curve Layer" from "MyActions"

                                        end if

                                        set current layer to layer "Curves 1"

                                        do javascript "loadCurves('" & gammaFolder & thefilename & ".acv');

function loadCurves(file) {

-- LOAD CURVES JAVASCRIPT HERE

};" --show debugger on runtime error

                              end tell

                    end tell

          end if

end repeat


Votes

Translate

Translate

Report

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 ,
Aug 13, 2013 Aug 13, 2013

Copy link to clipboard

Copied

I don't have CS4 installed to test but from the date of the file I got this code from it was written during CS4. And I also have never tested this on Mac. Just a guess but maybe on Mac you have to set the file type or creator as well as the extension. Can you use finder to set the type as a test to see if it loads then. If it does we can add code to set the type.

I thought the byte order in the Adobe support files like acv is the same on Windows or Mac but that may be another reason it doesn't work.

Or it is writting a binary file but doesn't explicitly set the file encoding. It works on Windows without setting the encoding but maybe Mac needs the encoding set. You can try adding the following line

// new line to set encoding

myACV.encoding = 'BINARY';

// existing line to open file to write

myACV.open('w');

Votes

Translate

Translate

Report

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
Explorer ,
Aug 13, 2013 Aug 13, 2013

Copy link to clipboard

Copied

LATEST

Adding the BINARY line worked. Thank you for your help.

Votes

Translate

Translate

Report

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