Guide positions

Discussion of Photoshop Scripting, Photoshop Actions and Photoshop Automation in General

Moderators: Tom, Kukurykus

myranalis

Guide positions

Post by myranalis »

I'm using a bit of code I found in another post, modified to suit my needs. Original post: bb/viewtopic.php?t=2818&highlight=guides. ... ght=guides

I needed to be able to access horizontal and vertical guides seperately and know for certain they were in acending order so the guideinfo object is a bit different, but I'm having a bit of trouble with the 'n' variable.

This method:
Code: Select allvar n = Number( '0x'+str.charCodeAt( pointer ).toString(16)+str.charCodeAt( pointer+1).toString(16)+str.charCodeAt( pointer+2).toString(16)+str.charCodeAt( pointer+3).toString(16))/32;

Most of the time it appears to be correct, but some documents it is comming up with random numbers. (Send me an email at myranalis at hotmail dot com if you want a problem document).

I noticed later versions of the code have a different way to calculate n:

Code: Select allvar n = ((str[pointer] << 3) + (str[pointer+1] << 2) + (str[pointer+2] << 1) + str[pointer+3])/32;

but that method just gives me an NaN value for n.

Can anyone give me a clue as to what is wrong? My full function following... Thx

Anna

Code: Select all///////////////////////////////////////////////////////////////////////////////
// Function: getGuideInfo
// Description: Saves the document as a temp jpg file
//                        and extracts the info about the guides
//                        in document if any
// Usage: var guides = getGuideInfo( activeDocument );
// Input: Document
// Return: Object: TotalCount property  = number of guides
//                  HorizontalCount property = number of horizontal guides
//                  VerticalCount property = number of vertical guides
//                  Horizontal = horizontal guides
//                  Vertical property = vertical guides
// Source: Modified from bb/viewtopic.php?t=2818&highlight=guides
///////////////////////////////////////////////////////////////////////////////
function getGuideInfo( doc ) {
   saveOptions = new JPEGSaveOptions();
   // we don't care about image quality in the temp file
   // we do want the smallest file size
   saveOptions.quality = 0;// we don't care about image quality in the temp file
   var tempFile = new File( Folder.temp + '/' + File().name + '.jpg');

   // Dupe the doc, make it savable as JPEG, save it, then close the file
   doc = doc.duplicate();
   if( doc.mode == DocumentMode.BITMAP ) doc.changeMode(ChangeMode.GRAYSCALE);
   doc.bitsPerChannel = BitsPerChannelType.EIGHT;
   doc.changeMode(ChangeMode.RGB);
   doc.saveAs(tempFile, saveOptions, true);
   doc.close(SaveOptions.DONOTSAVECHANGES);

  tempFile.encoding = 'BINARY';
  tempFile.open('r');
  var str = tempFile.read();
  tempFile.close();
  tempFile.remove();
 
   var guideTag = '8BIM\x04\x08';
   var tagPos = str.search(guideTag);
   var guides = new Object;
   guides.toString = function(){ return 'GuideInfo'; }
   
   var horGuides = new Array;
   var vertGuides = new Array;
   
   if( tagPos != -1 ) {
      var tagLength = 12 + str.charCodeAt( tagPos + 11 );
      var guideStr = str.substring( tagPos, tagPos+tagLength );
      guides.count = str.charCodeAt( tagPos + 27 );
    
      var pointer = tagPos + 28;
      for( var i =0; i < guides.count; i++ ){
       //  var n = ((str[pointer] << 3) + (str[pointer+1] << 2) + (str[pointer+2] << 1) + str[pointer+3])/32;
      var n = Number( '0x'+str.charCodeAt( pointer ).toString(16)+str.charCodeAt( pointer+1).toString(16)+str.charCodeAt( pointer+2).toString(16)+str.charCodeAt( pointer+3).toString(16))/32;
      
       if  (str.charCodeAt( pointer + 4 ) == 0) {
          //vertical
          vertGuides = insertValueInOrder(vertGuides, n);
       } else {
          //horizontal
          horGuides = insertValueInOrder(horGuides, n);
       }   
      
        // guides[ i ] =  [ (str.charCodeAt( pointer + 4 ) ? 'horz':'vert'), n ];     
         pointer = pointer + 5;
      }
 
     guides.HorizontalCount =horGuides.length;
     guides.VerticalCount =vertGuides.length;
     guides.Horizontal = horGuides;
     guides.Vertical = vertGuides;
   }else{
      guides.TotalCount = 0;
     guides.HorizontalCount =0;
     guides.VerticalCount =0;
   }

Professional AI Audio Generation within Adobe Premiere Pro - Download Free Plugin here

Mike Hale

Guide positions

Post by Mike Hale »

I have tracked it down to a byte order error. Mac and Windows store multi-byte values differently. I know how to find the byte order in a tiff file but I had thought the jpeg files were always stored in Windows/PC order.

The byte order used is not in the tag for the guides. So I will have try to find it elsewhere.

I'll post the fix if I can find one.
Mike Hale

Guide positions

Post by Mike Hale »

I'm not sure that I can come up with a fix for this. I'm using Windows and if I add a guide to the sample file created on a Mac, the existing guides are still in the wrong byte order. But the new guide is in the byte order the script expects.

So the guide tag now has 4 entries with the values stored in mixed byte order( 3 in Mac order, 1 in Win ) without any way I can see to tell which byte order to read the values.
Mike Hale

Guide positions

Post by Mike Hale »

It turns out it was the byte order after all. It was an error in the code used to read the 4 bytes of the guide position. If the last byte was less that 15 the next to last byte gets shifted down. i.e. 0x008d00 is read as 0x008d0

This corrects that error.

Code: Select all#target photoshop
app.bringToFront();

/* the info about guides can be found in the photoshop tag hex 35 42 49 4D 04 08
   the length of the tag is found at offset 11. that value is the length to the next tag
   the number of guides can be found at offset 27. From that point the data repeats
   for each guide. 4 bytes for the location. That value / 32 = pixels
   and one byte for type 0 = vert and 1 = horz
   Note: this info is just a best guess from looking at the data
*/
///////////////////////////////////////////////////////////////////////////////
// Function: getGuideInfo
// Description: Saves the document as a temp jpg file
//                        and extracts the info about the guides
//                        in document if any
// Usage: var guides = getGuideInfo( activeDocument );
// Input: Document
// Return: Object: TotalCount property  = number of guides
//                  HorizontalCount property = number of horizontal guides
//                  VerticalCount property = number of vertical guides
//                  Horizontal = horizontal guides
//                  Vertical property = vertical guides
// Source: Modified from bb/viewtopic.php?t=2818&highlight=guides
///////////////////////////////////////////////////////////////////////////////
function getGuideInfo( doc ) {
   saveOptions = new JPEGSaveOptions();
   // we don't care about image quality in the temp file
   // we do want the smallest file size
   saveOptions.quality = 0;// we don't care about image quality in the temp file
   var tempFile = new File( Folder.temp + '/' +'guideTemp.jpg' );

   // Dupe the doc, make it savable as JPEG, save it, then close the file
   doc = doc.duplicate();
   if( doc.mode == DocumentMode.BITMAP ) doc.changeMode(ChangeMode.GRAYSCALE);
   doc.bitsPerChannel = BitsPerChannelType.EIGHT;
   doc.changeMode(ChangeMode.RGB);
   doc.saveAs(tempFile, saveOptions, true);
   doc.close(SaveOptions.DONOTSAVECHANGES);

  tempFile.encoding = 'BINARY';
  tempFile.open('r');
  var str = tempFile.read();
  tempFile.close();
  tempFile.remove();
 
   var guideTag = '8BIM\x04\x08';
   var tagPos = str.search(guideTag);
   var guides = new Object;
   guides.toString = function(){ return 'GuideInfo'; }
   
   var horGuides = new Array;
   var vertGuides = new Array;
   
   if( tagPos != -1 ) {
      var tagLength = 12 + str.charCodeAt( tagPos + 11 );
      var guideStr = str.substring( tagPos, tagPos+tagLength );
      guides.count = str.charCodeAt( tagPos + 27 );
    
      var pointer = tagPos + 28;
      for( var i =0; i < guides.count; i++ ){
       //  var n = ((str[pointer] << 3) + (str[pointer+1] << 2) + (str[pointer+2] << 1) + str[pointer+3])/32;
      //var n = Number( '0x'+getHexString( str, pointer )+getHexString( str, pointer+1 )+getHexString( str, pointer+2 )+getHexString( str, pointer+3 ))/32;
             var n = ((str.charCodeAt(pointer)<< 32) + (str.charCodeAt(pointer + 1)<< 16) +
                    (str.charCodeAt(pointer + 2) << 8) + str.charCodeAt(pointer+3))/32;

if  (str.charCodeAt( pointer + 4 ) == 0) {
          //vertical
          vertGuides = insertValueInOrder(vertGuides, n);
       } else {
          //horizontal
          horGuides = insertValueInOrder(horGuides, n);
       }   
      
        // guides[ i ] =  [ (str.charCodeAt( pointer + 4 ) ? 'horz':'vert'), n ];     
         pointer = pointer + 5;
      }
 
     guides.HorizontalCount =horGuides.length;
     guides.VerticalCount =vertGuides.length;
     guides.Horizontal = horGuides;
     guides.Vertical = vertGuides;
   }else{
      guides.TotalCount = 0;
     guides.HorizontalCount =0;
     guides.VerticalCount =0;
   }

   function insertValueInOrder(a , n) {
      var b = new Array;
      var i = 0;

      if (a[0] == undefined)
         b[0] = n;
      else {
         while (a < n && i < a.length) {
               b = a;
               i++;
         }
               
         b = n;
            
         while (i < a.length) {
            b[i+1] = a;      
            i++;
         }
      }   
      return b;
   }

   return guides;
}
  function fromCharCode(input) {
      output = eval("String.fromCharCode(" + input + ")");
     return output;
   }

var masterDocument = app.activeDocument;
var guideInfo = getGuideInfo( masterDocument );
var s = "Vertical Guides: " + guideInfo.Vertical + "\nHorizontal Guides: " + guideInfo.Horizontal;
         
alert(s);
myranalis

Guide positions

Post by myranalis »

Thanks again Mike. Like you said - it works on all the problem documents I've found so far Got it out with some other testers at the moment, hopefully they won't break it

Cheers

Anna