Resize layer to fit guide lines

Anyone, especially newbies, asking for help with Photoshop Scripting and Photoshop Automation - as opposed to those contributing to discussion about an aspect of Photoshop Scripting

Moderators: Tom, Kukurykus

Byteripper

Resize layer to fit guide lines

Post by Byteripper »

Hello guys, this is my first day on this site and I am so glad that I found a forum about photoshop scripts:D
This is what I'm looking for:
I need a script to resize layers ( enlarge or contract), keep aspect ratio and fit to guidelines (left, right and below). I work with footwear products and my job is to arrange them on a 3000x3000 white background that has 3 guidelines( left, right and bottom). Please help if you can.

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

Paul MR

Resize layer to fit guide lines

Post by Paul MR »

This will work for Photoshop CS5 ONLY!

Select your layer and run the code.

Code: Select allmain();
function main(){
function numSortAccending(a, b){ return (a-b); }
var startRulerUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;
var guides = app.activeDocument.guides;
var gH = [];
var gV = [];
for( var g = 0; g < guides.length; g++ ){
    if(guides[g].direction.toString() == 'Direction.HORIZONTAL'){
        gH.push(parseInt(guides[g].coordinate.value));
        }else{
            gV.push(parseInt(guides[g].coordinate.value));
            }
}
gH.sort(numSortAccending);
if(gH.length != 1) return;
gV.sort(numSortAccending);
if(gV.length != 2) return;
var NewWidth = Number(gV[1])-Number(gV[0]);
resizeLayer(NewWidth , undefined, true);
var LB = activeDocument.activeLayer.bounds;
activeDocument.activeLayer.translate(Number(gV[0])-LB[0].value,Number(gH[0])-LB[3].value);
app.preferences.rulerUnits = startRulerUnits;
}

function resizeLayer(Width , Height, Constrain){
if(!documents.length) return;
if(activeDocument.activeLayer.isBackgroundLayer) return;
var startRulerUnits = preferences.rulerUnits;
preferences.rulerUnits = Units.PIXELS;
var LB = activeDocument.activeLayer.bounds;
var lWidth = 100/(LB[2].value - LB[0].value);
var lHeight =100/(LB[3].value - LB[1].value);
var NewWidth = lWidth * Width;
var NewHeight = lHeight * Height;
if(Constrain) NewHeight = NewWidth;
activeDocument.activeLayer.resize(Number(NewWidth),Number(NewHeight),AnchorPosition.MIDDLECENTER);
app.preferences.rulerUnits = startRulerUnits;
}

Byteripper

Resize layer to fit guide lines

Post by Byteripper »

Thank you very much, I appreciate your help. One little question... how can I modify this script to work on CS4, if that is possible?
Paul MR

Resize layer to fit guide lines

Post by Paul MR »

There isn't a good way to get this working on earlier versions of Photoshop as access to guides only started in CS5.
Mike has some code here to access guides:-
bb/viewtopic.php?f=13&t=2818

but I haven't got it to work with reliable results (for me it gives the wrong guide locations).
Paul MR

Resize layer to fit guide lines

Post by Paul MR »

This is not reliable, but has worked on smaller documents?
You could see if it works for you.

