Skip to main content
MasterCrod103
Participating Frequently
February 8, 2023
Answered

Batch replace smart objects script using a linked file for multiple files

  • February 8, 2023
  • 4 replies
  • 14942 views

Hey guys,

 

I have been digging into the forums but haven't seen a script for this use case yet. I barely have any script knowledge. I am looking for a script that can essentially update a smart object file (.psb), and save it and export both the updated smart object file itself and all of the linked mockups.

 

I have a single psb smart object file that is linked to 8 other template files. That way when I update the smart object, it reflects across all the template files which is nice. But I need to do this so many times a day that a script would be highly beneficial.

 

My current process:

1. Open 8 mockups and the linked PSB file associated with them

2. Drag image into PSB file

3. Expand image to fit dimensions

4. Save image to update the other mockups

5. Save the PSB file as its own JPG at project dimensions

6. Use image processor to export all the updated mockups at a certain size

 

What I am looking for in a script:

1. Pulls images from a folder

2. Place said images into the smart object PSB file linked to other mockup templates

3. Saves the PSB file with each image (which updates all the mockups)
4. Exports all of the files as JPGs while exporting the PSB file as JPG in its already set project dimensions at full quality

 

Does anyone know of a script that can do this? Or maybe one that is fairly close? Thank you!

This topic has been closed for replies.
Correct answer Stephen Marsh

Gotcha thats no problem! I've been using the script a bit today and was wondering about a couple things. Let me know what you think.

 

1. Is there a way to only have the script save just the smart object file instead of all the files since the smart object file is the only one that changes and updates the rest?

 

2. How do I change the export quality of the smart object file export to max it out?

 

3. At the end of the script, there is a script alert indicating the success of the execution, and then it opens the export folder. Is there a way to remove these occurrences?


quote

1. Is there a way to only have the script save just the smart object file instead of all the files since the smart object file is the only one that changes and updates the rest?

 

@MasterCrod103 

 

Sure, I was assuming that you would wish all files to be "synchronised", but this is easy to do by deleting the appropriate chunk of code. 

 

quote

2. How do I change the export quality of the smart object file export to max it out?

 

By adjusting the quality value from 70 to 100. I have changed this for independent control, the 4K image is now saved at 100 quality, however the smaller JPEG files are still saved at 70. How it was previously setup was the same value for both.

 

quote

3. At the end of the script, there is a script alert indicating the success of the execution, and then it opens the export folder. Is there a way to remove these occurrences?

 

You can either delete or comment out the code, I have done both in the updated 1.1 version below:

 

/*
Save JPEG Versions from Templates v1-0.jsx
https://community.adobe.com/t5/photoshop-ecosystem-discussions/batch-replace-smart-objects-script-using-a-linked-file-for-multiple-files/m-p/13568165
v1.1 16th February 2023, Stephen Marsh

Notes:
* All 10 files must be open...
* The 'Placeholder_Screen.psb' should have been manually updated with the new content and saved.
* All of the 9 template files should have been automatically updated from the linked smart object placeholder.
* Run the script, it will create the new output folder and JPEG versions at 3840x2160px and 2000x1600px size.
*/

#target photoshop

    (function () {

        if (documents.length === 10) {

            try {

                // Save the "Placeholder_Screen.psb" document
                activeDocument = documents.getByName("Placeholder_Screen.psb");
                activeDocument.artLayers.add();
                activeDocument.activeLayer.name = "_T-E-M-P_";
                activeDocument.activeLayer.remove();
                activeDocument.save();

                // Create the next folder
                var lastDirPath = Folder.selectDialog("Please select the last 'TV####' folder:", "~/Desktop/Batch Replace SO/Tests/Samsung TV Frame Art");
                if (lastDirPath === null) {
                    alert('Script cancelled!');
                    return;
                }

                var lastDigits = lastDirPath.name.replace(/TV0/, "");
                lastDigits = Number(lastDigits) + 1;
                var newDirName = "TV0" + lastDigits;
                var newDirPath = Folder(lastDirPath.parent);
                var newDir = Folder(decodeURI(newDirPath + "/" + newDirName));
                if (!newDir.exists) newDir.create();

                // Export the SO file at native 3840x2160px size
                var saveFileJPEG = new File(newDirPath + "/" + newDirName + "/" + newDirName + ".jpg");
                SaveForWeb(100, saveFileJPEG);
                activeDocument.close(SaveOptions.DONOTSAVECHANGES);

                // Loop over the open template files and save 2000x1600px JPEG versions to the same folder
                while (app.documents.length > 0) {
                    var origUnits = app.preferences.rulerUnits;
                    app.preferences.rulerUnits = Units.PIXELS;
                    var docName = activeDocument.name.replace(/\.[^\.]+$/, '');
                    activeDocument.resizeImage(2000, null, null, ResampleMethod.BICUBIC);
                    var saveFileJPEG = new File(newDirPath + "/" + newDirName + "/" + docName + ".jpg");
                    SaveForWeb(70, saveFileJPEG);
                    activeDocument.close(SaveOptions.DONOTSAVECHANGES);
                    app.preferences.rulerUnits = origUnits;
                }

                // End of script
                //app.beep();

            } catch (e) {
                alert("The file 'Placeholder_Screen.psb' isn't open!");
            }

        } else {
            alert("Only the 10 required template/placeholder files should be open!");
        }

    }());


