Copy link to clipboard
Copied
I needed a Photoshop script to automate the process of inserting PNG files from fold_A = "C:\Users\Utente\Desktop\design" into the active smart object layer. The PNGs should fit proportionally, similar to Photopea's "Generate Mockups" feature (File --> Automate --> "Generate Mockups" with stretch option deselected).
The script should: Open the smart object layer. Insert the PNG, ensuring it fits proportionally (like dragging and dropping into a smart object in Photopea). Save the PSB file. Return to the main PSD file. Export the PSD as a JPG with quality 12 into fold_B = "C:\Users\Utente\Desktop\mockup" using the same name as the inserted PNG. The script should replace the previous PNG in the smart object with the new one, deleting the old PNG from the PSB. alert "FINITO" when finished.
I've tried various codes however the common problem I encounter with every code is that the png won't behave as when I open the smart object clicking on the thumbnail and manually drag and drop the png, which will automatically be fitted inside the canvas of the .psb file. All the codes I've tried will just overlay the png without taking in consideration the smart object dimensions (as if it just drag and drops inside the smart object layer without opening it and saving it)
Here's a video of the wanted outcome: https://streamable.com/5bveni
Images descriptions:
1)bbox of the smart object
2)how it should be inside of smart object (which is what happens when I open SO and drop the png manually)
The issue is that with this code is that the pngs will replace the smart object while they should replace the layer inside of the smart object:
// Create a new window
var win = new Window("dialog", "Process Images");
// Add input folder panel
var inputPanel = win.add("panel", undefined, "Input Folder");
inputPanel.alignment = "fill";
var inputFolderBtn = inputPanel.add("button", undefined, "Select Input Folder");
var inputFolderText = inputPanel.add("edittext", undefined, "");
inputFolderText.alignment = "fill";
inputFolderBtn.onClick = function() {
inputFolder = Folder.selectDialog("Select a folder with images to process:");
if (inputFolder) {
inputFolderText.text = inputFolder.fsName;
}
};
// Add output folder panel
var outputPanel = win.add("panel", undefined, "Output Folder");
outputPanel.alignment = "fill";
var outputFolderBtn = outputPanel.add("button", undefined, "Select Output Folder");
var outputFolderText = outputPanel.add("edittext", undefined, "");
outputFolderText.alignment = "fill";
outputFolderBtn.onClick = function() {
outputFolder = Folder.selectDialog("Select a folder to save the processed images:");
if (outputFolder) {
outputFolderText.text = outputFolder.fsName;
}
};
// Add mockup folder panel
var mockupPanel = win.add("panel", undefined, "Mockup Folder");
mockupPanel.alignment = "fill";
var mockupFolderBtn = mockupPanel.add("button", undefined, "Select Mockup Folder");
var mockupFolderText = mockupPanel.add("edittext", undefined, "");
mockupFolderText.alignment = "fill";
mockupFolderBtn.onClick = function() {
mockupFiles = File.openDialog("Select the PSD mockup files:", "PSD files:*.psd;*.psdt", true);
};
// Add process button
var processBtn = win.add("button", undefined, "Process Images");
processBtn.alignment = "center";
processBtn.onClick = function() {
if (inputFolder && outputFolder) {
// Process images
var imageFiles = inputFolder.getFiles(/\.(jpg|jpeg|png|gif|tiff|webp)$/i);
for (var m = 0; m < mockupFiles.length; m++) {
var mockup = app.open(mockupFiles[m]);
for (var i = 0; i < imageFiles.length; i++) {
processImage(imageFiles[i], mockupFiles[m]);
}
// Close the PSD mockup
mockup.close(SaveOptions.DONOTSAVECHANGES);
}
// Function to process each image
function processImage(imageFile, mockupFile) {
// Replace the Smart Object's content with the new image
var smartObjectLayer = mockup.layers[0]; // Adjust this if the Smart Object is not the first layer
var idplacedLayerReplaceContents = stringIDToTypeID("placedLayerReplaceContents");
var desc = new ActionDescriptor();
desc.putPath(charIDToTypeID("null"), new File(imageFile));
executeAction(idplacedLayerReplaceContents, desc, DialogModes.NO);
// Save the processed image
var outputFile = new File(outputFolder + "/" + mockupFile.displayName.replace(".psdt", "") + "_" + imageFile.name);
var saveOptions = new JPEGSaveOptions();
saveOptions.quality = 12;
mockup.saveAs(outputFile, saveOptions, true, Extension.LOWERCASE);
}
alert("Processing complete.");
} else {
alert("Please select input and output folders.");
}
};
// Function to process each image
function processImage(imageFile, mockup) {
// Replace the Smart Object's content with the new image
var smartObjectLayer = mockup.layers[0]; // Adjust this if the Smart Object is not the first layer
var idplacedLayerReplaceContents = stringIDToTypeID("placedLayerReplaceContents");
var desc = new ActionDescriptor();
desc.putPath(charIDToTypeID("null"), new File(imageFile));
executeAction(idplacedLayerReplaceContents, desc, DialogModes.NO);
// Save the processed image
var outputFile = new File(outputFolder + "/" + mockup.name + "_" + imageFile.name);
var saveOptions = new JPEGSaveOptions();
saveOptions.quality = 12;
mockup.saveAs(outputFile, saveOptions, true, Extension.LOWERCASE);
}
// Add exit button
var exitBtn = win.add("button", undefined, "Exit");
exitBtn.alignment = "center";
exitBtn.onClick = function() {
win.close();
};
Copy link to clipboard
Copied
These issues seem to have come up again and again … the following code actually does not exactly what you want but replaces the active Smart Object in any Smart Object called »Your Design Here« and scales it to the Canvas. So if you adapt your template accordingly it should work or, hopefully, at least provide a starting point.
// 2023, use it at your own risk;
if (app.documents.length > 0) {main()};
function main () {
try {
var originalRulerUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;
var myDocument = activeDocument;
var theName = myDocument.name.match(/(.*)\.[^\.]+$/)[1];
var thePath = myDocument.path;
var theFiles = selectFile (true);
var theLayers = collectLayersByName ("Your Design Here");
selectLayerByID(theLayers[0][2],false);
var theSO = openSmartObject();
app.runMenuItem(charIDToTypeID('FtOn'));
for (var m = 0; m < theFiles.length; m++) {
var thisOne = theFiles[m];
replaceContents (thisOne, theSO.activeLayer);
scaleLayerToFitCanvas ();
// save;
theSO.save();
activeDocument = myDocument;
saveJpg(thePath, theName, new File (thisOne).name.match(/(.*)\.[^\.]+$/)[1]);
activeDocument = theSO;
};
theSO.close();
app.preferences.rulerUnits = originalRulerUnits;
}
catch (e) {alert ("something is wrong")}
};
////// open smart object //////
function openSmartObject () {
var idplacedLayerEditContents = stringIDToTypeID( "placedLayerEditContents" );
var desc2 = new ActionDescriptor();
executeAction( idplacedLayerEditContents, desc2, DialogModes.NO );
return activeDocument;
};
////// replace contents //////
function replaceContents (newFile, theSO) {
app.activeDocument.activeLayer = theSO;
// =======================================================
var idplacedLayerReplaceContents = stringIDToTypeID( "placedLayerReplaceContents" );
var desc3 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
desc3.putPath( idnull, new File( newFile ) );
var idPgNm = charIDToTypeID( "PgNm" );
desc3.putInteger( idPgNm, 1 );
executeAction( idplacedLayerReplaceContents, desc3, DialogModes.NO );
return app.activeDocument.activeLayer
};
////// select files //////
function selectFile (multi) {
if (multi == true) {var theString = "please select files"}
else {var theString = "please select one file"};
if ($.os.search(/windows/i) != -1) {var theFiles = File.openDialog (theString, '*.jpg;*.tif;*.psd;*.pdf;*.ai', multi)}
else {var theFiles = File.openDialog (theString, getFiles, multi)};
////// filter files for mac //////
function getFiles (theFile) {
if (theFile.name.match(/\.(jpg|tif|psd|pdf|ai)$/i) || theFile.constructor.name == "Folder") {
return true
};
};
return theFiles
};
////// save a jpg //////
function saveJpg (thePath, theName, theNewName) {
// jpg options;
var jpegOptions = new JPEGSaveOptions();
jpegOptions.quality = 9;
jpegOptions.embedColorProfile = true;
jpegOptions.matte = MatteType.NONE;
//save jpg;
activeDocument.saveAs((new File(thePath+"/"+theName+"_"+theNewName+".jpg")),jpegOptions,true);
};
////// collect layers with certain name //////
function collectLayersByName (aName) {
// 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"));
// if group 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'));
if (theName == aName) {theLayers.push([theName, theIndex, theID])}
};
}
catch (e) {};
};
return theLayers
};
////// 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);
}
};
////// scale layer to fit canvas //////
function scaleLayerToFitCanvas () {
var ref = new ActionReference();
ref.putProperty (stringIDToTypeID ("property"), stringIDToTypeID ("bounds"));
ref.putEnumerated( charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
var layerDesc = executeActionGet(ref);
var theBounds = layerDesc.getObjectValue(stringIDToTypeID("bounds"));
var layerX = theBounds.getUnitDoubleValue(stringIDToTypeID("left"));
var layerY = theBounds.getUnitDoubleValue(stringIDToTypeID("top"));
var layerWidth = theBounds.getUnitDoubleValue(stringIDToTypeID("right"))-layerX;
var layerHeight = theBounds.getUnitDoubleValue(stringIDToTypeID("bottom"))-layerY;
var ref1 = new ActionReference();
ref1.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
var docDesc = executeActionGet(ref1);
var docWidth = docDesc.getUnitDoubleValue(stringIDToTypeID("width"));
var docHeight = docDesc.getUnitDoubleValue(stringIDToTypeID("height"));
var docRes = docDesc.getInteger(stringIDToTypeID("resolution"));
var scaleX = docWidth/layerWidth*docRes/72*100;
var scaleY = docHeight/layerHeight*docRes/72*100;
var theScale = Math.min(scaleX, scaleY);
layerX = ((docWidth*docRes/144) - (layerX+layerWidth/2));
layerY = ((docHeight*docRes/144) - (layerY+layerHeight/2));
// =======================================================
var idTrnf = charIDToTypeID( "Trnf" );
var desc24 = new ActionDescriptor();
// desc24.putEnumerated( charIDToTypeID( "FTcs" ), charIDToTypeID( "QCSt" ), charIDToTypeID( "Qcs0" ) );
desc24.putEnumerated( charIDToTypeID( "FTcs" ), charIDToTypeID( "QCSt" ), charIDToTypeID( "Qcsa" ) );
var idOfst = charIDToTypeID( "Ofst" );
var desc25 = new ActionDescriptor();
var idHrzn = charIDToTypeID( "Hrzn" );
var idPxl = charIDToTypeID( "#Pxl" );
desc25.putUnitDouble( idHrzn, idPxl, layerX);
var idVrtc = charIDToTypeID( "Vrtc" );
desc25.putUnitDouble( idVrtc, idPxl, layerY);
desc24.putObject( idOfst, idOfst, desc25 );
var idWdth = charIDToTypeID( "Wdth" );
var idPrc = charIDToTypeID( "#Prc" );
desc24.putUnitDouble( idWdth, idPrc, theScale );
var idHght = charIDToTypeID( "Hght" );
desc24.putUnitDouble( idHght, idPrc, theScale );
executeAction( idTrnf, desc24, DialogModes.NO );
};
Copy link to clipboard
Copied