Code: Select all/* 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: count property  = number of guides
//                              X property = array of type and pixel pos
//                                                     where X = guide number
///////////////////////////////////////////////////////////////////////////////

function getGuideInfo( doc ) {
   saveOptions = new JPEGSaveOptions();
   saveOptions.quality = 0;// we don't care about image quality in the temp file
   var tempFile = new File( Folder.temp + '/' +'guideTemp.jpg' );
   doc.saveAs( tempFile, saveOptions, true );
   var guideTag = '8BIM' + fromCharCode( 4 ) + fromCharCode( 8 );
   tempFile.encoding = 'BINARY';
   tempFile.open('r');
   var str = tempFile.read();
   tempFile.close();
   tempFile.remove();
   var tagPos = str.search(guideTag);
   var guides = new Object;
   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 = 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;
         guides[ i + 1 ] =  [ (str.charCodeAt( pointer + 4 ) ? 'horz':'vert'), n ];     
         pointer = pointer + 5;
      }
   }else{
      guides.count = 0;
   }
   function fromCharCode(input) {
      output = eval("String.fromCharCode(" + input + ")");
   return output;
   }
   return guides;
}

//////////////////////
function main(){
var startRulerUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;
g = getGuideInfo( activeDocument );

var gH = [];
var gV = [];

for( var p = 1 ; p < g.count+1;p++){
    if(g[p][0].toString() == 'horz'){
        gH.push(parseInt(g[p][1]));
        }else{
            gV.push(parseInt(g[p][1]));
            }
}
gH.sort(numSortAccending);
if(gH.length != 1) return;
gV.sort(numSortAccending);
if(gV.length != 2) return;
var NewWidth = Number(gV[1])-Number(gV[0]);
resizeLayer(NewWidth , undefined, true);
var LB = activeDocument.activeLayer.bounds;
activeDocument.activeLayer.translate(Number(gV[0])-LB[0].value,Number(gH[0])-LB[3].value);
app.preferences.rulerUnits = startRulerUnits;
}
function numSortAccending(a, b){ return (a-b); }
function resizeLayer(Width , Height, Constrain){
if(!documents.length) return;
if(activeDocument.activeLayer.isBackgroundLayer) return;
var startRulerUnits = preferences.rulerUnits;
preferences.rulerUnits = Units.PIXELS;
var LB = activeDocument.activeLayer.bounds;
var lWidth = 100/(LB[2].value - LB[0].value);
var lHeight =100/(LB[3].value - LB[1].value);
var NewWidth = lWidth * Width;
var NewHeight = lHeight * Height;
if(Constrain) NewHeight = NewWidth;
activeDocument.activeLayer.resize(Number(NewWidth),Number(NewHeight),AnchorPosition.MIDDLECENTER);
app.preferences.rulerUnits = startRulerUnits;
}
main();
Byteripper

Resize layer to fit guide lines

Post by Byteripper »

The first script works perfectly on CS5, today I'll try it on CS4 at work, the last script isn't accurate. I'll post later on this day if it worked on CS4.
I've tried it on CS4 64bit and gaved me this error: ->for (var g=0; g<guides.lenght; g++){.
Have any idea what is the problem?
Byteripper

Resize layer to fit guide lines

Post by Byteripper »

But if I want to fit to 4 guide lines or 2 what part of the script I have to modify?
Paul MR

Resize layer to fit guide lines

Post by Paul MR »

Yes, CS4 didn't support getting guide information so the first script won't work.

If you want to use 4 guides this should work. It could distort the layer though.

Code: Select all#target photoshop
main();
function main(){
function numSortAccending(a, b){ return (a-b); }
var startRulerUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;
var guides = app.activeDocument.guides;
var gH = [];
var gV = [];
for( var g = 0; g < guides.length; g++ ){
    if(guides[g].direction.toString() == 'Direction.HORIZONTAL'){
        gH.push(parseInt(guides[g].coordinate.value));
        }else{
            gV.push(parseInt(guides[g].coordinate.value));
            }
}
gH.sort(numSortAccending);
if(gH.length != 2) return;
gV.sort(numSortAccending);
if(gV.length != 2) return;
var NewWidth = Number(gV[1])-Number(gV[0]);
var NewHeight = Number(gH[1]) - Number(gH[0]);
resizeLayer(NewWidth , NewHeight, false);
var LB = activeDocument.activeLayer.bounds;
activeDocument.activeLayer.translate(Number(gV[0])-LB[0].value,Number(gH[1])-LB[3].value);
app.preferences.rulerUnits = startRulerUnits;
}

function resizeLayer(Width , Height, Constrain){
if(!documents.length) return;
if(activeDocument.activeLayer.isBackgroundLayer) return;
var startRulerUnits = preferences.rulerUnits;
preferences.rulerUnits = Units.PIXELS;
var LB = activeDocument.activeLayer.bounds;
var lWidth = 100/(LB[2].value - LB[0].value);
var lHeight =100/(LB[3].value - LB[1].value);
var NewWidth = lWidth * Width;
var NewHeight = lHeight * Height;
if(Constrain) NewHeight = NewWidth;
activeDocument.activeLayer.resize(Number(NewWidth),Number(NewHeight),AnchorPosition.MIDDLECENTER);
app.preferences.rulerUnits = startRulerUnits;
}



This will use two vertical guides aligned to the bottom of the document.


Code: Select all#target photoshop
main();
function main(){
function numSortAccending(a, b){ return (a-b); }
var startRulerUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;
var guides = app.activeDocument.guides;
var gH = [];
var gV = [];
for( var g = 0; g < guides.length; g++ ){
    if(guides[g].direction.toString() == 'Direction.HORIZONTAL'){
        gH.push(parseInt(guides[g].coordinate.value));
        }else{
            gV.push(parseInt(guides[g].coordinate.value));
            }
}
gH.sort(numSortAccending);
gV.sort(numSortAccending);
if(gV.length != 2) return;
var NewWidth = Number(gV[1])-Number(gV[0]);
resizeLayer(NewWidth , undefined, true);
var LB = activeDocument.activeLayer.bounds;
activeDocument.activeLayer.translate(Number(gV[0])-LB[0].value,activeDocument.height-LB[3].value);
app.preferences.rulerUnits = startRulerUnits;
}

function resizeLayer(Width , Height, Constrain){
if(!documents.length) return;
if(activeDocument.activeLayer.isBackgroundLayer) return;
var startRulerUnits = preferences.rulerUnits;
preferences.rulerUnits = Units.PIXELS;
var LB = activeDocument.activeLayer.bounds;
var lWidth = 100/(LB[2].value - LB[0].value);
var lHeight =100/(LB[3].value - LB[1].value);
var NewWidth = lWidth * Width;
var NewHeight = lHeight * Height;
if(Constrain) NewHeight = NewWidth;
activeDocument.activeLayer.resize(Number(NewWidth),Number(NewHeight),AnchorPosition.MIDDLECENTER);
app.preferences.rulerUnits = startRulerUnits;
}

Byteripper

Resize layer to fit guide lines

Post by Byteripper »

Thank you very much.
S_K

Resize layer to fit guide lines

Post by S_K »

Paul MR wrote:Yes, CS4 didn't support getting guide information so the first script won't work.

If you want to use 4 guides this should work. It could distort the layer though.



Hello Mr. Paul MR,

Thank you very much for this script. I was looking for a script that expands an imported layer to fit an image, but your script does one better by shrinking it to fit too. So thank you.

Regards,
S_K