17 Replies Latest reply on Aug 21, 2017 7:23 AM by c.pfaffenbichler

    Iterating image lines pixel by pixel

    andyf65867865 Level 1

      Could you show an example how to iterate image file lines pixel by pixel to detect is pixel line is completely "white" i.e. empty or not empty i.e. "not white".

      So if line is full of white pixels then result is 0 if not then result is 1. Just for a sample.


      The example is below. As you can observe, some lines are completely emty while othes is not. So how to iterate such an image in Photoshop script?

      Untitled-1.png

        • 1. Re: Iterating image lines pixel by pixel
          Chuck Uebele Adobe Community Professional & MVP

          You can try this:

           

          #target photoshop
          var doc = activeDocument
          
          for(var i=0;i<doc.height;i++){
              doc.selection.deselect();
              getSelect (i, 0, i+1, doc.width)
              if(doc.histogram[255]==parseInt (doc.width)){
                  checkSelet (i);
                  if(doc.selection.bounds[2]<doc.width){$.writeln(false)}
                  else{$.writeln(true)}
                  }
              else{$.writeln(false)}
             }
          
          function getSelect(top,left,bottom,right){
              var idsetd = charIDToTypeID( "setd" );
                  var desc6 = new ActionDescriptor();
                  var idnull = charIDToTypeID( "null" );
                      var ref1 = new ActionReference();
                      var idChnl = charIDToTypeID( "Chnl" );
                      var idfsel = charIDToTypeID( "fsel" );
                      ref1.putProperty( idChnl, idfsel );    
              desc6.putReference( idnull, ref1 );
              var idT = charIDToTypeID( "T   " );
                  var desc7 = new ActionDescriptor();
                  var idTop = charIDToTypeID( "Top " );
                  var idPxl = charIDToTypeID( "#Pxl" );
                  desc7.putUnitDouble( idTop, idPxl, top );
                  var idLeft = charIDToTypeID( "Left" );
                  var idPxl = charIDToTypeID( "#Pxl" );
                  desc7.putUnitDouble( idLeft, idPxl, left );
                  var idBtom = charIDToTypeID( "Btom" );
                  var idPxl = charIDToTypeID( "#Pxl" );
                  desc7.putUnitDouble( idBtom, idPxl, bottom );
                  var idRght = charIDToTypeID( "Rght" );
                  var idPxl = charIDToTypeID( "#Pxl" );
                  desc7.putUnitDouble( idRght, idPxl, right );
              var idRctn = charIDToTypeID( "Rctn" );
              desc6.putObject( idT, idRctn, desc7 );
              executeAction( idsetd, desc6, DialogModes.NO );    
              }
          
          function checkSelet(y){
                  var idIntW = charIDToTypeID( "IntW" );
                  var desc10 = new ActionDescriptor();
                  var idnull = charIDToTypeID( "null" );
                      var ref2 = new ActionReference();
                      var idChnl = charIDToTypeID( "Chnl" );
                      var idfsel = charIDToTypeID( "fsel" );
                      ref2.putProperty( idChnl, idfsel );
                  desc10.putReference( idnull, ref2 );
                  var idT = charIDToTypeID( "T   " );
                      var desc11 = new ActionDescriptor();
                      var idHrzn = charIDToTypeID( "Hrzn" );
                      var idPxl = charIDToTypeID( "#Pxl" );
                      desc11.putUnitDouble( idHrzn, idPxl, 1 );
                      var idVrtc = charIDToTypeID( "Vrtc" );
                      var idPxl = charIDToTypeID( "#Pxl" );
                      desc11.putUnitDouble( idVrtc, idPxl, y );
                  var idPnt = charIDToTypeID( "Pnt " );
                  desc10.putObject( idT, idPnt, desc11 );
                  var idTlrn = charIDToTypeID( "Tlrn" );
                  desc10.putInteger( idTlrn, 0 );
                  var idAntA = charIDToTypeID( "AntA" );
                  desc10.putBoolean( idAntA, true );
              executeAction( idIntW, desc10, DialogModes.NO );
              }
          
          1 person found this helpful
          • 2. Re: Iterating image lines pixel by pixel
            andyf65867865 Level 1

            where did u get it...

            • 3. Re: Iterating image lines pixel by pixel
              Chuck Uebele Adobe Community Professional & MVP

              I wrote it. Just a word of warning, It won't detect a full line that's transparent. Placing a colored layer under the layer you're checking would work better.

              • 4. Re: Iterating image lines pixel by pixel
                andyf65867865 Level 1

                I tried it with ps cs6 on 1 by 1 pixel document.
                It only outputs false while pixel is white but if pixel is not white then there is an error

                 

                 

                fghj.jpg

                • 5. Re: Iterating image lines pixel by pixel
                  Chuck Uebele Adobe Community Professional & MVP

                  I'll have to take a look later and see if my CS6 still works.

                  • 6. Re: Iterating image lines pixel by pixel
                    SuperMerlin Level 5

                    Just shortened your code Chuck and it does work now in CS6.

                    #target photoshop  
                    var doc = activeDocument       
                    for(var i=0;i<doc.height;i++){   
                        getSelect (i, 0, i+1, doc.width);
                        if(doc.histogram[255]==Number (doc.width))  $.writeln(true);
                        else $.writeln(false);
                    }       
                    doc.selection.deselect(); 
                    
                    function getSelect(top,left,bottom,right){  
                    var desc6 = new ActionDescriptor();  
                    var ref1 = new ActionReference();  
                    ref1.putProperty( charIDToTypeID('Chnl'), charIDToTypeID('fsel') );      
                    desc6.putReference( charIDToTypeID('null'), ref1 );  
                    var desc7 = new ActionDescriptor();  
                    desc7.putUnitDouble( charIDToTypeID('Top '), charIDToTypeID('#Pxl'), top );  
                    desc7.putUnitDouble( charIDToTypeID('Left'), charIDToTypeID('#Pxl'), left );  
                    desc7.putUnitDouble( charIDToTypeID('Btom'), charIDToTypeID('#Pxl'), bottom );  
                    desc7.putUnitDouble( charIDToTypeID('Rght'), charIDToTypeID('#Pxl'), right );  
                    desc6.putObject( charIDToTypeID('T   '), charIDToTypeID('Rctn'), desc7 );  
                    executeAction( charIDToTypeID('setd'), desc6, DialogModes.NO );     
                    };  
                    
                    
                    
                    • 7. Re: Iterating image lines pixel by pixel
                      Chuck Uebele Adobe Community Professional & MVP

                      Thanks. With PS 2017, it was registering transparent as white with the histogram. A full lime of transparent might throw that error.

                      • 8. Re: Iterating image lines pixel by pixel
                        SuperMerlin Level 5

                        Yes transparency does show as white in the histogram, it would take a lot more code to work out those lines.

                        • 9. Re: Iterating image lines pixel by pixel
                          andyf65867865 Level 1

                          not sure is the code works properly...


                          for example, with the following sample picture (10 px height)
                          Untitled-1.png
                          it outputs in javascript console

                          false

                          false

                          false

                          false

                          but for I understand it it should outputs next

                          false

                          false

                          true

                          false

                          true

                          false

                          false

                          true

                          false

                          false

                           

                          because there are 10 lines in the picture and only three lines contains not white pixels

                           

                          note that transparency does not matter here because source image will be flat

                           

                          Am I describe the idea clear?

                          • 10. Re: Iterating image lines pixel by pixel
                            SuperMerlin Level 5

                            Try this version...

                            #target photoshop;
                            app.bringToFront();
                            
                            main();
                            function main(){
                            if(!documents.length) return;
                            try{
                            var doc = app.activeDocument;
                            app.displayDialogs = DialogModes.NO;
                            var strtRulerUnits = app.preferences.rulerUnits;
                            var strtTypeUnits = app.preferences.typeUnits;
                            app.preferences.rulerUnits = Units.PIXELS;
                            app.preferences.typeUnits = TypeUnits.PIXELS;
                            Left =0; Top = 0; Right = doc.width; Bottom =1;
                            var lineType=[];
                            for(var a = 0;a<doc.height; a++){
                            activeDocument.selection.select([[Left,Top],[Right,Top],[Right,Bottom],[Left,Bottom]], SelectionType.REPLACE, 0, false);
                            Top++; Bottom++;
                            var area = activeDocument.histogram;
                            if(area[255] != doc.width.value){
                            lineType.push(1);
                            }else{
                            lineType.push(0);
                            }}
                            activeDocument.selection.deselect();
                            var w = new Window("dialog","Lines",undefined, {closeButton: false});
                            w.dl = w.add("dropdownlist");
                            for(var z in lineType){w.dl.add("item", "Line " +(Number(z)+1) + " = " + lineType[z]);}
                            w.dl.selection=0;
                            w.b = w.add("button",undefined,"Okay");
                            w.b.onClick = function(){w.close(0);}
                            w.show();
                            }catch(e){}
                            finally{
                            app.preferences.rulerUnits = strtRulerUnits;
                            app.preferences.typeUnits = strtTypeUnits;
                            }
                            };
                            
                            
                            
                            
                            
                            1 person found this helpful
                            • 11. Re: Iterating image lines pixel by pixel
                              c.pfaffenbichler Level 9

                              Using the data from a RAW duplicate might be faster especially for larger images.

                              // based on code by paul riggott;

                              // 2017, use it at your own risk;

                              #target photoshop

                              File.prototype.readByte = function() {

                                return this.read(1).charCodeAt(0);

                              };

                              function convertByteToSignedByte(num){

                                   var dec = (num | (num % 256))-128

                                   return dec;

                              };

                              function convertByteToLum( num){

                                   var dec = Math.round((num/256)*100);

                                   return dec;

                              };

                              function main(){

                              if(!documents.length) return;

                              if(activeDocument.mode != DocumentMode.LAB) {

                              var theCopy = activeDocument.duplicate("theCopy", true);

                                  var desc3 = new ActionDescriptor();

                                  desc3.putClass( charIDToTypeID( "T   " ), charIDToTypeID( "LbCM" ) );

                              executeAction( charIDToTypeID( "CnvM" ), desc3, DialogModes.NO );

                                  }

                              var Name = decodeURI(app.activeDocument.name).replace(/\.[^\.]+$/, '');

                              try{

                              var Path = activeDocument.path;

                              }catch(e){var Path = '~/Desktop';}

                              var rawFile = new File(Path +"/"+Name +".raw");

                              saveAsRaw(rawFile);

                              var len = 0;

                              var W = activeDocument.width.as('px');

                              CountW=0;

                              CountH=0;

                              rawFile.encoding = 'BINARY';

                              rawFile.open('r');

                              var theArray = new Array;

                              //////////////////

                              var theCheck = true;

                              while(!rawFile.eof){

                              var theL = convertByteToLum(rawFile.readByte());

                              convertByteToSignedByte(rawFile.readByte());

                              convertByteToSignedByte(rawFile.readByte());

                              if (theL != 100) {theCheck = false}; 

                                   len++;

                                   if(len % W == 0){

                                       CountH++;

                                       CountW=0;

                                theArray.push(theCheck);

                              var theCheck = true;

                                       }

                                else{

                                  CountW++;

                                   }

                              };

                              rawFile.close();

                              rawFile.remove();

                              try {theCopy.close(SaveOptions.DONOTSAVECHANGES)}

                              catch (e) {};

                              alert ("line white\n"+theArray.join("\n"))

                              };

                              //var time1 = Number(timeString());

                              main();

                              //var time2 = Number(timeString());

                              //alert("time: "+((time2-time1)/1000)+" seconds\nstart "+time1+"\nend "+time2);

                              function saveAsRaw(file) {

                              var desc1 = new ActionDescriptor();

                              var desc2 = new ActionDescriptor();

                              desc2.putString( charIDToTypeID('FlCr'), "8BIM" );

                              desc2.putBoolean( charIDToTypeID('ChnI'), true );

                              desc1.putObject( charIDToTypeID('As  '), charIDToTypeID('Rw  '), desc2 );

                              desc1.putPath( charIDToTypeID('In  '), new File( file ) );

                              desc1.putBoolean( charIDToTypeID('Cpy '), true );

                              executeAction( charIDToTypeID('save'), desc1, DialogModes.NO );

                              };

                              ////// function to get the date //////

                              function timeString () {

                                var now = new Date();

                                return now.getTime()

                                };

                              1 person found this helpful
                              • 12. Re: Iterating image lines pixel by pixel
                                andyf65867865 Level 1

                                For some reason the code works too slow on real size A4 300 dpi documents... Maybe there is other fast logic to complete the same process?

                                • 13. Re: Iterating image lines pixel by pixel
                                  SuperMerlin Level 5

                                  Sorry no there isn't.

                                  Matlab might be the way to go though as Photoshop is not good at this sort of thing.

                                  • 14. Re: Iterating image lines pixel by pixel
                                    c.pfaffenbichler Level 9

                                    Have you tried the RAW code?

                                    • 15. Re: Iterating image lines pixel by pixel
                                      andyf65867865 Level 1

                                      Yes, I have tried the RAW code. It works allmost identical if not longer and there were some troubles with finishing the process.

                                      • 16. Re: Iterating image lines pixel by pixel
                                        c.pfaffenbichler Level 9

                                        Can you provide a file for testing?

                                        • 17. Re: Iterating image lines pixel by pixel
                                          c.pfaffenbichler Level 9

                                          In my test with an 8bit RGB image (210mm x 297mm at 300ppi) Supermerlin’s Script took only about half the time the Raw one did (roughly 27sec and 54sec).

                                          So the advantage I had noticed in previous testing was apparently owed to some intermediate image size …