17 Replies Latest reply on Mar 11, 2011 12:32 PM by Michael L Hale

    Get values of adjustment layer

    jconor29 Level 1

      Is it possible, to get for example the brightness and the contrast of a brightness/contrast adjustment layer?

      I found only for solid color layer.

        • 1. Re: Get values of adjustment layer
          Michael L Hale Level 5

          What version of Photoshop are you using. Adobe changed the way adustments are stored and it is much harder to deal with in newer version.

          • 3. Re: Get values of adjustment layer
            Michael L Hale Level 5

            With CS4's new adjustment panel the adjustment is saved as raw data in the layer's descriptor. You can get that data with this code.

                 var ref = new ActionReference();
                 ref.putEnumerated( charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") ); 
                 var desc = executeActionGet(ref).getList(stringIDToTypeID('adjustment')).getObjectValue(0);
                 var rawData = desc.getData(stringIDToTypeID('legacyContentData'));
            

            The problem then is understanding the raw data. I have worked that out for some adjustments but not brightness/contrast.

             

            And maybe I (or my system) is having a bad day or Adobe has again changed the adjustment descriptor because none of the code I have including the code above works in ESTK with Photoshop CS5.

            • 4. Re: Get values of adjustment layer
              jconor29 Level 1

              Ok.Thanks!I will try to find it and I will let you know.

              • 5. Re: Get values of adjustment layer
                Michael L Hale Level 5

                A system restart now lets me get the raw data. But unless 'Use Legacy' is check on the bc adjustment layer the data is empty. With 'Use Legacy' check here is one way to get the settings

                 

                var ref = new ActionReference();
                     ref.putEnumerated( charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") ); 
                     var desc = executeActionGet(ref).getList(stringIDToTypeID('adjustment')).getObjectValue(0);
                     var rawData = desc.getData(stringIDToTypeID('legacyContentData'));
                      var brightness = rawData.charCodeAt(1);// get byte
                      if(brightness>127) brightness = 0xFFFFFF00^brightness;// check sign
                      var contrast = rawData.charCodeAt(3);
                       if(contrast>127) contrast = 0xFFFFFF00^contrast;
                       alert('The brightness is '+brightness+'\rContrast is '+contrast);
                

                If 'Use Legacy'is not check this will return 0,0 no matter what values are used in the adjustment layer.

                 

                I don't see a way to get the setting if 'Use Legacy' is not checked.

                • 6. Re: Get values of adjustment layer
                  jconor29 Level 1

                  That's great. Actually, I don't want use legacy to be selected(the default is unchecked, right?).

                  Maybe it is supported for previous versions only.How are adjustments stored in new versions?

                  Thanks again!

                  • 7. Re: Get values of adjustment layer
                    Michael L Hale Level 5

                    jconor29 wrote:

                     

                    How are adjustments stored in new versions?

                    That is the question. For most adjustment layers the values are stored in the 'legacyContentData' key. That data changes depending on what type of adjustment. But not brightness/contrast adjustment with use legacy unchecked( and yes that is the default).

                     

                    And I don't see anywhere else in the layer's descriptor where the settings could be stored.

                    • 8. Re: Get values of adjustment layer
                      jconor29 Level 1

                      Do you know about hue/saturation?

                      Thanks in advance!

                      • 9. Re: Get values of adjustment layer
                        Michael L Hale Level 5

                        You can get the raw data of a hue/saturation adjustment layer. However I have not tried to parse the data. If it is anything like curves, I would expect it to be a complex structure that depends on which color groups have been adjusted.

                         

                        A good place to start would be to save some hue/sat setting(.AHU) files and look at the structure of those files. I would expect the structure to be very similar to the rawData structure.

                        • 10. Re: Get values of adjustment layer
                          jconor29 Level 1

                          How can these files be read?


                          • 11. Re: Get values of adjustment layer
                            Michael L Hale Level 5

                            The files are binary so you will need an app that view/edit binary files. If you are on Windows you can try XVI32. It is free-ware and is what I use.

                             

                            But it is not an easy task to determine an unknown data structure from looking at the file with a hexeditor.

                            • 12. Re: Get values of adjustment layer
                              Michael L Hale Level 5

                              It looks like the rawData for hue/sat adjustment is set up as a group of words(two bytes) in big-endian(Motorola) byte order. The values below are in decimal.

                               

                              The first word seems to always be 2.

                               

                              The next word seems to be a flag for 'colorize'. If the second word is 256, 'colorize' is checked in the adjustment panel and the next three words have the hsl values used to colorize. If it is set to 0 then the next three words are 0. After that the next three words are the hsl values for 'Master'.

                               

                              The next four words starting at the ninth work are the values for the color range of 'Reds'. Then the next 3 words are the hsl values for "Reds".

                               

                              That pattern of seven words repeats for the other colors with the last word in the data being the value for the "Magentas" lightness.

                               

                              So there is a lot of data and I am not sure how to best turn it into a usable form. There also doesn't seem to be a way (other than checking for 0 values) to know if say only "Master" is set for the adjustment.

                              • 13. Re: Get values of adjustment layer
                                Michael L Hale Level 5

                                Soemthing like this

                                 

                                getHueSatAdjustment();
                                function getHueSatAdjustment(){     
                                      var ref = new ActionReference();
                                     ref.putEnumerated( charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") ); 
                                     var desc = executeActionGet(ref).getList(stringIDToTypeID('adjustment')).getObjectValue(0);
                                     var rawData = desc.getData(stringIDToTypeID('legacyContentData'));
                                      var hueSatAdjustment = {};
                                      hueSatAdjustment.isColorized = Boolean(readInteger(rawData, 2));
                                         hueSatAdjustment.colorized = {};
                                       hueSatAdjustment.colorized.hue = readInteger(rawData, 4);
                                       hueSatAdjustment.colorized.sat = readInteger(rawData, 6);
                                       hueSatAdjustment.colorized.brightness = readInteger(rawData, 8);
                                       hueSatAdjustment.master = {};
                                       hueSatAdjustment.master.hue = readInteger(rawData, 10);
                                       hueSatAdjustment.master.sat = readInteger(rawData, 12);
                                       hueSatAdjustment.master.brightness = readInteger(rawData, 14);
                                       hueSatAdjustment.reds = {};
                                       hueSatAdjustment.reds.beginRamp = readInteger(rawData, 16);
                                       hueSatAdjustment.reds.beginSustain = readInteger(rawData, 18);
                                       hueSatAdjustment.reds.endSustain = readInteger(rawData, 20);
                                       hueSatAdjustment.reds.endRamp = readInteger(rawData, 22);
                                       hueSatAdjustment.reds.hue = readInteger(rawData, 24);
                                       hueSatAdjustment.reds.sat = readInteger(rawData, 26);
                                       hueSatAdjustment.reds.brightness = readInteger(rawData, 28);
                                       hueSatAdjustment.yellows = {};
                                       hueSatAdjustment.yellows.beginRamp = readInteger(rawData, 30);
                                       hueSatAdjustment.yellows.beginSustain = readInteger(rawData, 32);
                                       hueSatAdjustment.yellows.endSustain = readInteger(rawData, 34);
                                       hueSatAdjustment.yellows.endRamp = readInteger(rawData, 36);
                                       hueSatAdjustment.yellows.hue = readInteger(rawData, 38);
                                       hueSatAdjustment.yellows.sat = readInteger(rawData, 40);
                                       hueSatAdjustment.yellows.brightness = readInteger(rawData, 42);
                                       hueSatAdjustment.greens = {};
                                       hueSatAdjustment.greens.beginRamp = readInteger(rawData, 44);
                                       hueSatAdjustment.greens.beginSustain = readInteger(rawData, 46);
                                       hueSatAdjustment.greens.endSustain = readInteger(rawData, 48);
                                       hueSatAdjustment.greens.endRamp = readInteger(rawData, 50);
                                       hueSatAdjustment.greens.hue = readInteger(rawData, 52);
                                       hueSatAdjustment.greens.sat = readInteger(rawData, 54);
                                       hueSatAdjustment.greens.brightness = readInteger(rawData, 56);
                                       hueSatAdjustment.cyans = {};
                                       hueSatAdjustment.cyans.beginRamp = readInteger(rawData, 58);
                                       hueSatAdjustment.cyans.beginSustain = readInteger(rawData, 60);
                                       hueSatAdjustment.cyans.endSustain = readInteger(rawData, 62);
                                       hueSatAdjustment.cyans.endRamp = readInteger(rawData, 64);
                                       hueSatAdjustment.cyans.hue = readInteger(rawData, 66);
                                       hueSatAdjustment.cyans.sat = readInteger(rawData, 68);
                                       hueSatAdjustment.cyans.brightness = readInteger(rawData, 70);
                                          hueSatAdjustment.blues = {};
                                          hueSatAdjustment.blues.beginRamp = readInteger(rawData, 72);
                                       hueSatAdjustment.blues.beginSustain = readInteger(rawData, 74);
                                       hueSatAdjustment.blues.endSustain = readInteger(rawData, 76);
                                       hueSatAdjustment.blues.endRamp = readInteger(rawData, 78);
                                       hueSatAdjustment.blues.hue = readInteger(rawData, 80);
                                       hueSatAdjustment.blues.sat = readInteger(rawData, 82);
                                       hueSatAdjustment.blues.brightness = readInteger(rawData, 84);
                                       hueSatAdjustment.magentas = {};
                                       hueSatAdjustment.magentas.beginRamp = readInteger(rawData, 86);
                                       hueSatAdjustment.magentas.beginSustain = readInteger(rawData, 88);
                                       hueSatAdjustment.magentas.endSustain = readInteger(rawData, 90);
                                       hueSatAdjustment.magentas.endRamp = readInteger(rawData, 92);       
                                       hueSatAdjustment.magentas.hue = readInteger(rawData, 94);
                                       hueSatAdjustment.magentas.sat = readInteger(rawData, 96);
                                       hueSatAdjustment.magentas.brightness = readInteger(rawData, 98);
                                       return hueSatAdjustment;
                                };
                                function readInteger(str, pointer) { //aka signed word = 2 bytes in big-endian byte order
                                  var b1 = str.charCodeAt(pointer);
                                  var b2 = str.charCodeAt(pointer+1);
                                  var ss = (b1 << 8) + b2;
                                  if(ss>0x7FFF){
                                     ss = 0xFFFF0000^ss;
                                  }
                                  return ss;
                                };
                                
                                • 14. Re: Get values of adjustment layer
                                  jconor29 Level 1

                                  Thank you so much! It was difficult for me to understand it. That's enough for what I need.

                                  (However, I think for colorize the hue is not correct because it has a different range.)

                                  • 15. Re: Get values of adjustment layer
                                    Michael L Hale Level 5

                                    jconor29 wrote:

                                     

                                    (However, I think for colorize the hue is not correct because it has a different range.)

                                    I'm not sure what you mean. When the colorize checkbox is checked in the adjustment, the range control is disabled. Same for Master. Only the colors such as Reds, Yellows, etc let you set the range.

                                     

                                    And at least on my system the script above returns the same value as the ones in the adjustment for the colorized settings when colorize is checked.

                                    • 16. Re: Get values of adjustment layer
                                      jconor29 Level 1

                                      When colorize is not checked, hue takes values between -180 and 180, when it is checked it ranges from 0 to 360. So, readinteger does not return the correct value if it is above 180. It just wants to take 180-hue if hue>180.

                                      • 17. Re: Get values of adjustment layer
                                        Michael L Hale Level 5

                                        Ssorry you are right. I created this for you and didn't test colorized hue values above 180. It seems that that angle is stored in two bytes but in a format that I don't fully understand. The code below does return the correct colorized hue value unless it is 360. It then return 0. 0 and 360 map to the same color and appears to be stored the same.

                                         

                                        getHueSatAdjustment().colorized.hue;
                                        function getHueSatAdjustment(){     
                                              var ref = new ActionReference();
                                             ref.putEnumerated( charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") ); 
                                             var desc = executeActionGet(ref).getList(stringIDToTypeID('adjustment')).getObjectValue(0);
                                             var rawData = desc.getData(stringIDToTypeID('legacyContentData'));
                                              var hueSatAdjustment = {};
                                              hueSatAdjustment.isColorized = readInteger(rawData, 2);
                                                 hueSatAdjustment.colorized = {};
                                               hueSatAdjustment.colorized.hue = readAngle(rawData, 4);
                                               hueSatAdjustment.colorized.sat = readInteger(rawData, 6);
                                               hueSatAdjustment.colorized.brightness = readInteger(rawData, 8);
                                               hueSatAdjustment.master = {};
                                               hueSatAdjustment.master.hue = readInteger(rawData, 10);
                                               hueSatAdjustment.master.sat = readInteger(rawData, 12);
                                               hueSatAdjustment.master.brightness = readInteger(rawData, 14);
                                               hueSatAdjustment.reds = {};
                                               hueSatAdjustment.reds.beginRamp = readInteger(rawData, 16);
                                               hueSatAdjustment.reds.beginSustain = readInteger(rawData, 18);
                                               hueSatAdjustment.reds.endSustain = readInteger(rawData, 20);
                                               hueSatAdjustment.reds.endRamp = readInteger(rawData, 22);
                                               hueSatAdjustment.reds.hue = readInteger(rawData, 24);
                                               hueSatAdjustment.reds.sat = readInteger(rawData, 26);
                                               hueSatAdjustment.reds.brightness = readInteger(rawData, 28);
                                               hueSatAdjustment.yellows = {};
                                               hueSatAdjustment.yellows.beginRamp = readInteger(rawData, 30);
                                               hueSatAdjustment.yellows.beginSustain = readInteger(rawData, 32);
                                               hueSatAdjustment.yellows.endSustain = readInteger(rawData, 34);
                                               hueSatAdjustment.yellows.endRamp = readInteger(rawData, 36);
                                               hueSatAdjustment.yellows.hue = readInteger(rawData, 38);
                                               hueSatAdjustment.yellows.sat = readInteger(rawData, 40);
                                               hueSatAdjustment.yellows.brightness = readInteger(rawData, 42);
                                               hueSatAdjustment.greens = {};
                                               hueSatAdjustment.greens.beginRamp = readInteger(rawData, 44);
                                               hueSatAdjustment.greens.beginSustain = readInteger(rawData, 46);
                                               hueSatAdjustment.greens.endSustain = readInteger(rawData, 48);
                                               hueSatAdjustment.greens.endRamp = readInteger(rawData, 50);
                                               hueSatAdjustment.greens.hue = readInteger(rawData, 52);
                                               hueSatAdjustment.greens.sat = readInteger(rawData, 54);
                                               hueSatAdjustment.greens.brightness = readInteger(rawData, 56);
                                               hueSatAdjustment.cyans = {};
                                               hueSatAdjustment.cyans.beginRamp = readInteger(rawData, 58);
                                               hueSatAdjustment.cyans.beginSustain = readInteger(rawData, 60);
                                               hueSatAdjustment.cyans.endSustain = readInteger(rawData, 62);
                                               hueSatAdjustment.cyans.endRamp = readInteger(rawData, 64);
                                               hueSatAdjustment.cyans.hue = readInteger(rawData, 66);
                                               hueSatAdjustment.cyans.sat = readInteger(rawData, 68);
                                               hueSatAdjustment.cyans.brightness = readInteger(rawData, 70);
                                                  hueSatAdjustment.blues = {};
                                                  hueSatAdjustment.blues.beginRamp = readInteger(rawData, 72);
                                               hueSatAdjustment.blues.beginSustain = readInteger(rawData, 74);
                                               hueSatAdjustment.blues.endSustain = readInteger(rawData, 76);
                                               hueSatAdjustment.blues.endRamp = readInteger(rawData, 78);
                                               hueSatAdjustment.blues.hue = readInteger(rawData, 80);
                                               hueSatAdjustment.blues.sat = readInteger(rawData, 82);
                                               hueSatAdjustment.blues.brightness = readInteger(rawData, 84);
                                               hueSatAdjustment.magentas = {};
                                               hueSatAdjustment.magentas.beginRamp = readInteger(rawData, 86);
                                               hueSatAdjustment.magentas.beginSustain = readInteger(rawData, 88);
                                               hueSatAdjustment.magentas.endSustain = readInteger(rawData, 90);
                                               hueSatAdjustment.magentas.endRamp = readInteger(rawData, 92);       
                                               hueSatAdjustment.magentas.hue = readInteger(rawData, 94);
                                               hueSatAdjustment.magentas.sat = readInteger(rawData, 96);
                                               hueSatAdjustment.magentas.brightness = readInteger(rawData, 98);
                                               return hueSatAdjustment;
                                        };
                                        function readInteger(str, pointer) { //aka signed word = 2 bytes in big-endian byte order
                                          var b1 = str.charCodeAt(pointer);
                                          var b2 = str.charCodeAt(pointer+1);
                                          var ss = (b1 << 8) + b2;
                                          if(ss>0x7FFF){
                                             ss = 0xFFFF0000^ss;
                                          }
                                          return ss;
                                        };
                                        function readAngle(str, pointer) { 
                                             var b1 = str.charCodeAt(pointer);
                                             var b2 = str.charCodeAt(pointer+1);// if hue is 0 or 360 both == 0
                                             if(b1==0){// will be either 0 for less than 181
                                                  var ss = b2;// range 0-180
                                             }else{// or 256 for greater than 181
                                                  var ss = b2+104;//if b1 is 256 b2 range 77-256 
                                             }
                                          return ss;
                                        };