Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
0

create layered image stack from files and align

Explorer ,
Jul 25, 2018 Jul 25, 2018

Hi everyone,

i'm pretty new to scripting so i would really love to have some suggestions. i'm trying to code a script that does the following steps:

1.open the selected files (not from folder) in a layered photoshop stack

2. align them

3. read the shortest layer name and saves to a variable (let's call it "product")

4. create some layerset

5. saves the file to the parent directory of the source with the "product" name

6. close the file

i searched on the forum for a solution for long time but my scripting skills are too basic.

i'm not sure if it's better to do this form bridge or directly from ps.

at the moment i'm trying both the ways but don't figure out how to solve.

for the bridge script i've found some hint from this forum but this doesn't open the layered stack...

#target bridge      

/*if( BridgeTalk.appName == "bridge" ) {     

stacksToLayers = new MenuElement("command", "Stacks To Layers",  "at the end of Tools");   

}   

stacksToLayers.onSelect = function () { */

var stacks =  app.document.selections;

var stackCount = stacks.length;

for(var s = 0;s<stackCount;s++){

     var stackFiles = getStackFiles( stacks );

     if(stackFiles.length> 1){

          var bt = new BridgeTalk;

          bt.target = "photoshop";

          var myScript = ("var ftn = " + psRemote.toSource() + "; ftn("+stackFiles.toSource()+");");

          bt.body = myScript; 

          bt.onResult = function( inBT ) {myReturnValue(inBT.body); }

          bt.send(500);

     }

}

function getStackFiles( stack ){

     var files = new Array();

     for( var f = 0; f<stackCount;f++){

          files.push(stacks.spec);

          }

     return files;

};

function myReturnValue(str){

     res = str;

}

// don't have comments in the psRemote function

function psRemote(stackFiles){

     var loadLayersFromScript = true;

     var strPresets = localize ("$$$/ApplicationPresetsFolder/Presets=Presets");

     var strScripts = localize ("$$$/PSBI/Automate/ImageProcessor/Photoshop/Scripts=Scripts");

     var strFile2Stack = "Load Files into Stack.jsx";

     var ipFilePath = app.path + "/" + strPresets + "/" + strScripts + "/" + strFile2Stack;

     var ipFile = new File (ipFilePath);

     $.evalFile( ipFile );

     loadLayers.intoStack(stackFiles);

     var saveFile = new File('~/desktop/'+app.activeDocument.name+'.psd');

     app.activeDocument.saveAs(saveFile);

}

//}//  app.activeDocument.close(SaveOptions.DONOTSA

VECHANGES);

from debugging it stops on bt.send(500); line repeating this command....

$.level = 0; app.synchronousMode = false;

on the ps script part i have similar issue, the layered files doesn't open... here the code

var fileList= File.openDialog("seleziona i files",undefined,true);

    for (i = 0; i <= fileList.length-1; i++) { 

        alert(fileList.path + "/" +fileList.name);

        // or open or do somethig else 

        }

if ( fileList != null ){

runLoadStack();

}

function runLoadStack( fileList ){

    var loadLayersFromScript = true;// must be set before the include

    // @include '/C/Program Files/Adobe/Adobe Photoshop CC 2017/Presets/Scripts/Load Files into Stack.jsx'

    var aFlag = true;

    loadLayers.intoStack( fileList, aFlag );

}

the other parts of the script i should be able to manage...

anyone could help me?

thank you a lot and a great hug form Italy

Alessio

TOPICS
Scripting
3.6K
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Jul 26, 2018 Jul 26, 2018

sorry i wrote too fast

it also saves the psd in the same folder with 2 layers inside a layerset

GREATTTTT

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Jul 26, 2018 Jul 26, 2018

I tried the older version of the script with other stacks and everything is working correctly... actually the problem was with the pictures i used to test it.. never thought about this

i think you are a great programmer, for real!

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jul 26, 2018 Jul 26, 2018

