Skip to main content
Mohamed Hameed21513110
Inspiring
January 5, 2022
解決済み

Copy and past layer boundary

  • January 5, 2022
  • 返信数 3.
  • 2782 ビュー

- First : Copy the code / I want a code when choosing a specific layer and standing on it, it copies the dimensions of the layer and saves it

 

- Second : Paste the code/I want when selecting other layers and executing the code, it will scale the layer to the same dimensions as the layer the values were copied to

This idea is similar to that of Copy layerStyle and Past layerStyle

このトピックへの返信は締め切られました。
解決に役立った回答 Stephen Marsh

 

@Mohamed Hameed21513110 – as I said, the points are only minor, however, I believe that they are worth discussing as a learning exercise.

 

1) The script explicitly captures the current ruler units to a variable startRulerUnits, before setting the rulers to pixels. All good so far... However, you didn't set the original ruler units back again at the end of the script. It's a simple and easy mistake to make, I have been there myself. My assumption is that if you didn't want to restore the original rulers in the first place, there would be no need to capture their value, you would have just set the script to change the units to pixels.

 

Therefore:

 

app.preferences.rulerUnits = startRulerUnits;

 

Should be added at the end of the script, before the SaveCurrentConfig function.

 

2) The script obviously works fine as is, the following just looks like a bit of cleanup/housekeeping:

 

var cInfo

cInfo = layerWidth + ',' + layerHeight;

 

I'm not trying to "nit pick" on this point, it just didn't look right, it obviously works as is and I could be missing something? I would clean this to:

 

var cInfo = layerWidth + ',' + layerHeight;

 

I haven't looked over the second script in detail.

 

I am very happy that you could read between the lines and produce the two scripts from my original outline of what I believed was required. The scripts that I made at the time followed the same basic steps, however, I went about things differently to achieve the same end.

 


Script 2 of 2:

 

/*
Resize Selected Layers from Source - Script 2 of 2.jsx
Stephen Marsh, v1.0 - 6th January 2022
https://community.adobe.com/t5/photoshop-ecosystem-discussions/copy-and-past-layer-boundary/td-p/12636059
NOTES:
Run this script on multiple target layers to resize using the source layer size from the desktop preference file
*/

//#target photoshop

