Skip to main content
Participant
February 28, 2023
Question

can't make my JS script to work in Photoshop

  • February 28, 2023
  • 3 replies
  • 1602 views

Hello everyone.

I'm trying to make a PS script that would merge one by one all the PNG files from a directory with a background image, and save it in another folder. 

I came up with that script : 

// Background image directory and name
var backgroundDir = new Folder("bg_image");
var backgroundFile = backgroundDir + "/background_image.jpg";

// Logos directory and files
var logoDir = new Folder("logo");
var logoFiles = logoDir.getFiles("*.png");

// logo loop
for (var i = 0; i < logoFiles.length; i++) {

    // open background image and get current logo
    var backgroundDoc = app.open(backgroundFile);
    var logoFile = logoFiles[i];
    
    // New Layer for logo and load it
    var logoLayer = backgroundDoc.artLayers.add();
    logoLayer.place(logoFile);

    // Resize logo and Set logo height to 90% of background height
    var logoHeight = backgroundDoc.height * 0.9;
    logoLayer.resize(undefined,logoHeight);

    // Center logo on the picture
    logoLayer.translate(backgroundDoc.width/2 - logoLayer.bounds.width/2,backgroundDoc.height/2 - logoLayer.bounds.height/2);

    // final save 
    var finalDir = new Folder("final");
    if(!finalDir.exists) {
        finalDir.create();
    }
    var finalFile = new File(finalDir + "/" + logoFile.name.replace(/\.[^\.]+$/, '') + "_final.jpg");
    backgroundDoc.saveAs(finalFile, new JPEGSaveOptions(), true);

    // close background image
    backgroundDoc.close(SaveOptions.DONOTSAVECHANGES);
}

 

But it doesn't seem to work and i can't see where is my mistake.

I dont have any error message, but nothing happens.

What i do is just launching PS2023, then go to file/scripts/browse and load my JS. But nothing happens like no script was charged 😞

 

Any help would be appreciated 🙂

This topic has been closed for replies.

3 replies

Stephen Marsh
Community Expert
Community Expert
March 1, 2023

@silk1975 

 

The following code will give you a result, however, I had to comment out some code that you will need to work on further...

 

// Capture and set the original ruler units to pixels
var origUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;

// Background image directory and name
var backgroundDir = new Folder("~/Desktop/bg_image");
var backgroundFile = new File(backgroundDir + "/" + "background_image.jpg");

// Logos directory and files
var logoDir = new Folder(backgroundDir + "/" + "logo");
var logoFiles = logoDir.getFiles("*.png");

// logo loop
for (var i = 0; i < logoFiles.length; i++) {

    // open background image and get current logo
    var backgroundDoc = app.open(backgroundFile);
    var logoFile = logoFiles[i];

    // New Layer for logo and load it
    var logoLayer = backgroundDoc.artLayers.add();

    placeFile(new File(logoFile), false, 0, 0);


    // Resize logo and Set logo height to 90% of background height
    //var logoHeight = backgroundDoc.height * 0.9;
    //logoLayer.resize(undefined,logoHeight);

    // Center logo on the picture
    //logoLayer.translate(backgroundDoc.width / 2 - logoLayer.bounds.width / 2, backgroundDoc.height / 2 - logoLayer.bounds.height / 2);

    // final save 
    var finalDir = new Folder(backgroundDir + "/" + "final");
    if (!finalDir.exists) {
        finalDir.create();
    }
    var finalFile = new File(finalDir + "/" + logoFile.name.replace(/\.[^\.]+$/, '') + "_final.jpg");
    backgroundDoc.saveAs(finalFile, new JPEGSaveOptions(), true);

    // close background image
    backgroundDoc.close(SaveOptions.DONOTSAVECHANGES);
}

// Restore the original ruler units
app.preferences.rulerUnits = origUnits;

function placeFile(null2, linked, horizontal, vertical) {
    var s2t = function (s) {
        return app.stringIDToTypeID(s);
    };
    var AD = new ActionDescriptor();
    AD.putInteger(s2t("ID"), 1);
    AD.putPath(s2t("null"), null2);
    AD.putBoolean(s2t("linked"), linked); // false for embedded
    AD.putEnumerated(s2t("freeTransformCenterState"), s2t("quadCenterState"), s2t("QCSAverage"));
    AD.putUnitDouble(s2t("horizontal"), s2t("pixelsUnit"), horizontal);
    AD.putUnitDouble(s2t("vertical"), s2t("pixelsUnit"), vertical);
    AD.putObject(s2t("offset"), s2t("offset"), AD);
    executeAction(s2t("placeEvent"), AD, DialogModes.NO);
}

 

Please compare your original code to this edited version.

 

Note that the following has been disabled, you will need to put in more work to correct it:

 

    // Resize logo and Set logo height to 90% of background height
    //var logoHeight = backgroundDoc.height * 0.9;
    //logoLayer.resize(undefined,logoHeight);

    // Center logo on the picture
    //logoLayer.translate(backgroundDoc.width / 2 - logoLayer.bounds.width / 2, backgroundDoc.height / 2 - logoLayer.bounds.height / 2);

 

 

Stephen Marsh
Community Expert
Community Expert
March 1, 2023

@silk1975 

 

In addition to the previously mentioned issues with your various paths, there is an issue with this line:

 

logoLayer.place(logoFile);

 

Where did you get that code? From ChatGPT?

 

There is no .place method for artLayer or artLayers

 

So instead of using standard DOM code (Document Object Model), you will need AM code (Action Manager). The most commonly available method is to use the ScriptingListener plug-in to record (and then edit as required) the image placement process.

 

Legend
February 28, 2023

You open a folder called "bg_image" and one called "logo". But how does Photoshop know where to look for these? 

I suggest as well as using full paths, you add some messages to track your progress through the script.

silk1975Author
Participant
February 28, 2023

everything is at the same place (my 2 folders and my script), i assumed Photoshop would use the relative paths instead of full paths...

I'll try with full paths, but i still dont get why i do'nt have error message with the relative paths if PS can't find them 😕😕

Legend
February 28, 2023

JavaScript doesn't necessarily give you error messages for things you don't want. For instance my folder = new Folder(path) doesn't fail if the path doesn't exist, because it can be used as part of creating a new folder. Each time you use an API you need to check for success by whatever you need to work. For example check the value of myFolder.exists. Report if the folder is empty instead of doing nothing etc.