What's wrong with pictures you used for test, why they don't have resolution? What is difference between them and regular ones? Can you also check my last post - I updated it. Regarding being great programmer - I think SuperMerlin is greater

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Jul 26, 2018 Jul 26, 2018

is there a way to save the file in tif format to the parent directory?

i've tryed

aD.saveAs(File(decodeURI(v[0]).slice(0, -3).parent + '.tif'))

but is not working..

anyway thanks a lot for your time and experience. Hope to see the results of all this efforts!

Don't know supermerlin, but of course you know what you're doing

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jul 26, 2018 Jul 26, 2018

I think it can be changed to .tif on the condition you will use tif options which you store to tif variable and then use this:

aD.saveAs(File(decodeURI(v[0]).slice(0, -3) + 'tif'), tif)

You can actually set default resolution to 300 in this Bridge part of script:

w = m().width, h = m().height, x = m().xResolution || 300

As I said in post with original script that's not done yet. Now after you tested it and suggested some changes, I'll write them.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Jul 30, 2018 Jul 30, 2018

Hi,

hope this finds you well!!

do you think you are going to work on this in the next days? if not i wil try to make the changes, let's see what happens

anyway thank you again for your efforts

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jul 30, 2018 Jul 30, 2018

I'm sorry for delay. I had to focus on other huge project I started actually before your script. But it's almost finished, so I will try today evening to finish also this one for you. If not today then probably tomorrow. Thx for patience, and of course that's something interesting to me to get it done

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Jul 30, 2018 Jul 30, 2018

Hi Kukurykus,

i want to share with you the result of my hard coding day

this is where i am at the moment:

the structure of the folders and layers is working good

the script saves the file in the parent parent folder of the stack

it saves a tiff with lzw compression and name it with the right filename

i know i'm a donk in coding, but i'm pretty happy about how it is working

#target bridge 

/*if( BridgeTalk.appName == "bridge" ) {   

batchone = new MenuElement("command", "batchone",  "at the end of Tools"); 

batchone.onSelect = function () {  */

