Skip to main content
Participant
August 19, 2022
Question

Batch Creating Mock ups using Scripts

  • August 19, 2022
  • 2 replies
  • 556 views

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
};

 

This topic has been closed for replies.

2 replies

c.pfaffenbichler
Community Expert
Community Expert
August 20, 2022

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;
    };
c.pfaffenbichler
Community Expert
Community Expert
August 20, 2022

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? 

https://community.adobe.com/t5/photoshop-ecosystem-discussions/batch-mockup-multiple-dimensions/m-p/12145263#M557684

Participant
August 20, 2022

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. 

c.pfaffenbichler
Community Expert
Community Expert
August 20, 2022

"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?