function main() {

    var prefFileIn = File('~/Desktop/_Resize_Layer_Preference_File.txt');

    if (File(prefFileIn).exists && File(prefFileIn).length > 0) {

        // Read the preference file from the user's desktop
        prefFileIn.open('r');
        // Read the 1st line from the log file, a means to an end...
        var logInfo = prefFileIn.readln(1);
        // Read the 2nd line from the log file & convert the string to a number/integer
        var prefFileWidthValue = Math.floor(prefFileIn.readln(2));
        //alert(prefFileWidthValue.toSource());
        // Read the 3rd line from the log file & convert the string to a number/integer
        var prefFileHeightValue = ~~prefFileIn.readln(3);
        //alert(prefFileHeightValue.toSource());
        prefFileIn.close();

        // Debugging
        $.writeln(logInfo);
        $.writeln(prefFileWidthValue);
        $.writeln(prefFileHeightValue);

        processSelectedLayers();

        // End of script notification
        var layerWidth = (app.activeDocument.activeLayer.bounds[2] - app.activeDocument.activeLayer.bounds[0]);
        var layerHeight = (app.activeDocument.activeLayer.bounds[3] - app.activeDocument.activeLayer.bounds[1]);
        app.refresh();
        alert("Script completed!" + "\r" + "Source Layer Size:" + "\r" + "W: " + prefFileWidthValue + "px" + "  H: " + prefFileHeightValue + "px" + "\r" + "Target Layer Size:" + "\r" + "W: " + layerWidth + "  H: " + layerHeight);


        // Functions

        function processSelectedLayers() {
            var s2t = stringIDToTypeID;
            (r = new ActionReference).putProperty(s2t('property'), p = s2t('targetLayersIDs'));
            r.putEnumerated(s2t('document'), s2t('ordinal'), s2t('targetEnum'));
            var lrs = executeActionGet(r).getList(p),
                sel = new ActionReference();

            for (var i = 0; i < lrs.count; i++) {
                sel.putIdentifier(s2t('layer'), p = lrs.getReference(i).getIdentifier(s2t('layerID')));
                (r = new ActionReference).putIdentifier(s2t('layer'), p);
                (d = new ActionDescriptor()).putReference(s2t("target"), r);
                executeAction(s2t('select'), d, DialogModes.NO);

                // Call the resize layer function
                resizeLayerFromPrefFile();
            }
        }

        function resizeLayerFromPrefFile() {
            // Store the original ruler units and set to px
            var savedRuler = app.preferences.rulerUnits;
            app.preferences.rulerUnits = Units.PIXELS;

            // Layer origin
            // ~~ = convert string to integer
            var layerX = ~~app.activeDocument.activeLayer.bounds[0].value;
            var layerY = ~~app.activeDocument.activeLayer.bounds[1].value;

            // Convert the selected layer to an embedded Smart Object
            // A hack to work in px rather than converting to % for use with .resize()
            executeAction(stringIDToTypeID("newPlacedLayer"), undefined, DialogModes.NO);
            // Edit the smart object
            app.runMenuItem(stringIDToTypeID('placedLayerEditContents'));
            // Resize the smart object using px
            app.activeDocument.resizeImage(prefFileWidthValue, prefFileHeightValue, app.activeDocument.resolution, ResampleMethod.BICUBIC);
            // Close saving changes
            app.activeDocument.close(SaveOptions.SAVECHANGES);
            // Align Active Layer to Select All.jsx
            align2SelectAll('AdLf');
            align2SelectAll('AdTp');
            // Reposition the resized layer back to the upper left origin
            app.activeDocument.activeLayer.translate(layerX, layerY);
            // Convert the smart object back to a layer (less compatible? 'placedLayerConvertToLayers')
            app.runMenuItem(stringIDToTypeID('rasterizePlaced'));
            // Restore the original ruler units
            app.preferences.rulerUnits = savedRuler;

        }

        function align2SelectAll(method) {
            /* 
            AdLf = Align Left
            AdRg = Align Right
            AdCH = Align Centre Horizontal
            AdTp = Align Top
            AdBt = Align Bottom
            AdCV = Align Centre Vertical
            */
            app.activeDocument.selection.selectAll();
            var desc = new ActionDescriptor();
            var ref = new ActionReference();
            ref.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
            desc.putReference(charIDToTypeID("null"), ref);
            desc.putEnumerated(charIDToTypeID("Usng"), charIDToTypeID("ADSt"), charIDToTypeID(method));
            try {
                executeAction(charIDToTypeID("Algn"), desc, DialogModes.NO);
            } catch (e) {}
            app.activeDocument.selection.deselect();
        }

    } else {
        app.beep();
        alert('There is no valid file named "_Resize_Layer_Preference_File.txt" on the desktop!');
    }
}

app.activeDocument.suspendHistory("Resize selected layers script", "main()");

返信数 3

Mohamed Hameed21513110
Inspiring
January 10, 2022

I found the solution that gives me the desired result and this is what I wanted
Thank you all

 

First : Copy the code

var startRulerUnits = app.preferences.rulerUnits;  
    app.preferences.rulerUnits = Units.PIXELS;  
var theBounds = app.activeDocument.activeLayer.bounds;
var layerWidth = theBounds[2] - theBounds[0];
var layerHeight = theBounds[3] - theBounds[1];

var ConfigFile = "~/Desktop/pref.txt";
var cInfo

cInfo = layerWidth +','+layerHeight ;
SaveCurrentConfig(cInfo, ConfigFile);

function SaveCurrentConfig(cInfo, ConfigFile){
    var F = new File(ConfigFile);
     F.open("w");
   F.write(cInfo);
    F.close();
}

 

Second : Paste the code

 

var thePref = "~/Desktop/pref.txt";

