12 Replies Latest reply on May 22, 2016 2:34 PM by Chuck Uebele

    pixel count on Hue-value (hsb)

    scrapheap

      Allready created a base extension fot Photoshop CC2015. But now for the content of that extension.

       

      I would like to create a histogram with a pixelcount (on the y-axis) for each hue-value (hsb: 0 - 360) on the x-axis.

       

      Is that possible, and if so could you please guide me in the direction of the object needed or the path to a solution.

       

      I have been looking through the scripting-reference but don't know where to start.

       

       

      Thank you

        • 1. Re: pixel count on Hue-value (hsb)
          scrapheap Level 1

          update:

           

          I discovered the HSB/HSL-filter. And with that filter a channel (red-channel) representing the Hue-values in the image. Just about what I am looking for. A histogram represents 256 values instead of 360, but that will probable not be a big problem.

           

          So new question: How to access the histogram data-array of this channelmask.

          • 2. Re: pixel count on Hue-value (hsb)
            Chuck Uebele Adobe Community Professional & MVP

            The below code will put the red channel values into the array hisR. You can loop through that to get individual values.

            var doc = activeDocument;
            var hisR = doc.channels[0].histogram;
            
            1 person found this helpful
            • 3. Re: pixel count on Hue-value (hsb)
              scrapheap Level 1

              Thank you, I can start with that.

              • 4. Re: pixel count on Hue-value (hsb)
                scrapheap Level 1

                Oke, I managed to retrieve the (doc.channels[0].histogram:) array, but something isn't right. And I don't understand what it is I am missing.

                 

                My functions that process the data don't seem to work when fed with this array. While they do work if I provide a manual dummy-example.

                 

                arrayThatWorks = [10,5,5,10,2];

                 

                I only have an alert available in photoshop to check the content of the array.

                it returns (doc.channels[0].histogram:) array):

                 

                1111514,1262,1661,2420,3539,4740,6407,31464,19120,67877,62807,91558,94620,52893,35566,3144 1,39573,26136,35542,42532,25739,25021,13592,10219,6376,4423,2358,3886,318050,444,1318,997, 361,157,71418,174,794,409,73,231,114,209,9,461834,57,71,54,174,35,107,110,1313,73,20,17,26 ,18,10,11,7,10,10,5,1,2,2,0,0,7,3,1,23,0,6,4,1,0,0,3,1,2,1,0,0,0,2,0,0,1,0,2,0,0,0,6,1,0,1 ,0,0,2,0,0,1,0,0,0,17241,0,0,0,0,1,0,1,0,0,5,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,3,0,0,0 ,0,0,0,1,0,1,1,0,0,0,0,0,0,0,3,17,0,0,0,0,0,6,0,3,0,0,0,0,0,0,28,0,0,0,0,0,0,3,12,0,0,0,0, 0,0,0,0,14,3,0,0,0,0,0,0,0,0,0,13,0,5,0,0,0,0,11,0,2,0,0,0,0,9,0,0,0,0,0,0,0,0,6,0,0,0,0,0 ,4,0,0,0,2,5,0,11260,1,1,0,0,26,7,163,5,3,380,18,138,126,300,366,1633,1566,1391,1245,1355

                 

                And when I feed this data manually into the dummy array it also all works fine.

                 

                What is going on here? How can I get the histogam data to work?

                • 5. Re: pixel count on Hue-value (hsb)
                  Chuck Uebele Adobe Community Professional & MVP

                  I'm not really sure how you're processing the data. The array that you show only has five values. The histogram array should have 256 values, with the first value of the count of pixels with a value of 0, and so forth. What isn't working?

                  • 6. Re: pixel count on Hue-value (hsb)
                    scrapheap Level 1

                    below is the main.js

                     

                    What it should do:

                    - get the histogram data (via the hotscript.jsx)

                    - recalculate the data so the values are between 0 and 10

                    - render a radar chart with the data.

                     

                    And it does all that! But only if I create my own array, shown here as hisRw.

                     

                    What I don't understand is why the function 'indexeer()' doesn't work when using the array 'hisR'. And to make it more complicated: it does work when I copy the content from hisR from the alert window and feed it into hisRw and use hisRw.

                     

                     

                    hotscript,jsx

                    /*jslint vars: true, plusplus: true, devel: true, nomen: true, regexp: true, indent: 4, maxerr: 50 */
                    /*global $, Folder*/
                    
                    
                    function getChartData() {
                        // Hue-values from channel(red) after HSB/HSL filter
                        var doc = activeDocument;  
                        var hChannelData = doc.channels[0].histogram;
                        
                        return hChannelData;
                    }
                    

                     

                     

                    main,js

                    /*jslint vars: true, plusplus: true, devel: true, nomen: true, regexp: true, indent: 4, maxerr: 50 */
                    /*global $, window, location, CSInterface, SystemPath, themeManager*/
                    
                    
                    (function () {
                        'use strict';
                    
                    
                        var csInterface = new CSInterface();
                        window.hisR = [];
                        
                        function init() {
                                    
                            themeManager.init();
                            
                                
                            // get data array
                            csInterface.evalScript('getChartData();', function (result) {
                                window.hisR = result;
                                return window.hisR;
                            });
                            
                            // "refresh chart"-button
                            $("#btn_gaan").click(function () {
                    
                    
                                csInterface.evalScript('radarChart()', function (result) {
                                    
                                    //var hisRw = [1111514,1262,1661,2420,3539,4740,6407,31464,19120,67877,62807,91558,94620,52893,35566,31441,39573,26136,35542,42532,25739,25021,13592,10219,6376,4423,2358,3886,318050,444,1318,997,361,157,71418,174,794,409,73,231,114,209,9,461834,57,71,54,174,35,107,110,1313,73,20,17,26,18,10,11,7,10,10,5,1,2,2,0,0,7,3,1,23,0,6,4,1,0,0,3,1,2,1,0,0,0,2,0,0,1,0,2,0,0,0,6,1,0,1,0,0,2,0,0,1,0,0,0,17241,0,0,0,0,1,0,1,0,0,5,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,1,0,1,1,0,0,0,0,0,0,0,3,17,0,0,0,0,0,6,0,3,0,0,0,0,0,0,28,0,0,0,0,0,0,3,12,0,0,0,0,0,0,0,0,14,3,0,0,0,0,0,0,0,0,0,13,0,5,0,0,0,0,11,0,2,0,0,0,0,9,0,0,0,0,0,0,0,0,6,0,0,0,0,0,4,0,0,0,2,5,0,11260,1,1,0,0,26,7,163,5,3,380,18,138,126,300,366,1633,1566,1391,1245,1355];
                                    alert('hisR0: ' + window.hisR);
                                    
                                                    
                                    // recalculate the values from the array to a value between 0 and 10
                                    function indexeer(array) {
                                        var indext = [];
                                        var highest = Math.max.apply(Math, array);
                                        for (var i = 0; i < array.length; i++){
                                            indext.push( (array[i]/highest) * 10 );
                                        }
                                        return indext;
                                    }
                                                
                                    var chartDataClean = indexeer(window.hisR);
                                    //var chartDataClean = indexeer(hisRw);
                                    alert('chartDataClean: '+chartDataClean);
                                                
                                    
                                    // render radarChart
                                    $('#hChart').radarChart({
                                      size: [240, 240],
                                      step: 1,
                                      fixedMaxValue:9,
                                      values: chartDataClean
                                    });
                                });
                            });
                        }
                            
                        init();
                    
                    
                    }());
                    
                    • 7. Re: pixel count on Hue-value (hsb)
                      Chuck Uebele Adobe Community Professional & MVP

                      Are you getting an error code, or what is happening when you try and use the histogram array? Is there a reason you're doing all this calculation in your main js script rather than the PS jsx script?

                      • 8. Re: pixel count on Hue-value (hsb)
                        scrapheap Level 1

                        No error codes. It looks like the code just stops running. (no more alerts)

                        I am running the extension in photoshop via Brackets because I need the histogram data. And I don't know how to get feedback within photoshop. Therefore I am limited to alerts. No console logs. But if there is a way.... please tell me....

                         

                        There is no particular reason. I guess I started with a example script and kept working in the main.js. I'll rework it when things work proper.

                         

                        ---

                         

                        update:

                        I started doubting whether or not the histogram-array was actually an array. Or maybe an object.

                         

                        so I tested this line of code where I put object values in a new array:

                         

                            csInterface.evalScript('getChartData();', function (result) {
                                window.hisR = [];
                                for(var i in result) {window.hisR.push(result[i]);}
                                
                                //alert('hisR: ' + window.hisR);
                                return window.hisR;
                            });
                        

                         

                         

                        And that works! Now the radar chart is rendered with the histogram data. At last....

                         

                        Luckaly also new problems arose. Now I am confronted with asynchronous issues. But thats an other story.

                         

                        thank you for your help.

                        • 9. Re: pixel count on Hue-value (hsb)
                          Chuck Uebele Adobe Community Professional & MVP

                          I was beginning to wonder the same thing about the histogram being an array. Glad you got it working. There is a bit of code to make things write to the ESTK when using Brackets, but now I can't find it. I think Tom Ruark gave it to me.

                          • 10. Re: pixel count on Hue-value (hsb)
                            Chuck Uebele Adobe Community Professional & MVP

                            I found the script that Tom Ruark gave me to have output sent to ESTK console, when using Brackets:

                             

                            // output to the ESTK console
                            
                            /*
                            this.print = function( inMessage ) {
                            if ( app.name == "ExtendScript Toolkit" ) {
                            print (inMessage);
                            }
                            else {
                            var btMessage = new BridgeTalk();
                            btMessage.target = "estoolkit";
                            btMessage.body = "print(" + inMessage.toSource() + ")";
                            btMessage.send ();
                            }
                            
                            */
                            // might need to escape and encode the inMessage as well to deal with double quotes and single quotes in inMessage
                            function MyWriteln(inMessage) {
                                // comment this out for production code
                                if ( ! BridgeTalk.isRunning( "estoolkit" ) )
                                    BridgeTalk.launch( "estoolkit" );
                            
                                if ( BridgeTalk.isRunning( "estoolkit" ) ) {
                                    if ( app.name == "ExtendScript Toolkit" ) {
                                        $.writeln("help me " + inMessage);
                                  } else {
                                        var bt = new BridgeTalk;
                                        bt.body = "$.writeln('help me : " + inMessage + "');";
                                        bt.target = "estoolkit";
                                  bt.send();
                                  }
                                }
                            }
                            
                            • 11. Re: pixel count on Hue-value (hsb)
                              scrapheap Level 1

                              Thank you for this script. Will try it out.

                               

                              in the meantime;

                              I reworked the code and it became a lot simpler now I understand things better.

                               

                              But one annoying issue remains.

                               

                              In the main.js I call the hostscript for histogram data and I get an variable back with the values.

                               

                              if I alert this variable I get: 10,0,0

                               

                              when I pass this variable into my chart script nothing happens. As we found out ealier. The variable isn't an array. It appears to be an object. So I push the values into a new array. with this function

                               

                              // Push result.values in new array
                              var resultValues = [];
                              for (var i in result) { resultValues.push(result[i]);}
                              

                               

                              The chart script then will render a chart. But the values it uses are wrong. I  found out that the resultValues array looks like this

                              it should be: 10,0,0

                              it actually is: 1,0,,,0,,,0,

                               

                              Why is the value '10' not recognised as 10 but as a '1' and a '0'

                               

                              How can I push the correct values from the object into a array?

                               

                               

                              update:

                               

                              Found the answer just seconds after posting this reply

                               

                              var resultValues = result.split(","); and now all is how it should be.

                              • 12. Re: pixel count on Hue-value (hsb)
                                Chuck Uebele Adobe Community Professional & MVP

                                I think what issue might be is that passing info from a jsx file to your main js file only can pass a string. So the array is converted to a string, so using the split creates an array again.