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

Photoshop script how to select multi layers by size ( CM or inch)

Enthusiast ,
Nov 23, 2021 Nov 23, 2021

Copy link to clipboard

Copied

Hi every body how i need to know how to select all photoshop layers by size or diminsion ( CM or inch ) Please

TOPICS
Actions and scripting , SDK

Views

3.5K

Translate

Translate

Report

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

correct answers 1 Correct answer

Community Expert , Nov 24, 2021 Nov 24, 2021

How familiar are you with JavaScript and Photoshop Scripting? 

Are you capable of adapting a Script that contains the necessary basic operations to your needs? 

 

The below Script should group Layers that have the same bounds dimensions and align them horizontally in the group (see screenshots). 

Screenshot 2021-11-24 at 10.13.02.png

Screenshot 2021-11-24 at 10.13.10.png

 

// group layers of the same bounds dimensions;
// 2021, use it at your own risk;
if (app.documents.length > 0) {
    var theLayers = collectLayersBounds ();
    theLayers.sort(sortArrayByIndexedItem
...

Votes

Translate

Translate
Adobe
Enthusiast ,
Nov 24, 2021 Nov 24, 2021

Copy link to clipboard

Copied

How do I put this in the code?

Votes

Translate

Translate

Report

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
Community Expert ,
Nov 24, 2021 Nov 24, 2021

Copy link to clipboard

Copied


How do I put this in the code?

The line 

groupSelectedLayers (theArray[m][0][3])

is where the Groups get their names. 

 

How familiar are you with JavaScript and Photoshop Scripting? 

Votes

Translate

Translate

Report

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
Enthusiast ,
Nov 24, 2021 Nov 24, 2021

Copy link to clipboard

Copied

Thank you very much c.pfaffenbichler.. you succeeded in solving the problem very much
I'm a Photoshop designer, not a programmer
But I like the programming language and code, the ease of executing commands
But I see that Java and scripts are a difficult language, but I would like to learn it
Is it possible to learn a language and how do I start with it?

Votes

Translate

Translate

Report

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
Community Expert ,
Nov 24, 2021 Nov 24, 2021

Copy link to clipboard

Copied

Just to make sure:

This is JavaScript, not Java. 

 

Resources to learn Scripting for Photoshop are available from Adobe, but they may not make for great reading. 

https://www.adobe.com/content/dam/acom/en/devnet/photoshop/pdfs/photoshop-cc-scripting-guide-2019.pd...

 

It might also be a problematic point of time to dive into it – relevant changes are being made and support for this very old version of JavaScript in Photoshop will be discontinued at some point in the future if I understand correctly. 

@DavideBarranca has written books on Panels for Photoshop, maybe he could recommend one that he feels includes a good intro to the Scripting issue (or just give a quick estimate regarding the imminent changes). 

@J453 wrote a book on Photoshop automation (including Scripting) but I am not sure if that has been updated recently. 

Votes

Translate

Translate

Report

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 ,
Nov 24, 2021 Nov 24, 2021

Copy link to clipboard

Copied

Votes

Translate

Translate

Report

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
Community Expert ,
Nov 24, 2021 Nov 24, 2021

Copy link to clipboard

Copied

Why did you accept that script as a solution for you problem?  It does group same size layers like you want.  It does not distribute the layers optimality over the canvas, You can move the groups over the canvas  if the grouped layers will fit within the canvas width, and if when you distribute the groups layer they fit within the document height.  If all the layer are then over the canvas I would not think the tiling would be optimal.   That is the hard part of your problem. Here I have a document like the one you posted as far as the image layers distribution goes.  I ran the script. The layer were grouped and moved many layers off canvas and many over lapping other.  I then move the  layer groups  on canvas and distributed them so the was no overlapping layers.  I would not call that layout optimal.

Capture.jpg

JJMack

Votes

Translate

Translate

Report

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
Community Expert ,
Nov 24, 2021 Nov 24, 2021

Copy link to clipboard

Copied

One could process the groups further, but getting at a truly efficient usage of canvas space would seem quite difficult to me. 

Screenshot 2021-11-24 at 17.32.22.pngScreenshot 2021-11-24 at 17.32.36.png

// groups wider than canvas could be a problem;
// distribute groups on canvas;
// 2021, use it at your own risk;
if (app.documents.length > 0) {
	var savedRuler = app.preferences.rulerUnits;
	app.preferences.rulerUnits = Units.PIXELS;
	var myDocument = activeDocument;
	var docW = myDocument.width;
	var docH = myDocument.height;
	var theGroups = collectGroupsBounds ();
	theGroups.sort(sortArrayByIndexedItems);
	var theRefX = 0;
	var theRefY = 0;
	var lineH = 0;
	for (var m =0; m < theGroups.length; m++) {
		var theX = theGroups[m][3];
		var theY = theGroups[m][4];
		var theW = theGroups[m][5];
		var theH = theGroups[m][6];
// check if line exceeds doc width;
		if (theRefX + theW >= docW) {
			theRefX = 0;
			theRefY = theRefY + lineH;
			lineH = 0;
		};
		if (theH > lineH) {lineH = theH};
// move group;		
		moveLayer (theGroups[m][2], theRefX-theX, theRefY-theY);
		theRefX = theRefX+theW;
		};
	app.preferences.rulerUnits = savedRuler;
	};
////////////////////////////////////
////// based on code by mike hale and paul riggott //////
function selectLayerByID(index,add){ 
add = undefined ? add = false:add 
var ref = new ActionReference();
    ref.putIdentifier(charIDToTypeID("Lyr "), index);
    var desc = new ActionDescriptor();
    desc.putReference(charIDToTypeID("null"), ref );
       if(add) desc.putEnumerated( stringIDToTypeID( "selectionModifier" ), stringIDToTypeID( "selectionModifierType" ), stringIDToTypeID( "addToSelection" ) ); 
      desc.putBoolean( charIDToTypeID( "MkVs" ), false ); 
   try{
    executeAction(charIDToTypeID("slct"), desc, DialogModes.NO );
}catch(e){
alert(e.message); 
}
};
////// sort a double array, thanks to sam, http://www.rhinocerus.net/forum/lang-javascript/ //////
function sortArrayByIndexedItems(a,b) {
var theIndex1 = 5;
var theIndex2 = 6;
if (a[theIndex1]*a[theIndex2]<b[theIndex1]*b[theIndex2]) return 1;
if (a[theIndex1]*a[theIndex2]>b[theIndex1]*b[theIndex2]) return -1;
return 0;
};
////// move layer //////
function moveLayer (theID, hor, ver) {
	selectLayerByID(theID, false);
		var desc77 = new ActionDescriptor();
		var ref38 = new ActionReference();
		var idlayer = stringIDToTypeID( "layer" );
		ref38.putEnumerated( idlayer, stringIDToTypeID( "ordinal" ), stringIDToTypeID( "targetEnum" ));
	desc77.putReference( stringIDToTypeID( "null" ), ref38 );
	var idto = stringIDToTypeID( "to" );
		var desc78 = new ActionDescriptor();
		var idpixelsUnit = stringIDToTypeID( "pixelsUnit" );
		desc78.putUnitDouble( stringIDToTypeID( "horizontal" ), idpixelsUnit, hor );
		desc78.putUnitDouble( stringIDToTypeID( "vertical" ), idpixelsUnit, ver );
	desc77.putObject( idto, stringIDToTypeID( "offset" ), desc78 );
	executeAction( stringIDToTypeID( "move" ), desc77, DialogModes.NO );
	};
////// collect groups //////
function collectGroupsBounds () {
// the file;
    var myDocument = app.activeDocument;
// get number of layers;
    var ref = new ActionReference();
    ref.putProperty(stringIDToTypeID('property'), stringIDToTypeID('numberOfLayers'));
    ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") ); 
    var applicationDesc = executeActionGet(ref);
    var theNumber = applicationDesc.getInteger(stringIDToTypeID("numberOfLayers"));
// process the layers;
    var theLayers = new Array;
    for (var m = 0; m <= theNumber; m++) {
    try {
    var ref = new ActionReference();
    ref.putIndex( charIDToTypeID( "Lyr " ), m);
    var layerDesc = executeActionGet(ref);
    var layerSet = typeIDToStringID(layerDesc.getEnumerationValue(stringIDToTypeID("layerSection")));
    var isBackground = layerDesc.getBoolean(stringIDToTypeID("background"));
// collect values;
    if (/*layerSet != "layerSectionEnd" &&*/ layerSet == "layerSectionStart" && isBackground != true) {
	var theName = layerDesc.getString(stringIDToTypeID('name'));
    var theID = layerDesc.getInteger(stringIDToTypeID('layerID'));
    var theIndex = layerDesc.getInteger(stringIDToTypeID('itemIndex'));
    var theColor = typeIDToStringID(layerDesc.getEnumerationValue(stringIDToTypeID("color")));
// boundsNoEffects works better on groups;
    var theBounds = layerDesc.getObjectValue(stringIDToTypeID("boundsNoEffects"));
    var theX = theBounds.getUnitDoubleValue(stringIDToTypeID("left"));
    var theY = theBounds.getUnitDoubleValue(stringIDToTypeID("top"));
    var theW = theBounds.getUnitDoubleValue(stringIDToTypeID("right")) - theBounds.getUnitDoubleValue(stringIDToTypeID("left"));
    var theH = theBounds.getUnitDoubleValue(stringIDToTypeID("bottom")) - theBounds.getUnitDoubleValue(stringIDToTypeID("top"));
    theLayers.push([theName, theIndex, theID, theX, theY, theW, theH, theW * theH])
    };
    }
    catch (e) {};
    };
    return theLayers
    };

 

Votes

Translate

Translate

Report

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
Enthusiast ,
Nov 24, 2021 Nov 24, 2021

Copy link to clipboard

Copied

Really, thank you c.pfaffenbichler
The first code works very well for me
But I ask you for a code that checks all groups
And it converts it from px to cm
Really nice and amazing work
Thank you again

Votes

Translate

Translate

Report

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
Community Expert ,
Nov 24, 2021 Nov 24, 2021

Copy link to clipboard

Copied

Try replacing the line

groupSelectedLayers (theArray[m][0][3])

with these three lines

        var theW = theArray[m][0][3].split("*")[0]/activeDocument.resolution*2.54;
        var theH = theArray[m][0][3].split("*")[1]/activeDocument.resolution*2.54;
        groupSelectedLayers (theW+"cm x"+theH+"cm")

 

Votes

Translate

Translate

Report

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
Enthusiast ,
Nov 24, 2021 Nov 24, 2021

Copy link to clipboard

Copied

You really are a genius c.pfaffenbichler
I didn't know how to thank you for this wonderful effort
All thanks and appreciation to you

Votes

Translate

Translate

Report

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
Enthusiast ,
Nov 24, 2021 Nov 24, 2021

Copy link to clipboard

Copied

I have a simple request
If I didn't bother you
When arranging layers and placing them inside the group
There are layers sticking out from the design
Is it possible to arrange layers within the design

Votes

Translate

Translate

Report

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
Community Expert ,
Nov 24, 2021 Nov 24, 2021

Copy link to clipboard

Copied

One could process the groups further, but getting at a truly efficient usage of canvas space would seem quite difficult to me

 

Yes that is the boat I'm in.  Its a puzzle beyond my math and logic skills. And the code you posted as you stated would not work where there were a lot of image the same size for laying them out horizontally will exceed the canvas width. But the it no difficult to add canvas. The op does not appreciate how difficult the the puzzle is.

 

I punk out I size the image to a single brick size and bricked the canvas  without staging the bricks.  I retired I have the right to take the easy way out.

 

Capture.jpg

JJMack

Votes

Translate

Translate

Report

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
Community Expert ,
Nov 24, 2021 Nov 24, 2021

Copy link to clipboard

Copied

I merged c.pfaffenbichler two scripts and added the  code to expand the canvas width if needed;

 

 

// group layers of the same bounds dimensions;
// 2021, use it at your own risk;
if (app.documents.length > 0) {
    var theLayers = collectLayersBounds ();
    theLayers.sort(sortArrayByIndexedItem);
    var theIndex = 1;
    var theArray = [[theLayers[0]]];
    while (theIndex != theLayers.length) {
        if (theArray[theArray.length-1][0][3] == theLayers[theIndex][3]) {
            theArray[theArray.length-1].push(theLayers[theIndex])
        }
        else {theArray.push([theLayers[theIndex]])};
        theIndex++
    };
// group layers;
    for (var m = 0; m < theArray.length; m++) {
        selectLayerByID(theArray[m][0][2], false);
        for (var n = 1; n < theArray[m].length; n++) {
            selectLayerByID(theArray[m][n][2], true);
        };
        groupSelectedLayers (theArray[m][0][3])
    };
// move layers;
    for (var o = 0; o < theArray.length; o++) {
        var theW = Number(theArray[o][0][3].split("*")[0]);
        for (var n = 1; n < theArray[o].length; n++) {
            moveLayer (theArray[o][n][2], theArray[o][0][4]-theArray[o][n][4]+theW*n, theArray[o][0][5]-theArray[o][n][5]);
        };
    };
	
	var savedRuler = app.preferences.rulerUnits;
	app.preferences.rulerUnits = Units.PIXELS;
	var myDocument = activeDocument;
	var docW = myDocument.width;
	var docH = myDocument.height;
	var theGroups = collectGroupsBounds ();
	theGroups.sort(sortArrayByIndexedItems);
	var theRefX = 0;
	var theRefY = 0;
	var lineH = 0;
	var changeWidth = docW;
	var changeHeight = 0;
	for (var m =0; m < theGroups.length; m++) {
		var theX = theGroups[m][3];
		var theY = theGroups[m][4];
		var theW = theGroups[m][5];
		var theH = theGroups[m][6];
		// check if line exceeds doc width;
		if (theRefX + theW >= docW) {
			theRefX = 0;
			theRefY = theRefY + lineH;
			lineH = 0;
		};
		if (theH > lineH) {lineH = theH};
		// move group;		
		moveLayer (theGroups[m][2], theRefX-theX, theRefY-theY);
		theRefX = theRefX+theW;
		if (changeHeight < theRefY+theH)changeHeight = theRefY+theH;
		if (docW < theW & changeWidth < theW) changeWidth = theW; 
	};
	myDocument.resizeCanvas(changeWidth,changeHeight,AnchorPosition.TOPLEFT);
	SetViewFitonScreen();
	app.preferences.rulerUnits = savedRuler;	
};
////////////////////////////////////
// based on code by mike hale, via paul riggott;
function selectLayerByID(id,add){ 
add = undefined ? add = false:add 
var ref = new ActionReference();
    ref.putIdentifier(charIDToTypeID("Lyr "), id);
    var desc = new ActionDescriptor();
    desc.putReference(charIDToTypeID("null"), ref );
       if(add) desc.putEnumerated( stringIDToTypeID( "selectionModifier" ), stringIDToTypeID( "selectionModifierType" ), stringIDToTypeID( "addToSelection" ) ); 
      desc.putBoolean( charIDToTypeID( "MkVs" ), false ); 
   try{
    executeAction(charIDToTypeID("slct"), desc, DialogModes.NO );
}catch(e){
alert(e.message); 
}
};
////// collect layers //////
function collectLayersBounds () {
    // the file;
    var myDocument = app.activeDocument;
    // get number of layers;
    var ref = new ActionReference();
    ref.putProperty(stringIDToTypeID('property'), stringIDToTypeID('numberOfLayers'));
    ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") ); 
    var applicationDesc = executeActionGet(ref);
    var theNumber = applicationDesc.getInteger(stringIDToTypeID("numberOfLayers"));
    // process the layers;
    var theLayers = new Array;
    for (var m = 0; m <= theNumber; m++) {
    try {
    var ref = new ActionReference();
    ref.putIndex( charIDToTypeID( "Lyr " ), m);
    var layerDesc = executeActionGet(ref);
    var layerSet = typeIDToStringID(layerDesc.getEnumerationValue(stringIDToTypeID("layerSection")));
    var isBackground = layerDesc.getBoolean(stringIDToTypeID("background"));
    // collect values;
    if (layerSet != "layerSectionEnd" && layerSet != "layerSectionStart" && isBackground != true) {
    var theName = layerDesc.getString(stringIDToTypeID('name'));
    var theID = layerDesc.getInteger(stringIDToTypeID('layerID'));
    var theIndex = layerDesc.getInteger(stringIDToTypeID('itemIndex'));
    var theColor = typeIDToStringID(layerDesc.getEnumerationValue(stringIDToTypeID("color")));
    var theBounds = layerDesc.getObjectValue(stringIDToTypeID("bounds"));
    var theX = theBounds.getUnitDoubleValue(stringIDToTypeID("left"));
    var theY = theBounds.getUnitDoubleValue(stringIDToTypeID("top"));
    var theW = theBounds.getUnitDoubleValue(stringIDToTypeID("right")) - theBounds.getUnitDoubleValue(stringIDToTypeID("left"));
    var theH = theBounds.getUnitDoubleValue(stringIDToTypeID("bottom")) - theBounds.getUnitDoubleValue(stringIDToTypeID("top"));
    theLayers.push([theName, theIndex, theID, theW+"*"+theH, theX, theY])
    };
    }
    catch (e) {};
    };
    return theLayers
    };
////// group //////
function groupSelectedLayers (theName) {
    var desc159 = new ActionDescriptor(); 
    var ref114 = new ActionReference(); 
    var idlayer = stringIDToTypeID( "layer" );
    var idordinal = stringIDToTypeID( "ordinal" );
    var idtargetEnum = stringIDToTypeID( "targetEnum" );
    var idnull = stringIDToTypeID( "null" );
    var idname = stringIDToTypeID( "name" );
    ref114.putEnumerated(idlayer, idordinal, idtargetEnum); 
    desc159.putReference(idnull, ref114 );
    desc159.putString(idname, "aaa" );
    executeAction( stringIDToTypeID( "groupLayersEvent" ), desc159, DialogModes.NO );
    var desc63 = new ActionDescriptor();
    var ref37 = new ActionReference();
    ref37.putEnumerated( idlayer, idordinal, idtargetEnum );
    desc63.putReference( idnull, ref37 );
    var desc64 = new ActionDescriptor();
    desc64.putString(idname, theName);
    desc63.putObject(stringIDToTypeID( "to" ), idlayer, desc64);
    executeAction(stringIDToTypeID( "set" ), desc63, DialogModes.NO)
};
////// sort a double array, thanks to sam, http://www.rhinocerus.net/forum/lang-javascript/ //////
function sortArrayByIndexedItem(a,b) {
    var theIndex = 3;
    if (a[theIndex]<b[theIndex]) return -1;
    if (a[theIndex]>b[theIndex]) return 1;
    return 0;
    };
////// move layer //////
function moveLayer (theID, hor, ver) {
selectLayerByID(theID, false);
    var desc77 = new ActionDescriptor();
    var ref38 = new ActionReference();
    var idlayer = stringIDToTypeID( "layer" );
    ref38.putEnumerated( idlayer, stringIDToTypeID( "ordinal" ), stringIDToTypeID( "targetEnum" ));
desc77.putReference( stringIDToTypeID( "null" ), ref38 );
var idto = stringIDToTypeID( "to" );
    var desc78 = new ActionDescriptor();
    var idpixelsUnit = stringIDToTypeID( "pixelsUnit" );
    desc78.putUnitDouble( stringIDToTypeID( "horizontal" ), idpixelsUnit, hor );
    desc78.putUnitDouble( stringIDToTypeID( "vertical" ), idpixelsUnit, ver );
desc77.putObject( idto, stringIDToTypeID( "offset" ), desc78 );
executeAction( stringIDToTypeID( "move" ), desc77, DialogModes.NO );
};

////////////////////////////////////
////// based on code by mike hale and paul riggott //////
function selectLayerByID(index,add){ 
	add = undefined ? add = false:add 
	var ref = new ActionReference();
    ref.putIdentifier(charIDToTypeID("Lyr "), index);
    var desc = new ActionDescriptor();
    desc.putReference(charIDToTypeID("null"), ref );
    if(add) desc.putEnumerated( stringIDToTypeID( "selectionModifier" ), stringIDToTypeID( "selectionModifierType" ), stringIDToTypeID( "addToSelection" ) ); 
    desc.putBoolean( charIDToTypeID( "MkVs" ), false ); 
    try{ executeAction(charIDToTypeID("slct"), desc, DialogModes.NO );}
	catch(e){ alert(e.message); }
};
////// sort a double array, thanks to sam, http://www.rhinocerus.net/forum/lang-javascript/ //////
function sortArrayByIndexedItems(a,b) {
	var theIndex1 = 5;
	var theIndex2 = 6;
	if (a[theIndex1]*a[theIndex2]<b[theIndex1]*b[theIndex2]) return 1;
	if (a[theIndex1]*a[theIndex2]>b[theIndex1]*b[theIndex2]) return -1;
	return 0;
};
////// move layer //////
function moveLayer (theID, hor, ver) {
	selectLayerByID(theID, false);
		var desc77 = new ActionDescriptor();
		var ref38 = new ActionReference();
		var idlayer = stringIDToTypeID( "layer" );
		ref38.putEnumerated( idlayer, stringIDToTypeID( "ordinal" ), stringIDToTypeID( "targetEnum" ));
	desc77.putReference( stringIDToTypeID( "null" ), ref38 );
	var idto = stringIDToTypeID( "to" );
		var desc78 = new ActionDescriptor();
		var idpixelsUnit = stringIDToTypeID( "pixelsUnit" );
		desc78.putUnitDouble( stringIDToTypeID( "horizontal" ), idpixelsUnit, hor );
		desc78.putUnitDouble( stringIDToTypeID( "vertical" ), idpixelsUnit, ver );
	desc77.putObject( idto, stringIDToTypeID( "offset" ), desc78 );
	executeAction( stringIDToTypeID( "move" ), desc77, DialogModes.NO );
};
////// collect groups //////
function collectGroupsBounds () {
	// the file;
    var myDocument = app.activeDocument;
	// get number of layers;
    var ref = new ActionReference();
    ref.putProperty(stringIDToTypeID('property'), stringIDToTypeID('numberOfLayers'));
    ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") ); 
    var applicationDesc = executeActionGet(ref);
    var theNumber = applicationDesc.getInteger(stringIDToTypeID("numberOfLayers"));
	// process the layers;
    var theLayers = new Array;
    for (var m = 0; m <= theNumber; m++) {
		try {
			var ref = new ActionReference();
				ref.putIndex( charIDToTypeID( "Lyr " ), m);
			var layerDesc = executeActionGet(ref);
			var layerSet = typeIDToStringID(layerDesc.getEnumerationValue(stringIDToTypeID("layerSection")));
			var isBackground = layerDesc.getBoolean(stringIDToTypeID("background"));
			// collect values;
			if (/*layerSet != "layerSectionEnd" &&*/ layerSet == "layerSectionStart" && isBackground != true) {
				var theName = layerDesc.getString(stringIDToTypeID('name'));
				var theID = layerDesc.getInteger(stringIDToTypeID('layerID'));
				var theIndex = layerDesc.getInteger(stringIDToTypeID('itemIndex'));
				var theColor = typeIDToStringID(layerDesc.getEnumerationValue(stringIDToTypeID("color")));
				// boundsNoEffects works better on groups;
				var theBounds = layerDesc.getObjectValue(stringIDToTypeID("boundsNoEffects"));
				var theX = theBounds.getUnitDoubleValue(stringIDToTypeID("left"));
				var theY = theBounds.getUnitDoubleValue(stringIDToTypeID("top"));
				var theW = theBounds.getUnitDoubleValue(stringIDToTypeID("right")) - theBounds.getUnitDoubleValue(stringIDToTypeID("left"));
				var theH = theBounds.getUnitDoubleValue(stringIDToTypeID("bottom")) - theBounds.getUnitDoubleValue(stringIDToTypeID("top"));
			theLayers.push([theName, theIndex, theID, theX, theY, theW, theH, theW * theH])
			};
		}
		catch (e) {};
    };
    return theLayers
};
//==================== Set View Fit on Screen ==============
function SetViewFitonScreen() {
  // Menu View>screen Mode Standard
    var desc1 = new ActionDescriptor();
    var ref1 = new ActionReference();
    ref1.putEnumerated(app.charIDToTypeID('Mn  '), app.charIDToTypeID('MnIt'), app.stringIDToTypeID("screenModeStandard"));
    desc1.putReference(app.charIDToTypeID('null'), ref1);
    executeAction(app.charIDToTypeID('slct'), desc1, DialogModes.NO);
  // Menu View>Fit on screen
    var desc1 = new ActionDescriptor();
    var ref1 = new ActionReference();
    ref1.putEnumerated(app.charIDToTypeID('Mn  '), app.charIDToTypeID('MnIt'), app.charIDToTypeID('FtOn'));
    desc1.putReference(app.charIDToTypeID('null'), ref1);
    executeAction(app.charIDToTypeID('slct'), desc1, DialogModes.NO);
};
JJMack

Votes

Translate

Translate

Report

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
Enthusiast ,
Nov 24, 2021 Nov 24, 2021

Copy link to clipboard

Copied

I am very grateful for your effort and interest
But the c.pfaffenbichler code sorts the images from this

لقطة الشاشة 2021-11-25 014316.png

to this

لقطة الشاشة 2021-11-25 015152.png

In No. 1 the required was done as I wanted
And in number 2, I liked the arrangement of the side pictures of each other
But in the event that the number of pictures is many
I found that the pictures are out of the way of design
I want a code that arranges images in the same way within the design boundaries and not outside the design

Votes

Translate

Translate

Report

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
Community Expert ,
Nov 24, 2021 Nov 24, 2021

Copy link to clipboard

Copied

From the beginning I have written to do a optimal layer layout is a very complex and a challenge far beyond my skill level.  I only hack at Photoshop Scripting I do not know Javascript. Adobe Scripting DOM does not cover all of Photoshop features,. So Action Manager Code must be use to script many  of  Photoshop features. While I can use code the Adobe Scriptlistener plug-in logs in Action Manager code it is not very readable and only covers half of the story the execution half of the action manager capability. The retrieval capability half of the action manager get is not logged by the Scriplisener.   When you do not know what event the Action manager has and their four Character ID and the data structures required for action manager code. Much of what you can done scripting Photoshop  is out of your reach.  As far as I can tell you do not understand what is required to solve the optimal layout solution. I do not believe you even tried to write any Photoshop script code to see what you can do to to solve your issue.  All I read is I have a simple request I want this I want that. Your request is far from simple,  You need to work out the solution so far no no one here has a solution for what you want.   What you want is  feasible and may even be available in some Application design for layout problems. Photoshop is a Pixel editor.

JJMack

Votes

Translate

Translate

Report

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
Community Expert ,
Nov 25, 2021 Nov 25, 2021

Copy link to clipboard

Copied

LATEST

I changed the code in the merged script to fit the canvas to the layers layout. To keep the same size images together.  An optional layout for the current canvas that keep same size images adjacent is very complicated.

Capture.jpg

Should Work even when the images combined canvas size is greater then the documents canvas size. 

Capture.jpg

Capture.jpg

JJMack

Votes

Translate

Translate

Report

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
Community Expert ,
Nov 25, 2021 Nov 25, 2021

Copy link to clipboard

Copied

Below will still not provide optimal results, but avoid some issues. 

Maybe it is time for you to explain what you are actually trying to achieve – what is the real task you are trying to automate here? 

Screenshot 2021-11-25 at 13.00.41.pngScreenshot 2021-11-25 at 13.01.53.png

// distribute layers on canvas;
// 2021, use it at your own risk;
if (app.documents.length > 0) {
	var savedRuler = app.preferences.rulerUnits;
	app.preferences.rulerUnits = Units.PIXELS;
	var myDocument = activeDocument;
	var docW = myDocument.width;
	var docH = myDocument.height;
	var theLayers = collectLayersBounds ();
// sort by height;
	theLayers.sort(sortArrayByIndexedItem);
	var theRefX = 0;
	var theRefY = 0;
	var lineH = 0;
	for (var m =0; m < theLayers.length; m++) {
		var theX = theLayers[m][3];
		var theY = theLayers[m][4];
		var theW = theLayers[m][5];
		var theH = theLayers[m][6];
// check if line exceeds doc width;
		if (theRefX + theW >= docW) {
			theRefX = 0;
			theRefY = theRefY + lineH;
			lineH = 0;
		};
		if (theH > lineH) {lineH = theH};
// move group;		
		moveLayer (theLayers[m][2], theRefX-theX, theRefY-theY);
		theRefX = theRefX+theW;
		};
	app.preferences.rulerUnits = savedRuler;
	};
////////////////////////////////////
////// based on code by mike hale and paul riggott //////
function selectLayerByID(index,add){ 
add = undefined ? add = false:add 
var ref = new ActionReference();
    ref.putIdentifier(charIDToTypeID("Lyr "), index);
    var desc = new ActionDescriptor();
    desc.putReference(charIDToTypeID("null"), ref );
       if(add) desc.putEnumerated( stringIDToTypeID( "selectionModifier" ), stringIDToTypeID( "selectionModifierType" ), stringIDToTypeID( "addToSelection" ) ); 
      desc.putBoolean( charIDToTypeID( "MkVs" ), false ); 
   try{
    executeAction(charIDToTypeID("slct"), desc, DialogModes.NO );
}catch(e){
alert(e.message); 
}
};
////// sort a double array, thanks to sam, http://www.rhinocerus.net/forum/lang-javascript/ //////
function sortArrayByIndexedItem(a,b) {
    var theIndex1 = 6;
    if (a[theIndex1]<b[theIndex1]) return 1;
    if (a[theIndex1]>b[theIndex1]) return -1;
    return 0;
    };
////// move layer //////
function moveLayer (theID, hor, ver) {
	selectLayerByID(theID, false);
		var desc77 = new ActionDescriptor();
		var ref38 = new ActionReference();
		var idlayer = stringIDToTypeID( "layer" );
		ref38.putEnumerated( idlayer, stringIDToTypeID( "ordinal" ), stringIDToTypeID( "targetEnum" ));
	desc77.putReference( stringIDToTypeID( "null" ), ref38 );
	var idto = stringIDToTypeID( "to" );
		var desc78 = new ActionDescriptor();
		var idpixelsUnit = stringIDToTypeID( "pixelsUnit" );
		desc78.putUnitDouble( stringIDToTypeID( "horizontal" ), idpixelsUnit, hor );
		desc78.putUnitDouble( stringIDToTypeID( "vertical" ), idpixelsUnit, ver );
	desc77.putObject( idto, stringIDToTypeID( "offset" ), desc78 );
	executeAction( stringIDToTypeID( "move" ), desc77, DialogModes.NO );
	};
////// collect groups //////
function collectLayersBounds () {
// the file;
    var myDocument = app.activeDocument;
// get number of layers;
    var ref = new ActionReference();
    ref.putProperty(stringIDToTypeID('property'), stringIDToTypeID('numberOfLayers'));
    ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") ); 
    var applicationDesc = executeActionGet(ref);
    var theNumber = applicationDesc.getInteger(stringIDToTypeID("numberOfLayers"));
// process the layers;
    var theLayers = new Array;
    for (var m = 0; m <= theNumber; m++) {
    try {
    var ref = new ActionReference();
    ref.putIndex( charIDToTypeID( "Lyr " ), m);
    var layerDesc = executeActionGet(ref);
    var layerSet = typeIDToStringID(layerDesc.getEnumerationValue(stringIDToTypeID("layerSection")));
    var isBackground = layerDesc.getBoolean(stringIDToTypeID("background"));
// collect values;
    if (layerSet != "layerSectionEnd" && layerSet != "layerSectionStart" && isBackground != true) {
	var theName = layerDesc.getString(stringIDToTypeID('name'));
    var theID = layerDesc.getInteger(stringIDToTypeID('layerID'));
    var theIndex = layerDesc.getInteger(stringIDToTypeID('itemIndex'));
    var theColor = typeIDToStringID(layerDesc.getEnumerationValue(stringIDToTypeID("color")));
// boundsNoEffects works better on groups;
    var theBounds = layerDesc.getObjectValue(stringIDToTypeID("boundsNoEffects"));
    var theX = theBounds.getUnitDoubleValue(stringIDToTypeID("left"));
    var theY = theBounds.getUnitDoubleValue(stringIDToTypeID("top"));
    var theW = theBounds.getUnitDoubleValue(stringIDToTypeID("right")) - theBounds.getUnitDoubleValue(stringIDToTypeID("left"));
    var theH = theBounds.getUnitDoubleValue(stringIDToTypeID("bottom")) - theBounds.getUnitDoubleValue(stringIDToTypeID("top"));
    theLayers.push([theName, theIndex, theID, theX, theY, theW, theH, theW * theH])
    };
    }
    catch (e) {};
    };
    return theLayers
    };

 

Votes

Translate

Translate

Report

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