///// Functions /////

function SaveForWeb(qValue, saveFileJPEG) {
    var sfwOptions = new ExportOptionsSaveForWeb();
    sfwOptions.format = SaveDocumentType.JPEG;
    sfwOptions.includeProfile = true;
    sfwOptions.interlaced = 0;
    sfwOptions.optimized = true;
    sfwOptions.quality = qValue;
    app.activeDocument.exportDocument(saveFileJPEG, ExportType.SAVEFORWEB, sfwOptions);
}

 

4 replies

Stephen Marsh
Brainiac
February 14, 2023

@MasterCrod103 

 

Try the following first draft script. A lot more can be done with time and effort.

 

All 10 files must be open...

 

The 'Placeholder_Screen.psb' should have been manually updated with the new content and saved.

 

All of the 9 template files should have been automatically updated from the saved linked smart object placeholder. It would be good to save these 9 files, but that could be a bit of a pain.

 

You should update the path from "~/Desktop/Batch Replace SO/Tests/Samsung TV Frame Art" to match your directory structure.

Run the script, all open placeholder and template files will be saved, just in case you didn't save them. You will then be prompted to select the last numbered folder in the parent 'Samsung TV Frame Art' folder. For example, if you select folder TV0287, then a new TV0288 folder will be created.

 

JPEG Save for Web 70% quality versions at 3840x2160px and 2000x1600px size will be saved to this new folder (Export As isn't currently supported for actions or scripts). You may need to adjust the quality setting to come close to Export As file size (they use different algorithms).

 

At the end of the script, all open files will be closed. I do understand that you would like to keep these files open to replace the next image and repeat... However, for an unknown reason, I was having problems updating all open files in a 'for' loop while keeping them open, so I had to use a 'while' loop and then close the files so as not to create an infinite loop. This should be fixable, perhaps another scripter here can fix my code with a working for loop!

 

Only new folders up to TV0999 will be handled cleanly. The current code would need to be updated once you get to folder 1000 when you need the next set incremented to 1001. I might have time to add better zero padding code later. Anyway, this shouldn't be a big deal for now.

 

File saving/naming:

 

All files saved to the new incremented TV#### folder.

 

The 3840x2160px placeholder image will be named: TV0288.jpg

 

The x9 2000x1600px images will be named: 01_TV_Mockup.jpg etc.

 

I wasn't sure if you needed to name them with the folder name as well? Such as 01_TV_Mockup_TV0288.jpg or similar?

 

Tested on a Mac in versions 2021, 2022 and 2023.

 

I think that's it... Let me know how you go!

 

/*
Save JPEG Versions from Templates v1-0.jsx
https://community.adobe.com/t5/photoshop-ecosystem-discussions/batch-replace-smart-objects-script-using-a-linked-file-for-multiple-files/m-p/13568165
v1.0 15th February 2023, Stephen Marsh

Notes:
* All 10 files must be open...
* The 'Placeholder_Screen.psb' should have been manually updated with the new content and saved.
* All of the 9 template files should have been automatically updated from the linked smart object placeholder.
* Run the script, it will create the new output folder and JPEG versions at 3840x2160px and 2000x1600px size.
*/

#target photoshop

    (function () {

        if (documents.length === 10) {

            try {

                // Save the "Placeholder_Screen.psb" document
                activeDocument = documents.getByName("Placeholder_Screen.psb");
                activeDocument.artLayers.add();
                activeDocument.activeLayer.name = "_T-E-M-P_";
                activeDocument.activeLayer.remove();
                activeDocument.save();

                // Save all open teplate docs
                for (var i = 0; i < documents.length; i++) {
                    activeDocument = documents[i];
                    activeDocument.artLayers.add();
                    activeDocument.activeLayer.name = "_T-E-M-P_";
                    activeDocument.activeLayer.remove();
                    activeDocument.save();
                }

                // Create the next folder
                var lastDirPath = Folder.selectDialog("Please select the last 'TV####' folder:", "~/Desktop/Batch Replace SO/Tests/Samsung TV Frame Art");
                if (lastDirPath === null) {
                    alert('Script cancelled!');
                    return;
                }

                var lastDigits = lastDirPath.name.replace(/TV0/, "");
                lastDigits = Number(lastDigits) + 1;
                var newDirName = "TV0" + lastDigits;
                var newDirPath = Folder(lastDirPath.parent);
                var newDir = Folder(decodeURI(newDirPath + "/" + newDirName));
                if (!newDir.exists) newDir.create();

                // Export the SO file at native 3840x2160px size
                var saveFileJPEG = new File(newDirPath + "/" + newDirName + "/" + newDirName + ".jpg");
                SaveForWeb(saveFileJPEG);
                activeDocument.close(SaveOptions.DONOTSAVECHANGES);

                // Loop over the open template files and save 2000x1600px JPEG versions to the same folder
                while (app.documents.length > 0) {
                    var origUnits = app.preferences.rulerUnits;
                    app.preferences.rulerUnits = Units.PIXELS;
                    var docName = activeDocument.name.replace(/\.[^\.]+$/, '');
                    activeDocument.resizeImage(2000, null, null, ResampleMethod.BICUBIC);
                    var saveFileJPEG = new File(newDirPath + "/" + newDirName + "/" + docName + ".jpg");
                    SaveForWeb(saveFileJPEG);
                    activeDocument.close(SaveOptions.DONOTSAVECHANGES);
                    app.preferences.rulerUnits = origUnits;
                }

                // End of script
                app.beep();
                alert("JPEG files saved to:" + "\r" + newDirPath.fsName + "/" + newDirName);
                var openDir = Folder(newDirPath.fsName + "/" + newDirName);
                openDir.execute();

            } catch (e) {
                alert("The file 'Placeholder_Screen.psb' isn't open!");
            }

        } else {
            alert("Only the 10 required template/placeholder files should be open!");
        }

    }());


///// Functions /////

function SaveForWeb(saveFileJPEG) {
    var sfwOptions = new ExportOptionsSaveForWeb();
    sfwOptions.format = SaveDocumentType.JPEG;
    sfwOptions.includeProfile = true;
    sfwOptions.interlaced = 0;
    sfwOptions.optimized = true;
    sfwOptions.quality = 70;
    app.activeDocument.exportDocument(saveFileJPEG, ExportType.SAVEFORWEB, sfwOptions);
}

 

https://prepression.blogspot.com/2017/11/downloading-and-installing-adobe-scripts.html

MasterCrod103
Participating Frequently
February 14, 2023

WOW you are a wizard Stephen!! This worked very well!!! I am super grateful for your work here seriously.

 

The only issue I ran into was that I noticed some of the files didn't export correctly. However I troubleshooted a bit and realized that when I open the files at the beginning, I have to open them one at a time in order. If I select all of them at once and open them, photoshop opens them in a random order, which then throws off the export phase of the script. Very interesting.

 

In regards to the closing of the files and the loop after the script ends, I did see some scripts online I thought that were able to keep the files open? Again, I don't know much about scripts so I hope I don't sound like a total loser lol.

 

The file names look great by the way. I don't rename any of the files except for the smart object export, but I see that it gets renamed to the same name as the folder like you said which is amazing. The only main area of improvement is the loop function. But again I know nothing about that. I wish I could contribute more!

Stephen Marsh
Brainiac
February 15, 2023

The current script could re-open all 10 files again after they are closed, it is just inefficient! Closing the files is a hack to work around the issue I'm having with the for loop over open docs. So yeah, looping over the open docs is killing me! I usually loop over a folder of files or layers etc, not over open docs... I must be missing something basic.

Earth Oliver
Brainiac
February 13, 2023

Also, this might be helpful for you:

https://mockcity.com/

Earth Oliver
Brainiac
February 13, 2023

One way you can automate some of this is to stack all the reference images as layers inside the reference .psb, then create layer comps for each layer visibility. From there, you can place that master linked .psb into your mockups and use the properties panel to change the layer comp visibility in you mockups. Linked smart object layer comps is a largely untapped and extremely usesful workflow in Ps. If you can wrap your head around what's going on, you'll unlock all sorts of uses.

MasterCrod103
Participating Frequently
February 14, 2023

Hey thank you for the information and the link! That is really cool and I didn't know anything about that until you posted it. Thanks for that! I'm gonna definitely have to look into that.

Stephen Marsh
Brainiac
February 8, 2023

Sample files and before/after screenshots would be helpful.

MasterCrod103
Participating Frequently
February 8, 2023

Yes definitely. So here are my template files. Every single one is linked to the .psb smart object file (at the bottom).

 

I open them up, then place my image into the .psb smart object file and save it which then updates all of the photoshop template files. You can see all my files open at the top.

 

 

I would then like to export these files into their respective folder. All my images have a numbered folder.

 

The final result is all of the photoshop files exported at 2000 x 1600 px with the new image. The .psb smart object file is itself exported at full-scale high quality which is 4k (3840x2160px). I currently do this all manually. Image processor helps but if I could place all my different images in the psb file and it shoots out all of the exports for each different image and its respective mockups into their own folders, that would literally cut my time by like 90%.

Stephen Marsh
Brainiac
February 9, 2023

Thanks, the actual PSD/PSB sample files are needed for at least 2-3 mockup files and the linked placeholder. You can redact/sanitise content and or consistently resize them smaller if you like. Without knowing the layer structure and whether it is consistent from PSD file to PSD file, attempts at automation are likely a waste of time.