Copy link to clipboard
Copied
I have this function as part of a script for finalising photoshop files. It checks for any points on the curve
this.checkCurve = function(index){
//if(app.activeDocument.activeLayer.kind != LayerKind.CURVES ) return;
var ref = new ActionReference();
ref.putIndex(s2t("layer"), index)
var rawDesc = executeActionGet( ref ).getList( s2t( 'adjustment' ) ).getObjectValue( 0 ).getData( s2t( '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 > 15 ) forceError;// check for valid value
if( bcd == 0 ) return false;// an empty adjustment - no curves to process
return true;
}
. The current version of photoshop doesnt seem to allow you to get the rawData. Anybody got some sort of work around or way of determining if a curve has no points on any of composite and component curves?
Does this help?
// check if curves layer has been changed at all;
// based on code by michael l hale;
// 2023, use it at your own risk;
if (app.documents.length > 0) {
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
var layerDesc = executeActionGet(ref);
try {
var aList = layerDesc.getList(stringIDToTypeID("adjustment"));
var listStuff = evaluateList (aList);
var listStuff2 = evaluateList (listStuff[0].getList(string
...
Copy link to clipboard
Copied
Does this help?
// check if curves layer has been changed at all;
// based on code by michael l hale;
// 2023, use it at your own risk;
if (app.documents.length > 0) {
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
var layerDesc = executeActionGet(ref);
try {
var aList = layerDesc.getList(stringIDToTypeID("adjustment"));
var listStuff = evaluateList (aList);
var listStuff2 = evaluateList (listStuff[0].getList(stringIDToTypeID("adjustment")))
var aaa = evaluateList(listStuff2[0].getList(stringIDToTypeID("curve")));
} catch (e) {
alert ("either not a curves adjustment layer or at unedited default settings")
}
};
////////////////////////////////////
////// get list values //////
function evaluateList (aList) {
var listStuff = new Array;
for (var x = 0; x < aList.count; x++) {
var theType = aList.getType(x);
switch (theType) {
case DescValueType.ALIASTYPE:
listStuff.push( aList.getPath(x));
break;
case DescValueType.BOOLEANTYPE:
listStuff.push( aList.getBoolean(x));
break;
case DescValueType.CLASSTYPE:
listStuff.push( aList.getClass(x));
break;
case DescValueType.DOUBLETYPE:
listStuff.push( aList.getDouble(x));
break;
case DescValueType.ENUMERATEDTYPE:
listStuff.push( aList.getEnumerationValue(x));
break;
case DescValueType.INTEGERTYPE:
listStuff.push( aList.getInteger(x));
break;
case DescValueType.LISTTYPE:
listStuff.push( aList.getList(x));
break;
case DescValueType.OBJECTTYPE:
listStuff.push( (aList.getObjectValue(x)));
break;
case DescValueType.RAWTYPE:
listStuff.push( aList.getReference(x));
break;
case DescValueType.REFERENCETYPE:
listStuff.push( aList.getReference(x));
break;
case DescValueType.STRINGTYPE:
listStuff.push( aList.getString(x));
break;
case DescValueType.UNITDOUBLE:
listStuff.push( aList.getUnitDoubleValue(x));
break;
default:
break;
};
};
return listStuff
};
Copy link to clipboard
Copied
thank you ! but for me only the alert is shown
Copy link to clipboard
Copied
Please provide the file you are testing on.
Copy link to clipboard
Copied
I tested once more. The code works for curve layer. but i need to get the values from a level layer.
something like this:
var inBlackLevel = levelsOptions.inBlack;
var inWhiteLevel = levelsOptions.inWhite;
var outBlackLevel = levelsOptions.outBlack;
var outWhiteLevel = levelsOptions.outWhite;
var gammaLevel = levelsOptions.gamma;
alert(gammaLevel);
Copy link to clipboard
Copied
in the var listStuff2 i get a alert [ActionDiscriptor]. But dont know how to get the level values.
Copy link to clipboard
Copied
And again: Please provide the file you are testing on.
Copy link to clipboard
Copied
//var aDoc = app.activeDocument;
//aDoc.activeLayer = aDoc.layers['Tonwertkorrektur 1'];
//https://community.adobe.com/t5/photoshop-ecosystem-discussions/modifying-levels-adjustment-layer/m-p/5587180
// working code before update
/*
var ref = new ActionReference();
//ref.putEnumerated( charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
//var data = executeActionGet(ref).getList(charIDToTypeID("Adjs")).getObjectValue(0).getData(stringIDToTypeID('legacyContentData'));
//var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID( 'Lyr ' ), charIDToTypeID( 'Ordn' ), charIDToTypeID( 'Trgt' ) );
var data = executeActionGet( ref ).getList( stringIDToTypeID( 'adjustment' ) ).getObjectValue( 0 ).getData( stringIDToTypeID( 'legacyContentData' ) );
//var data = get_prop_value("layer", null, "adjustment", 0, "legacyContentData");
var check = getShortFromStream( data, 0 ); // Prüfen ob Daten abgerufen werden können
if(check != 2 ) throwError;// if not 2 then something is wrong
var levelsOptions = {};
levelsOptions.inBlack = getShortFromStream( data, 2 );
levelsOptions.inWhite = getShortFromStream( data, 4 );
levelsOptions.outBlack = getShortFromStream( data, 6 );
levelsOptions.outWhite = getShortFromStream( data, 8 );
levelsOptions.gamma = getShortFromStream( data, 10 )/100;
//alert(levelsOptions.inBlack);
function getShortFromStream( stream, pointer ) {
var hi, low;
hi = stream.charCodeAt( pointer ) << 8 ;
low = stream.charCodeAt( pointer + 1 );
return hi + low;
};
var inBlackLevel = levelsOptions.inBlack;
var inWhiteLevel = levelsOptions.inWhite;
var outBlackLevel = levelsOptions.outBlack;
var outWhiteLevel = levelsOptions.outWhite;
var gammaLevel = levelsOptions.gamma;
alert(gammaLevel);
*/
if (app.documents.length > 0) {
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
var layerDesc = executeActionGet(ref);
try {
var aList = layerDesc.getList(stringIDToTypeID("adjustment"));
var listStuff = evaluateList (aList);
var listStuff2 = evaluateList (listStuff[0].getList(stringIDToTypeID("adjustment")))
// var aaa = evaluateList(listStuff2[0].getList(stringIDToTypeID("levels")));
alert (listStuff2);
} catch (e) {
alert ("either not a curves adjustment layer or at unedited default settings")
}
};
////////////////////////////////////
////// get list values //////
function evaluateList (aList) {
var listStuff = new Array;
for (var x = 0; x < aList.count; x++) {
var theType = aList.getType(x);
switch (theType) {
case DescValueType.ALIASTYPE:
listStuff.push( aList.getPath(x));
break;
case DescValueType.BOOLEANTYPE:
listStuff.push( aList.getBoolean(x));
break;
case DescValueType.CLASSTYPE:
listStuff.push( aList.getClass(x));
break;
case DescValueType.DOUBLETYPE:
listStuff.push( aList.getDouble(x));
break;
case DescValueType.ENUMERATEDTYPE:
listStuff.push( aList.getEnumerationValue(x));
break;
case DescValueType.INTEGERTYPE:
listStuff.push( aList.getInteger(x));
break;
case DescValueType.LISTTYPE:
listStuff.push( aList.getList(x));
break;
case DescValueType.OBJECTTYPE:
listStuff.push( (aList.getObjectValue(x)));
break;
case DescValueType.RAWTYPE:
listStuff.push( aList.getReference(x));
break;
case DescValueType.REFERENCETYPE:
listStuff.push( aList.getReference(x));
break;
case DescValueType.STRINGTYPE:
listStuff.push( aList.getString(x));
break;
case DescValueType.UNITDOUBLE:
listStuff.push( aList.getUnitDoubleValue(x));
break;
default:
break;
};
};
return listStuff
};
Copy link to clipboard
Copied
I meant the image; never mind …
Does this help?
updated code
// check levels layer;
// based on code by michael l hale;
// 2023, use it at your own risk;
if (app.documents.length > 0) {
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
var layerDesc = executeActionGet(ref);
try {
var listStuff = evaluateList (layerDesc.getList(stringIDToTypeID("adjustment")));
var listStuff2 = evaluateList (listStuff[0].getList(stringIDToTypeID("adjustment")));
var theResult = new Array;
for (var m = 0; m < listStuff2.length; m++) {
var theChannel = listStuff2[m].getReference(stringIDToTypeID("channel"));
theChannel = typeIDToStringID(theChannel.getEnumeratedValue());
var theInput = evaluateList (listStuff2[m].getList(stringIDToTypeID("input")));
var theGamma = listStuff2[m].getDouble(stringIDToTypeID("gamma"));
var theOutput = evaluateList (listStuff2[m].getList(stringIDToTypeID("output")));
theResult.push(theChannel+"\nthe input\n"+theInput+"\nthe gamma\n"+theGamma+"\nthe output\n"+theOutput+"\n\n");
};
alert ("levels\n"+theResult.join("\n"))
} catch (e) {
alert ("probably not a levels adjustment layer")
}
};
////////////////////////////////////
////// get list values //////
function evaluateList (aList) {
var listStuff = new Array;
for (var x = 0; x < aList.count; x++) {
var theType = aList.getType(x);
switch (theType) {
case DescValueType.ALIASTYPE:
listStuff.push( aList.getPath(x));
break;
case DescValueType.BOOLEANTYPE:
listStuff.push( aList.getBoolean(x));
break;
case DescValueType.CLASSTYPE:
listStuff.push( aList.getClass(x));
break;
case DescValueType.DOUBLETYPE:
listStuff.push( aList.getDouble(x));
break;
case DescValueType.ENUMERATEDTYPE:
listStuff.push( aList.getEnumerationValue(x));
break;
case DescValueType.INTEGERTYPE:
listStuff.push( aList.getInteger(x));
break;
case DescValueType.LISTTYPE:
listStuff.push( aList.getList(x));
break;
case DescValueType.OBJECTTYPE:
listStuff.push( (aList.getObjectValue(x)));
break;
case DescValueType.RAWTYPE:
listStuff.push( aList.getReference(x));
break;
case DescValueType.REFERENCETYPE:
listStuff.push( aList.getReference(x));
break;
case DescValueType.STRINGTYPE:
listStuff.push( aList.getString(x));
break;
case DescValueType.UNITDOUBLE:
listStuff.push( aList.getUnitDoubleValue(x));
break;
default:
break;
};
};
return listStuff
};
Copy link to clipboard
Copied
Nice work !!! thank you very much for the fast help!
Copy link to clipboard
Copied
Mind you, that’s just for the composite channel.
If you edited individal channels you need to amend the code further.
Copy link to clipboard
Copied
works fine for me ! thanks
Copy link to clipboard
Copied
I updated the code to include the channels (if they have been edited, too).
And feel free to mark a post as »Correct Answer« if it resoves the problem.
That’s not just about my vanity but also to enable potential future visitors to quickly find the relevant post/s.
Copy link to clipboard
Copied
Can you test how your code works if the user clicks the Auto button?
Copy link to clipboard
Copied
Interesting, in that case the three auto-edited color Channels don’t appear to be listed individually and the try-clause errors out.
Copy link to clipboard
Copied
@r-bin , does this work for you?
// check levels layer;
// based on code by michael l hale;
// 2023, use it at your own risk;
if (app.documents.length > 0) {
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
var layerDesc = executeActionGet(ref);
try {
var listStuff = evaluateList (layerDesc.getList(stringIDToTypeID("adjustment")));
var listStuff2 = evaluateList (listStuff[0].getList(stringIDToTypeID("adjustment")));
var theResult = new Array;
// check if auto;
if (listStuff2.length == 1 && listStuff2[0].hasKey(stringIDToTypeID("auto"))) {
var stuff = checkDesc2 (listStuff2[0]);
theResult.push(stuff)
}
else {
for (var m = 0; m < listStuff2.length; m++) {
var theChannel = listStuff2[m].getReference(stringIDToTypeID("channel"));
theChannel = typeIDToStringID(theChannel.getEnumeratedValue());
var theInput = evaluateList (listStuff2[m].getList(stringIDToTypeID("input")));
var theGamma = listStuff2[m].getDouble(stringIDToTypeID("gamma"));
var theOutput = evaluateList (listStuff2[m].getList(stringIDToTypeID("output")));
theResult.push(theChannel+"\nthe input\n"+theInput+"\nthe gamma\n"+theGamma+"\nthe output\n"+theOutput+"\n\n");
};
};
alert ("levels\n"+theResult.join("\n"))
} catch (e) {
alert ("probably not a levels adjustment layer")
}
};
////////////////////////////////////
////// get list values //////
function evaluateList (aList) {
var listStuff = new Array;
for (var x = 0; x < aList.count; x++) {
var theType = aList.getType(x);
switch (theType) {
case DescValueType.ALIASTYPE:
listStuff.push( aList.getPath(x));
break;
case DescValueType.BOOLEANTYPE:
listStuff.push( aList.getBoolean(x));
break;
case DescValueType.CLASSTYPE:
listStuff.push( aList.getClass(x));
break;
case DescValueType.DOUBLETYPE:
listStuff.push( aList.getDouble(x));
break;
case DescValueType.ENUMERATEDTYPE:
listStuff.push( aList.getEnumerationValue(x));
break;
case DescValueType.INTEGERTYPE:
listStuff.push( aList.getInteger(x));
break;
case DescValueType.LISTTYPE:
listStuff.push( aList.getList(x));
break;
case DescValueType.OBJECTTYPE:
listStuff.push( (aList.getObjectValue(x)));
break;
case DescValueType.RAWTYPE:
listStuff.push( aList.getReference(x));
break;
case DescValueType.REFERENCETYPE:
listStuff.push( aList.getReference(x));
break;
case DescValueType.STRINGTYPE:
listStuff.push( aList.getString(x));
break;
case DescValueType.UNITDOUBLE:
listStuff.push( aList.getUnitDoubleValue(x));
break;
default:
break;
};
};
return listStuff
};
////// based on code by michael l hale //////
function checkDesc2 (theDesc, theAlert) {
var c = theDesc.count;
var str = '';
for(var i=0;i<c;i++){ //enumerate descriptor's keys
str = str + 'Key '+i+' = '+typeIDToStringID(theDesc.getKey(i))+': '+theDesc.getType(theDesc.getKey(i))+'\n'+getValues (theDesc, i)+'\n';
};
if (theAlert == true) {alert("desc\n\n"+str);
return};
return str
};
////// check //////
function getValues (theDesc, theNumber) {
switch (theDesc.getType(theDesc.getKey(theNumber))) {
case DescValueType.ALIASTYPE:
return theDesc.getPath(theDesc.getKey(theNumber));
break;
case DescValueType.BOOLEANTYPE:
return theDesc.getBoolean(theDesc.getKey(theNumber));
break;
case DescValueType.CLASSTYPE:
return theDesc.getClass(theDesc.getKey(theNumber));
break;
case DescValueType.DOUBLETYPE:
return theDesc.getDouble(theDesc.getKey(theNumber));
break;
case DescValueType.ENUMERATEDTYPE:
return (typeIDToStringID(theDesc.getEnumerationValue(theDesc.getKey(theNumber)))+"_"+typeIDToStringID(theDesc.getEnumerationType(theDesc.getKey(theNumber))));
break;
case DescValueType.INTEGERTYPE:
return theDesc.getInteger(theDesc.getKey(theNumber));
break;
case DescValueType.LISTTYPE:
return theDesc.getList(theDesc.getKey(theNumber));
break;
case DescValueType.OBJECTTYPE:
return (theDesc.getObjectValue(theDesc.getKey(theNumber))+"_"+typeIDToStringID(theDesc.getObjectType(theDesc.getKey(theNumber))));
break;
case DescValueType.RAWTYPE:
return theDesc.getReference(theDesc.getData(theNumber));
break;
case DescValueType.REFERENCETYPE:
return theDesc.getReference(theDesc.getKey(theNumber));
break;
case DescValueType.STRINGTYPE:
return theDesc.getString(theDesc.getKey(theNumber));
break;
case DescValueType.UNITDOUBLE:
return (theDesc.getUnitDoubleValue(theDesc.getKey(theNumber))+"_"+typeIDToStringID(theDesc.getUnitDoubleType(theDesc.getKey(theNumber))));
break;
default:
break;
};
};
Copy link to clipboard
Copied
@r-bin , does this work for you?
By @c.pfaffenbichler
I can't check anything since I don't have Photoshop 2023. In any case, there is no way to get values for adjustment layers when using auto mode. The problem was identified in this thread https://community.adobe.com/t5/photoshop-ecosystem-discussions/photoshop-script-to-invert-curves/m-p...
I don't have a solution due to the lack of ability to work with the latest versions of Photoshop. You can try to solve it by applying my attempts in that topic.
Copy link to clipboard
Copied
The last Script I posted would essentially just give the info that »auto« is in effect – see screenshot.
Thanks for pointing out the »auto«-issue, I am not sure if I manage to look into it – much less find a solution.
Copy link to clipboard
Copied
@r-bin , I think the easiest route may be a (crude) work-around:
Editing the Composite Channel gets rid of the »auto«-designation, so one can get the settings of the individual color Channels and then undo the change to the Composite Channel itself.
Copy link to clipboard
Copied
Well, how can you find out the parameters of the composite channel in this case? The rollback method is not very good. I'm not sure that it will work in "SuspendHistory" mode. In that thread, I attempted to falsely change a layer with empty parameters. They all worked for me in 2020. However, a person with a new Photoshop (like beta) claimed that he always had a “program error”. I checked the absence of "auto" using the json parameters for the layer. There is no trace of 'auto' in the adjustment layer itself in the "adjustment" list. It is not clear why they removed LegacyRawData. Can you try the methods that I did purely theoretically in that topic?
Copy link to clipboard
Copied
Thank you so much for this, Apologies for the delay in replying i've been away. It has absolutely done the trick! Many thanks
Copy link to clipboard
Copied
You’re welcome!