if (sLen = (stck = (ad = app.document).stacks).length) { 

     ad.chooseMenuItem('CollapseAllStacks') 

     for(arr = Array(sLen), i = 0; i < sLen; i++) { 

          arr = [], tLen = (img = stck.thumbnails).length 

          for(j = tLen - 1; j >= 0; j--) arr = img.spec 

          m = function() {return img[0].core.quickMetadata} 

          w = m().width, h = m().height, x = m().xResolution 

          r = !((Math.abs(new Thumbnail(arr[0]).rotation / 90) + 2) % 3) 

          if (r) h = ([w = h, m().width])[1]; arr[tLen] = {w: w, h: h, x: x || 300} 

     } 

 

function Ps(v) { 

    displayDialogs = DialogModes.NO 

     function openingAlligningSaving(v) { 

          (dsc1 = new ActionDescriptor()).putPath(sTT('null'), v) 

          dsc1.putEnumerated(sTT('freeTransformCenterState'), sTT('quadCenterState'), sTT('QCSAverage')); 

          (dsc2 = new ActionDescriptor()).putUnitDouble(sTT('horizontal'), sTT('pixelsUnit'), 0) 

          dsc2.putUnitDouble(sTT('vertical'), sTT('pixelsUnit'), 0) 

          dsc1.putObject(sTT('offset'), sTT('offset'), dsc2) 

          executeAction(sTT('placeEvent'), dsc1) 

     } 

 

     function sTT(v) {return stringIDToTypeID(v)} 

 

     (ref1 = new ActionReference()).putProperty(sTT('property'), sTT('generalPreferences')) 

     ref1.putEnumerated(sTT('application'), sTT('ordinal'), sTT('targetEnum')); 

     (dsc1 = new ActionDescriptor()).putReference(sTT('null'), ref1); 

     (dsc2 = new ActionDescriptor()).putBoolean(sTT('placeRasterSmartObject'), false) 

     dsc1.putObject(sTT('to'), sTT('generalPreferences'), dsc2) 

     executeAction(sTT('set'), dsc1) 

 

     prf = preferences.rulerUnits, preferences.rulerUnits = Units.PIXELS;

 

for(i = 0; i < v.length; i++) {  

     

          documents.add((whx = v[v.length - 1]).w, whx.h, whx.x) 

          for(j = 0; j < v.length - 1; j++) openingAlligningSaving(v);  

         // var srcDoc = app.activeDocument;

         //  var nome = srcDoc.layers[0].name;

         //  alert(nome)

       

          (aD = activeDocument).selection.selectAll(); 

         

           

 

          (ref1= new ActionReference()).putEnumerated 

          (sTT('layer'), sTT('ordinal'), sTT('targetEnum')); 

          (dsc1 = new ActionDescriptor()).putReference(sTT('null'), ref1) 

          executeAction(sTT('selectAllLayers'), dsc1); 

 

          /* TEMPORARY */(function algn(v1, v2) { 

          dsc1.putEnumerated(sTT('using'), sTT('alignDistributeSelector'), 

          sTT(v1)), executeAction(sTT('align'), dsc1); if (v2) algn('ADSLefts') 

          })('ADSTops', true);/* TEMPORARY */ 

     

 

          (ref2 = new ActionReference()).putClass(sTT('layerSection')); 

          (dsc1 = new ActionDescriptor()).putReference(sTT('null'), ref2); 

          dsc1.putReference(sTT('from'), ref1), executeAction(sTT('make'), dsc1) 

 

          dsc1.putReference(sTT('null'), ref1); 

          (dsc2 = new ActionDescriptor()).putString(sTT('name'), 'Montaggio') 

          dsc1.putObject(sTT('to'), sTT('layer'), dsc2) 

          executeAction(sTT('set'), dsc1, DialogModes.NO) 

         

   var srcDoc = app.activeDocument;

   var newGroup = srcDoc.layerSets.add(); 

        newGroup.name = "Scontorno";

    var newTemp = srcDoc.layerSets["Scontorno"].artLayers.add();

        newTemp.name = "temp";

    srcDoc.layerSets["Montaggio"].move(srcDoc.layerSets["Scontorno"].layers["temp"], ElementPlacement.PLACEBEFORE);

    srcDoc.layerSets["Scontorno"].layers["temp"].remove();

         aD.selection.deselect(), aD.backgroundLayer.remove() 

     var nomeDir = String(v[0]);

  //   alert(nomeDir);

var cal = nomeDir.lastIndexOf("/");

var nomeFile = String(nomeDir).slice(cal+1);

         var lung = String(File(decodeURI(v[0].parent.parent)));

         alert(lung)

        var newNamePath = lung + '/' + nomeFile.slice(0,-3) + 'tif';

       

        tiffSaveOptions = new TiffSaveOptions();  

tiffSaveOptions.embedColorProfile = true;  

tiffSaveOptions.alphaChannels = true;  

tiffSaveOptions.layers = true; 

tiffSaveOptions.imageCompression = TIFFEncoding.TIFFLZW; 

         aD.saveAs(File(newNamePath), tiffSaveOptions, true,Extension.LOWERCASE);

        aD.close(SaveOptions.DONOTSAVECHANGES) 

 

          /*

          (ref = new ActionReference()).putEnumerated

          (sTT('layer'), sTT('ordinal'), sTT('targetEnum'));

          (dsc = new ActionDescriptor()).putReference(sTT('null'), ref )

          dsc.putEnumerated( sTT('using'), sTT('alignDistributeSelector'), sTT('ADSContent'))

          dsc.putEnumerated( sTT('apply'), sTT('projection'), sTT('perspective')), executeAction(sTT('align'), dsc)

          */ 

     } 

     preferences.rulerUnits = Units.PIXELS = prf 

 

//alert(sLen = (stck = (ad = app.document).stacks).length);

arr = arr.toSource(), 

(bT = new BridgeTalk()).target = 'photoshop' 

bT.body = Ps.toString() + '\nPs(' + arr + ')', bT.send()

//};

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Aug 03, 2018 Aug 03, 2018
LATEST

Yestarday I had no time while today I woke up late, but now I have time to focus on it what I'm going to do for next hours

For now I had time to focus on the hardest for me thing, so Br part. Now you can decide which Stacks you want to process:

sel = (ad = app.document).selectionLength

if (arr = [], sel && sLen = (stck = ad.stacks).length) {

     ad.chooseMenuItem('CollapseAllStacks'), str = ''

     for(i = 0; i < sel; i++) str += ad.selections.name + '|'

     function iO(v) {return str.indexOf(v)}; for(i = 0; i < sLen; i++) {

          if (iO((itm = (s = stck).thumbnails[0].name + '|')) + 1) {

               str = str.replace(itm, ''), image = stck.thumbnails

               arr[l = arr.length] = new Array, tLen = image.length

               for(j = tLen - 1; j >= 0; j--) arr = image.spec

               m = function() {return image[0].core.quickMetadata}

               w = m().width, h = m().height, x = m().xResolution || 300

               r = !((Math.abs(new Thumbnail(arr[0]).rotation / 90) + 2) % 3)

               if (r) h = ([w = h, m().width])[1]; arr[tLen] = {w: w, h: h, x: x}

               if (arr.length == sel) break;

          }

     }

}

Also change last 2 lines to:

arr = arr.toSource(), (bT = new BridgeTalk()).target = 'photoshop'

if (arr.length) bT.body = Ps.toString() + '\nPs(' + arr + ')', bT.send()

It still does not work with nasted folders (so Smart Objects in Smart Objects if that was Ps). I will do it after all other parts...

ah btw I noticed you marked as correct solution wrong one in this topic: apply layer mask  / that was mine, not yours

Here are another improvements. Now you can keep original resolution of each layer in created document as well as keep original dimension of all stacked layers so if they were bigger/smaller or had other orientation it will be taken into account. It also is storing layer names to choose the shortest and save new .psd with its name. So it is doing now almost everything. EDIT: there was a bug. It opened all next stack with dimension of first stuck. Now it works correctly. I also added files will be saved as tif's. I changed also order of layers beeing placed in a file. Previously there was wrong order, not the same as Stacks got. Last thing is you can run it now clicking right mouse button on selected thumbnail(s) to choose last item called 'Stacks':

#target bridge

Stacks = new MenuElement('command', 'Stacks', 'at the end of Thumbnail')

Stacks.onSelect = function() {

     sel = (ad = app.document).selectionLength

     if (arr = [], sel && sLen = (stck = ad.stacks).length) {

          ad.chooseMenuItem('CollapseAllStacks'), str = ''

          for(i = 0; i < sel; i++) str += ad.selections.name + '|'

          function iO(v) {return str.indexOf(v)}; for(i = 0; i < sLen; i++) {

               if (iO((itm = (s = stck).thumbnails[0].name + '|')) + 1) {

                    str = str.replace(itm, ''), image = stck.thumbnails

                    arr[l = arr.length] = new Array // array of all stacks

                    m = function() {return image.core.quickMetadata}

                    for(tLen = image.length, j = 0; j < tLen; j++) {

                         arr = Array(2), arr[0] = image.spec

                         w = m().width, h = m().height, x = m().xResolution || 300

                         r = !((Math.abs(new Thumbnail(arr[0]).rotation / 90) + 2) % 3)

                         if (r) h = ([w = h, m().width])[1]; arr[1] = {w: w, h: h, x: x}

                    }

                    if (arr.length == sel) break;

               }

          }

     }

     function Ps(v) {

          function placing(v1, v2) {

               (dsc1 = new ActionDescriptor()).putPath(sTT('null'), v1)

               dsc1.putEnumerated(sTT('freeTransformCenterState'),

               sTT('quadCenterState'), sTT('QCSAverage'))

               dsc2 = new ActionDescriptor();

               (function loop(v) {

                    (arr = v ? ['width', 'height'] :

                    ['horizontal', 'vertical'])

                    for(I = 0; I < arr.length;) {

                         (v ? dsc1 : dsc2).putUnitDouble(sTT(arr[I++]),

                         sTT((v ? 'percent' : 'pixels') + 'Unit'), v || 0)

                    }

                    if (!v) loop(v2)

               })()

               dsc1.putObject(sTT('offset'), sTT('offset'), dsc2)

               executeAction(sTT('placeEvent'), dsc1)

          }

          displayDialogs = DialogModes.NO; function sTT(v) {return stringIDToTypeID(v)}

          (ref = new ActionReference()).putProperty(sTT('property'),

          gP = sTT('generalPreferences')), ref.putClass(sTT('application'))

          dsc = executeActionGet(ref).getObjectValue(sTT('generalPreferences'))

          .getBoolean(pRSO = sTT('placeRasterSmartObject'))

          function plc(v) {

               (dsc1 = new ActionDescriptor()).putReference(sTT('null'), ref);

               (dsc2 = new ActionDescriptor()).putBoolean(pRSO, v)

               dsc1.putObject(sTT('to'), gP, dsc2), executeAction(sTT('set'), dsc1)

          }

          if (dsc) plc(!dsc); prf = preferences.rulerUnits, preferences.rulerUnits = Units.PIXELS

          for(i = 0; i < v.length; i++) {whx = v[0][1]

               documents.add(whx.w, whx.h, whx.x), nme = ''

               for(aD = activeDocument, j = v.length - 1; j >= 0; j--) {

                    whx = v[1]; if (j) {

                         w = aD.width, h = aD.height, nW = w - whx.w, nH = h - whx.h

                         function con(v1, v2) {return (v1 + (v2 < 0 && Math.abs(v2)) || 0)}

                         aD.resizeCanvas(con(w, nW), con(h, nH), AnchorPosition.TOPLEFT)

                    }

                    placing(v[0],  whx.x / aD.resolution * 100)

                    if (nn = aD.activeLayer.name, !nme) nme = nn

                    else if(nn.length < nme.length) nme = nn

               }

               aD.selection.selectAll();

               (ref1= new ActionReference()).putEnumerated

               (sTT('layer'), sTT('ordinal'), sTT('targetEnum'));

               (dsc1 = new ActionDescriptor()).putReference(sTT('null'), ref1)

               executeAction(sTT('selectAllLayers'), dsc1);

               (function algn(v1, v2) {

                    dsc1.putEnumerated(sTT('using'), sTT('alignDistributeSelector'),

                    sTT(v1)), executeAction(sTT('align'), dsc1); if (v2) algn('ADSLefts')

               })('ADSTops', true);

               (ref2 = new ActionReference()).putClass(sTT('layerSection'));

               (dsc1 = new ActionDescriptor()).putReference(sTT('null'), ref2)

               dsc1.putReference(sTT('from'), ref1), executeAction(sTT('make'), dsc1)

               dsc1.putReference(sTT('null'), ref1), lS = 'Scontorno';

               (dsc2 = new ActionDescriptor()).putString(sTT('name'), lS)

               dsc1.putObject(sTT('to'), sTT('layer'), dsc2)

               executeAction(sTT('set'), dsc1)

               tif = new TiffSaveOptions,  tif.alphaChannels

               = tif.layers = tif.embedColorProfile = true

               tif.imageCompression = TIFFEncoding.TIFFLZW

               aD.selection.deselect(), aD.backgroundLayer.remove()

               aD.saveAs(File(v[0][0].path + '/' + nme), tif)

               aD.close(SaveOptions.DONOTSAVECHANGES)

          }

          preferences.rulerUnits = Units.PIXELS = prf; if (dsc) plc(dsc)

     }

     arr = arr.toSource(), (bT = new BridgeTalk()).target = 'photoshop'

     if (arr.length) bT.body = Ps.toString() + '\nPs(' + arr + ')', bT.send()

}

The last thing I have to do is to make a loop over Br Stacks so they can be opened in Ps in subfolder imitating deeper stacks.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines