Batch Import/Resize/Placement

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

Tim.Belt

Batch Import/Resize/Placement

Post by Tim.Belt »

Hello, I am new to Photoshop Scripting and I am trying to create a script that will allow me to batch import/re-size/and place pictures in a grid by file name for a school yearbook to save time!

I am stuck at the point of resizing all of the pictures.

I used the original "load files in to stack" as a base script to go off of, and i also used someone else's scaling script, but i can't seem to get all of the files to resize. Only the first one works. If someone could give me some insight here it would be gladly appreciated! Thank you in advance!

Code: Select allfunction main() {
   // get selected layers
   var doc = activeDocument;
   var selectedLayers = getSelectedLayersIndex(doc);
   var layer = doc.activeLayer;
   selectAllLayers();

{ resizeLayer(286 , 626,true);
   

function resizeLayer(Width , Height, Constrain){//pixels

   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;
      }
   }
}

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

Mike Hale

Batch Import/Resize/Placement

Post by Mike Hale »

activeDocument.activeLayer only returns the top most selected layer or if no layers are selected the top most layer in the layer panel so that is why your code only resizes one layer.

To resize multiple layers you need to loop through the layers you want to resize and call the resizeLayer function in the loop.

I see that you have a variables for selecedLayers and the current activeLayer. You then select all layers. Do you want to resize all layers or just the selected ones?
Tim.Belt

Batch Import/Resize/Placement

Post by Tim.Belt »

I want it to resize All layers that are not locked. And thank you for replying, i didn't expect much of a response but i do need help and can't find many resources on this sort of thing.

Sorry for not mentioning i wanted it to resize layers not locked, I wasn't thinking about that specifically until now and i was just going to try and get that working after i got all the layers to scale.


To resize multiple layers you need to loop through the layers you want to resize and call the resizeLayer function in the loop.
How would i go about this? I'm new to photoshop/javascript.
Mike Hale

Batch Import/Resize/Placement

Post by Mike Hale »

Can you post all the code you have now for what you are trying to do. The snippet you posted calls functions that that were not in that snippet.

Even with a script, you can't resize a locked layer without first unlocking so working only with unlocked layers will not be a problem. I am not sure why you are getting the selected layers if you want to resize all the layers. Was that just part of some code you found and let in? Or can you explain step by step what you want the script to do?
Tim.Belt

Batch Import/Resize/Placement

Post by Tim.Belt »

Okay, So as i have mentioned before, i am mostly new to using photoshop script. I want to make a script for a school yearbook to let me
1) batch load pictures in to photoshop in one document. (imported and arranged by file name)
2) Resize all layers to a certain dimension
3) Position all layers in a grid or by position on the page for the "People" section of the yearbook

This is so other people and I don't have to manually do all of that for each individual person.

Here is my code, i used the "load files in to stack" script that came with photoshop as a base from where i started adding too.
Yes i know my code is a mess, but i don't have that much experience programming in the first place (but i want to have more) so I'm sorry if the code is messy.

Code: Select all$.level = 0;

// debugger; // launch debugger on next line

// on localized builds we pull the $$$/Strings from a .dat file
$.localize = true;

// Put header files in a "Stack Scripts Only" folder.  The "...Only" tells
// PS not to place it in the menu.  For that reason, we do -not- localize that
// portion of the folder name.
var g_StackScriptFolderPath = app.path + "/"+ localize("$$$/ScriptingSupport/InstalledScripts=Presets/Scripts") + "/"
                              + localize("$$$/Private/LoadStack/StackScriptOnly=Stack Scripts Only/");

$.evalFile(g_StackScriptFolderPath + "LatteUI.jsx");

$.evalFile(g_StackScriptFolderPath + "StackSupport.jsx");

$.evalFile(g_StackScriptFolderPath + "CreateImageStack.jsx");

/************************************************************/
// loadLayers routines

loadLayers = new ImageStackCreator( localize("$$$/AdobePlugin/Shared/LoadStack/Process/Name=Load Layers"),
                                localize('$$$/AdobePlugin/Shared/LoadStack/Auto/untitled=Untitled' ) );

// LoadLayers is less restrictive than MergeToHDR
loadLayers.mustBeSameSize         = true;   // Images' height & width don't need to match
loadLayers.mustBeUnmodifiedRaw      = false;   // Exposure adjustements in Camera raw are allowed
loadLayers.mustNotBe32Bit         = false;   // 32 bit images
loadLayers.createSmartObject      = false;   // If true, option to create smart object is checked.

// Add hooks to read the value of the "Create Smart Object" checkbox
loadLayers.customDialogSetup = function( w )
{
   w.findControl('_createSO').value = loadLayers.createSmartObject;
   if (! app.featureEnabled( localize( "$$$/private/ExtendedImageStackCreation=ImageStack Creation" ) ))
      w.findControl('_createSO').hide();
}

loadLayers.customDialogFunction = function( w )
{
   loadLayers.createSmartObject = w.findControl('_createSO').value;
}

// Override the default to use "Auto" alignment.
loadLayers.alignStack = function( stackDoc )
{
   selectAllLayers(stackDoc, 2);
   alignLayersByContent( "Auto" );
}

loadLayers.stackLayers = function()
{
   var result, i, stackDoc = null;
   
   stackDoc = this.loadStackLayers();
   if (! stackDoc)
      return;
   
   // Nuke the "destination" layer that got created (M2HDR holdover)
   stackDoc.layers[this.pluginName].remove();
   
   // Stack 'em up.
   if (this.createSmartObject)
   {
      selectAllLayers( stackDoc );
      executeAction( knewPlacedLayerStr, new ActionDescriptor(), DialogModes.NO );
   }
}

// "Main" execution of Merge to HDR
loadLayers.doInteractiveLoad = function ()
{
   this.getFilesFromBridgeOrDialog( localize("$$$/Private/LoadStack/LoadLayersexv=LoadLayers.exv") );

   if (this.stackElements)
      this.stackLayers();
}

loadLayers.intoStack = function(filelist, alignFlag)
{
   if (typeof(alignFlag) == 'boolean')
      loadLayers.useAlignment = alignFlag;
      
   if (filelist.length < 2)
   {
      alert(localize("$$$/AdobeScripts/Shared/LoadLayers/AtLeast2=At least two files must be selected to create a stack."), this.pluginName, true );
      return;
   }
   var j;
   this.stackElements = new Array();
   for (j in filelist)
   {
      var f = filelist[j];
      this.stackElements.push( new StackElement( (typeof(f) == 'string') ? File(f) : f ) );

   if (this.stackElements.length > 1)
      this.mergeStackElements();
}
{
if (typeof(loadLayersFromScript) == 'undefined')
   loadLayers.doInteractiveLoad();   
}


function main() {
   // get selected layers
   var doc = activeDocument;
   var selectedLayers = getSelectedLayersIndex(doc);
   var layer = doc.activeLayer;
   selectAllLayers();

{ resizeLayer(286 , 626,true);
   

function resizeLayer(Width , Height, Constrain){//pixels

   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;
      }
}
}
}
Mike Hale

Batch Import/Resize/Placement

Post by Mike Hale »

It's fine that you are new to scripting, we have this forum so people can get help.

From what you outlined I would script this task in InDesign. I think InDesign would be better suited for making pages in a yearbook.

Having said that here is one way to start this with Photoshop.

Code: Select allvar loadLayersFromScript = true;// must be defined before including Load Files into Stacks.jsx
var StacksScriptPath = app.path + "/" + localize("$$$/ScriptingSupport/InstalledScripts=Presets/Scripts/")+"/Load Files into Stack.jsx";
$.evalFile( StacksScriptPath );

// create new stacked document
var selectedFolder = Folder.selectDialog( "Please select folder to stack");
if(selectedFolder != null ){// make sure user selected a folder and didn't cancel the dialog
   var files = selectedFolder.getFiles(/.jpg$/i);// get only the jpg files in the selected folder,
   if( files.length > 1 ){// make sure that there is at least two files to process
       loadLayers.intoStack( files );// load the found files into a stack
        var stackDoc = app.activeDocument;
        // resizing document will resize all the layers
        stackDoc.resizeImage (new UnitValue(286,'px'), undefined, undefined, ResampleMethod.BICUBIC);
        // resize canvas to new page size
        // arrange layer on page
    }
}

That will get you a new document with all the jpeg files in a folder stacked as layer and the right size. I didn't code the positioning of the layer into a grid because you didn't say what size canvas you wanted or detailed the grid. Even with that info I am not sure about the best way to deal with overflow images that don't fit the layout( pagination )
Tim.Belt

Batch Import/Resize/Placement

Post by Tim.Belt »

Okay so i used that code and it seemed like it was going to work well, until i actually tried importing the folder.

It gives me this error

Error 24:this.mergeStackElements is not a function.
Line: 124
-> this.mergeStackElements();

I don't understand why it would say that because it is using the default script from photoshop, right?

I may have forgotten to mention i'm running photoshop CS3 for this. I'm sorry, i'm just completely lost.
Mike Hale

Batch Import/Resize/Placement

Post by Mike Hale »

I am not sure why you are getting that error either. I assume that Load Files into Stack works if you run it by itself in Photoshop( I don't have CS3 installed to test ).

I can't find the function 'mergeStackElements' in the CS5 version of the script( or support scripts ) and the script I posted works fine for me in CS5. The only thing I can think of is Adobe must have changed the scripts between CS3 and CS5.
Tim.Belt

Batch Import/Resize/Placement

Post by Tim.Belt »

It doesn't really make any sense to me either because the script itself runs fine, but when i use the one above i get that error.
Mike Hale

Batch Import/Resize/Placement

Post by Mike Hale »

I think I have found the problem. I went over to someone's house who still uses CS3.

It looks like Adobe never tested calling Load Files into Stack from another script. The function loadLayers.intoStack calls another function that does not exists. The loadLayers.doInteractiveLoad function which is called when running Load Files into Stack from the menu calls a different function ( loadLayers.stackLayers ). I guess Adobe changed the script or renamed that function and forgot to update both functions that use it.

If you are willing to edit the Load Files into Stack script the script I posted will work on CS3. Note - I think editing is the only way you will be able to call Load Files into Stack from another script even if you don't want to use my example.

To edit the script open it in either ExtendScript Toolkit( which ships with CS3 ) or a plain text editor. Replace the last two line of the loadLayers.intoStack function with these two lines.
Code: Select all   if (this.stackElements.length > 1)
      this.stackLayers();

With that edit loadLayers.intoStack will call the same function as loadLayers.doInteractiveLoad.