Copy link to clipboard
Copied
Hi
I am trying to use a script to automate mock up production and I cant get it to work correctly. I think this is potentially because the script isnt quite right for my mock up files, but I dont know how to change it.
I have a mock up file that has the mock up as a smart object with a layer mask. So normally I click on the this layer, a new layer window pops up, I place embed the image, save and close the layer and its in the mock up in the correct size etc.
When I use the script below - it puts the image directly into the smart object (ignoring the layer mask part) so the image is the wrong size in the mock up frame.
Do I need to change the script, or add in more code? (I have no clue how) or is the problem my mock up file set up?
Any advice greatfully received!
/ Replace SmartObject’s Content and Save as JPG // 2017, use it at your own risk // Via @Circle B: https://graphicdesign.stackexchange.com/questions/92796/replacing-a-smart-object-in-bulk-with-photoshops-variable-data-or-scripts/93359 // JPG code from here: https://forums.adobe.com/thread/737789 #target photoshop if (app.documents.length > 0) { var myDocument = app.activeDocument; var theName = myDocument.name.match(/(.*)\.[^\.]+$/)[1]; var thePath = myDocument.path; var theLayer = myDocument.activeLayer; // JPG Options; jpgSaveOptions = new JPEGSaveOptions(); jpgSaveOptions.embedColorProfile = true; jpgSaveOptions.formatOptions = FormatOptions.STANDARDBASELINE; jpgSaveOptions.matte = MatteType.NONE; jpgSaveOptions.quality = 11; // Check if layer is SmartObject; if (theLayer.kind != "LayerKind.SMARTOBJECT") { alert("selected layer is not a smart object") } else { // Select Files; if ($.os.search(/windows/i) != -1) { var theFiles = File.openDialog("please select files", "*.psd;*.tif;*.jpg", true) } else { var theFiles = File.openDialog("please select files", getFiles, true) }; if (theFiles) { for (var m = 0; m < theFiles.length; m++) { // Replace SmartObject theLayer = replaceContents(theFiles[m], theLayer); var theNewName = theFiles[m].name.match(/(.*)\.[^\.]+$/)[1]; // Save JPG myDocument.saveAs((new File(thePath + "/" + theNewName + ".jpg")), jpgSaveOptions, true,Extension.LOWERCASE); } } } }; // Get PSDs, TIFs and JPGs from files function getFiles(theFile) { if (theFile.name.match(/\.(psd|tif|jpg)$/i) != null || theFile.constructor.name == "Folder") { return true }; }; // Replace SmartObject 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 };
Copy link to clipboard
Copied
Please provide a sample file (feel free to delete or blacken sensitive elements).
If you want to replace a Smart Object inside the Smart Object the code needs amending.
Have you done a search for replacing SO inside an SO?
Copy link to clipboard
Copied
Hi
This is what I have - this is blank mock up file
so when I add the image - I click on the smart object layer and it opens the second window- where I do place embed and then close and save that window and then the image appears in the frame in the correct proportions.
But when I run the script instead of the image the image is placed directly on smart layer so it fills it and I get this
"If you want to replace a Smart Object inside the Smart Object the code needs amending."
Is this what I am trying to do? There is only 1 smart object, but it has a layer mask linked to it? I am not sure I understand. Clearly I don't know what I am doing! I have only just discovered that scripts even exist, so a lot to learn! I will have a look at those threads you suggested to see if they help but appreciate any help you can give.
Copy link to clipboard
Copied
"If you want to replace a Smart Object inside the Smart Object the code needs amending."
Is this what I am trying to do?
Apparently no, you want to place a SO in the SO.
But why not work from the file you create anyway – the one with the SO inside the SO?
Copy link to clipboard
Copied
The Script you posted seems familiar to me …
Anyway, try this:
// 2022, use it at your own risk;
if (app.documents.length > 0) {
var myDocument = app.activeDocument;
var theName = myDocument.name.match(/(.*)\.[^\.]+$/)[1];
var thePath = myDocument.path;
var theLayer = myDocument.activeLayer;
// JPG Options;
jpgSaveOptions = new JPEGSaveOptions();
jpgSaveOptions.embedColorProfile = true;
jpgSaveOptions.formatOptions = FormatOptions.STANDARDBASELINE;
jpgSaveOptions.matte = MatteType.NONE;
jpgSaveOptions.quality = 11;
// Check if layer is SmartObject;
if (theLayer.kind != "LayerKind.SMARTOBJECT") {
alert("selected layer is not a smart object")
} else {
// Select Files;
if ($.os.search(/windows/i) != -1) {
var theFiles = File.openDialog("please select files", "*.psd;*.tif;*.jpg", true)
} else {
var theFiles = File.openDialog("please select files", getFiles, true)
};
if (theFiles) {
for (var m = 0; m < theFiles.length; m++) {
var theState = myDocument.activeHistoryState;
var theSO = openSmartObject ();
placeScaleRotateFile (theFiles[m], 0, 0, 100, 100, 0);
scaleToCanvasSize ();
theSO.close(SaveOptions.SAVECHANGES);
var theNewName = theFiles[m].name.match(/(.*)\.[^\.]+$/)[1];
// Save JPG
myDocument.saveAs((new File(thePath + "/" + theNewName + ".jpg")), jpgSaveOptions, true,Extension.LOWERCASE);
myDocument.activeHistoryState = theState;
}
}
}
};
// Get PSDs, TIFs and JPGs from files
function getFiles(theFile) {
if (theFile.name.match(/\.(psd|tif|jpg)$/i) != null || theFile.constructor.name == "Folder") {
return true
};
};
// Replace SmartObject 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
};
////// open smart object //////
function openSmartObject () {
var desc2 = new ActionDescriptor();
executeAction( stringIDToTypeID( "placedLayerEditContents" ), desc2, DialogModes.NO );
return activeDocument;
};
////// place //////
function placeScaleRotateFile (file, xOffset, yOffset, theXScale, theYScale, theAngle) {
// =======================================================
var desc5 = new ActionDescriptor();
desc5.putPath( charIDToTypeID( "null" ), new File( file ) );
desc5.putEnumerated( charIDToTypeID( "FTcs" ), idQCSt = charIDToTypeID( "QCSt" ), charIDToTypeID( "Qcsa" ) );
var idOfst = charIDToTypeID( "Ofst" );
var desc6 = new ActionDescriptor();
var idPxl = charIDToTypeID( "#Pxl" );
desc6.putUnitDouble( charIDToTypeID( "Hrzn" ), idPxl, xOffset );
desc6.putUnitDouble( charIDToTypeID( "Vrtc" ), idPxl, yOffset );
var idOfst = charIDToTypeID( "Ofst" );
desc5.putObject( idOfst, idOfst, desc6 );
var idPrc = charIDToTypeID( "#Prc" );
desc5.putUnitDouble( charIDToTypeID( "Wdth" ), idPrc, theYScale );
desc5.putUnitDouble( charIDToTypeID( "Hght" ), idPrc, theXScale );
desc5.putUnitDouble( charIDToTypeID( "Angl" ), charIDToTypeID( "#Ang" ),theAngle );
desc5.putBoolean( charIDToTypeID( "Lnkd" ), false );
executeAction( charIDToTypeID( "Plc " ), desc5, DialogModes.NO );
return app.activeDocument.activeLayer;
};
////// scale active layer to canvas dimensions //////
function scaleToCanvasSize () {
// scale smart object:
var originalRulerUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
var layerDesc = executeActionGet(ref);
var theBounds = layerDesc.getObjectValue(stringIDToTypeID('bounds'));
var theX = theBounds.getInteger(stringIDToTypeID('left'));
var theY = theBounds.getInteger(stringIDToTypeID('top'));
var theX2 = theBounds.getInteger(stringIDToTypeID('right'));
var theY2 = theBounds.getInteger(stringIDToTypeID('bottom'));
// determine the scale;
var theSOProp = activeDocument.width/activeDocument.height;
var theNewProp = (theX2 - theX)/(theY2 - theY);
if (theNewProp >= theSOProp) {var theScale = activeDocument.width / (theX2 - theX) * 100}
else {var theScale = activeDocument.height / (theY2 - theY) * 100};
// transform;
var desc23 = new ActionDescriptor();
var ref2 = new ActionReference();
ref2.putEnumerated( charIDToTypeID( "Lyr " ), charIDToTypeID( "Ordn" ), charIDToTypeID( "Trgt" ) );
desc23.putReference( charIDToTypeID( "null" ), ref2 );
var idOfst = charIDToTypeID( "Ofst" );
var desc24 = new ActionDescriptor();
var idPxl = charIDToTypeID( "#Pxl" );
desc24.putUnitDouble( charIDToTypeID( "Hrzn" ), idPxl, activeDocument.width/2 - (theX+(theX2-theX)/2) );
desc24.putUnitDouble( charIDToTypeID( "Vrtc" ), idPxl, activeDocument.height/2 - (theY+(theY2-theY)/2) );
desc23.putObject( idOfst, idOfst, desc24 );
var idPrc = charIDToTypeID( "#Prc" );
desc23.putUnitDouble( charIDToTypeID( "Wdth" ), idPrc, theScale );
desc23.putUnitDouble( charIDToTypeID( "Hght" ), idPrc, theScale );
desc23.putEnumerated( charIDToTypeID( "Intr" ), charIDToTypeID( "Intp" ), stringIDToTypeID( "bicubicAutomatic" ) );
desc23.putEnumerated( stringIDToTypeID( "freeTransformCenterState" ), stringIDToTypeID( "quadCenterState" ), stringIDToTypeID( "QCSAverage" ) );
// desc23.putBoolean( charIDToTypeID( "Cpy " ), true );
executeAction( charIDToTypeID( "Trnf" ), desc23, DialogModes.NO );
app.preferences.rulerUnits = originalRulerUnits;
};