if (File (thePref).exists == true) {
     var theText = readPref (thePref);
     Width = theText.split(',')[0];
    Hight = theText.split(',')[1];
   
  //- Resize Layer With input Value - //
var startRulerUnits = app.preferences.rulerUnits;  
    app.preferences.rulerUnits = Units.PIXELS;  
    var bounds = activeDocument.activeLayer.bounds;  
    var width = bounds[2].value - bounds[0].value;
    var height = bounds[3].value - bounds[1].value;
    var newWidth = (100 / width) * Width;  
    var newHeight = (100 / height) * Hight;  
    activeDocument.activeLayer.resize(newWidth, newHeight, AnchorPosition.MIDDLECENTER);
    app.preferences.rulerUnits = startRulerUnits;     
     }
 
 function readPref (thePath) {
  if (File(thePath).exists == true) {
    var file = File(thePath);
    file.open("r", "TEXT", "????");
    file.encoding= 'BINARY';
    var theText = new String;
    for (var m = 0; m < file.length; m ++) {
      theText = theText.concat(file.readch());
      };
    file.close();
    return String(theText)
    }
  };

 

Stephen Marsh
Community Expert
Community Expert
January 11, 2022

@Mohamed Hameed21513110 – Great job!

 

You took this further than I expected, kudos to you.

 

I have a couple of very minor critique points on the first script if that is OK? I only mention this as I have made these mistakes in the past and may well do so in the future!

Mohamed Hameed21513110
Inspiring
January 11, 2022

@Stephen Marsh 

Thank you for your encouragement
I accept any criticism as long as it is constructive criticism and aims to learn from my mistakes
And you, you know, I'm not very deep into the codes, but when I wrote this code, I searched a lot and tried the code and discovered the errors and worked on them until I came up with the code in a way that fit what I wanted

So let me know what's wrong so I can fix it

Stephen Marsh
Community Expert
Community Expert
January 5, 2022

@Mohamed Hameed21513110 

 

I'll help you to break down your request into sections. You can then find the code for each section and combine the various bits of code together. This is only how I would do things, those with greater knowledge and experience would do things differently.

 

This help is offered under the concept of: 

“Give a man a fish, and you feed him for a day. Teach a man to fish, and you feed him for a lifetime.”

 

 

@Mohamed Hameed21513110 wrote:

- First : Copy the code / I want a code when choosing a specific layer and standing on it, it copies the dimensions of the layer and saves it


 

1A: Find code which collects the layer bounds of a selected layer to a variable

1B: Find code which saves a variable or other info to a .txt "log" file

 

This will be one separate script (or a conditional part of a single script that uses a keyboard modifier key press when run, but that is more advanced, I'd just stick with two separate scripts to begin with, baby steps).

 

 


@Mohamed Hameed21513110 wrote:

- Second : Paste the code/I want when selecting other layers and executing the code, it will scale the layer to the same dimensions as the layer the values were copied to

This idea is similar to that of Copy layerStyle and Past layerStyle


 

2A: Find code which reads the info from the text log file and saves it to a variable.

2B: Find code which resizes a selected layer's bounds using the info in the variable which was read from the text file

2C: Once you can do this for a single layer, you would then need to find code examples for multiple selected layers, just start with a single layer, again baby steps

 

Stephen Marsh
Community Expert
Community Expert
January 6, 2022

@Mohamed Hameed21513110 

Thank you for marking my answer as correct.

 

Before you start your code hunt for the key steps outlined, and before we explore how to adapt the code you find and tie it all together... Do you have any questions, comments etc, on my previous post and or the proposed code hunt?

Kukurykus
Legend
January 5, 2022

Stop creating similar threads, like you used to do in the passed year. Just yestarday you made this one:

Paste the copied image inside the selection

 

Additionally remember this forum is not to write scripts for others but mainly to help to finish already provided, solve unique problems and suggest methods to take.

 

The only you do is each time to request new scripts, written from zero. Now this becomes ridiciolous. You ask of very simple code to share. One of many you can find yourself on this forum in different forms, or easily learn from Photoshop Scripting Reference.

 

Make some effort to create code you need, and come back when you get stuck.

Mohamed Hameed21513110
Inspiring
January 5, 2022

@Kukurykus 

Sorry, but the title of this article and what I want here is different from what I want in the other article

Kukurykus
Legend
January 5, 2022

It's variation of that other request that can be continued by alike methods.

 

The things you're asking are easily searchable on this forum, but you don't do effort to find it. Still you can use mentioned reference to achieve your goal, without aksing constantly 'to tie your shoelaces'. Show your code you used / wrote so far...