Copy link to clipboard
Copied
Hi there,
I want to know if it's possible to import x-number of png images into a mockup template with a smart object and then all saved in jpgs? The following script is not working for me but it's probably close to what I need:
The script must do the following:
Search in folder for PNG files
Place the PNG image into the Smart Object (top center)
Save file as JPG into the source folder with the same name as the source file
For example:
Before the script
\Images\Image 1\PNG\Design1.png
\Images\Image 2\PNG\Design2.png
\Images\Image 3\PNG\Design3.png
\Images\Image 4\PNG\Design4.png
After the script
\Images\Image 1\PNG\Design1.png
\Images\Image 1\PNG\Mockup.jpg
\Images\Image 2\PNG\Design2.png
\Images\Image 2\PNG\Mockup.jpg
\Images\Image 3\PNG\Design3.png
\Images\Image 3\PNG\Mockup.jpg
\Images\Image 4\PNG\Design4.png
\Images\Image 4\PNG\Mockup.jpg
I hope this makes sense. I will appreciate if someone can give me an advise what is the best way to do that.
Kind regards,
Katt
Copy link to clipboard
Copied
My script would save Populated template as PSD you can adjust populated images and save out a PNG. You need to take care when you want to place is png image the transparent borders around an item. Place and Paste will most likely trim transparent borders to the subject item bounds. To prevent that when I create the PNG file a put a 1% opaque pixel in the top left and bottom right corners of the documents canvas. You will never see these pixels amt the will be not transparent borders the Photoshop will trim. If you do not have me scripts search for Photo Collage toolkit https://forums.adobe.com/search.jspa?q=Photo+Collage+toolkit
My scripts will not filter for PNG they will place in any type of image file from a source image folder. It would be easy to change the extension list to be png only.
To place in images in a particular groups in order requires you to rename the files with a sort order prefix which will not be included if you use file nams stamping on placed images.
My Batch Scripts will save PSD files and optionally also save a additional JPG version. The one image batch script will name save files with a name that reflects the template and image name. The Batch multi image script save files with the a name that reflect the template name a suffix number. The number is update 1 after a populated template is saved its a count of populated templates. Many of my scripts do not save a file instead the populated template copy will remain open in Photoshop layered to allow you the tweak the populated template and save out the files you want with the names you want.
Copy link to clipboard
Copied
// place png files in selected smart object and save jpg;
// 2018, use it at your own risk;
#target photoshop
if (app.documents.length > 0) {
var myDocument = app.activeDocument;
var basename = myDocument.name.match(/(.*)\.[^\.]+$/)[1];
//var thePath = myDocument.path;
var theLayer = myDocument.activeLayer;
// jpg options
var jpgopts = new JPEGSaveOptions();
jpgopts.embedProfile = true;
jpgopts.formatOptions = FormatOptions.STANDARDBASELINE;
jpgopts.matte = MatteType.NONE;
jpgopts.quality = 10;
// check if layer is smart object;
if (theLayer.kind != "LayerKind.SMARTOBJECT") {alert ("selected layer is not a smart object")}
else {
// select files;
var theFolder = Folder.selectDialog ("select folder");
var theFiles = retrievePngFiles (theFolder, []);
if (theFiles) {
// work through the array;
for (var m = 0; m < theFiles.length; m++) {
var thePath = File(theFiles
// open smart object;
var smartObject = openSmartObject (theLayer);
var theLayer2 = smartObject.activeLayer;
// place file and fit to convas;
var theNewOne = placeScaleRotateFile (theFiles
scaleLayerToFitCanvas ();
hideOthers ();
// close;
smartObject.close(SaveOptions.SAVECHANGES);
//save jpg;
myDocument.saveAs((new File(thePath+"/"+theFiles
// undo;
myDocument.activeHistoryState = myDocument.historyStates[myDocument.historyStates.length - 1];
}
}
}
};
////// get ong from subfolders //////
function retrievePngFiles (theFolder, theFiles) {
if (!theFiles) {var theFiles = []};
var theContent = theFolder.getFiles();
for (var n = 0; n < theContent.length; n++) {
var theObject = theContent
if (theObject.constructor.name == "Folder") {
theFiles = retrievePngFiles(theObject, theFiles)
};
if (theObject.name.slice(-4).match(/\.(png)$/i) ) {
theFiles.push(theObject)
}
};
return theFiles
};
////// place //////
function placeScaleRotateFile (file, xOffset, yOffset, theXScale, theYScale, theAngle) {
// =======================================================
var idPlc = charIDToTypeID( "Plc " );
var desc5 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
desc5.putPath( idnull, new File( file ) );
var idFTcs = charIDToTypeID( "FTcs" );
var idQCSt = charIDToTypeID( "QCSt" );
var idQcsa = charIDToTypeID( "Qcsa" );
desc5.putEnumerated( idFTcs, idQCSt, idQcsa );
var idOfst = charIDToTypeID( "Ofst" );
var desc6 = new ActionDescriptor();
var idHrzn = charIDToTypeID( "Hrzn" );
var idPxl = charIDToTypeID( "#Pxl" );
desc6.putUnitDouble( idHrzn, idPxl, xOffset );
var idVrtc = charIDToTypeID( "Vrtc" );
var idPxl = charIDToTypeID( "#Pxl" );
desc6.putUnitDouble( idVrtc, idPxl, yOffset );
var idOfst = charIDToTypeID( "Ofst" );
desc5.putObject( idOfst, idOfst, desc6 );
var idWdth = charIDToTypeID( "Wdth" );
var idPrc = charIDToTypeID( "#Prc" );
desc5.putUnitDouble( idWdth, idPrc, theYScale );
var idHght = charIDToTypeID( "Hght" );
var idPrc = charIDToTypeID( "#Prc" );
desc5.putUnitDouble( idHght, idPrc, theXScale );
var idAngl = charIDToTypeID( "Angl" );
var idAng = charIDToTypeID( "#Ang" );
desc5.putUnitDouble( idAngl, idAng,theAngle );
var idLnkd = charIDToTypeID( "Lnkd" );
desc5.putBoolean( idLnkd, true );
executeAction( idPlc, desc5, DialogModes.NO );
return app.activeDocument.activeLayer;
};
////// 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 );
};
////// open smart object //////
function openSmartObject (theLayer) {
if (theLayer.kind == "LayerKind.SMARTOBJECT") {
// =======================================================
var idplacedLayerEditContents = stringIDToTypeID( "placedLayerEditContents" );
var desc2 = new ActionDescriptor();
executeAction( idplacedLayerEditContents, desc2, DialogModes.NO );
};
return app.activeDocument
};
////// hide others //////
function hideOthers () {
// hide others;
// =======================================================
var idShw = charIDToTypeID( "Shw " );
var desc2 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var list1 = new ActionList();
var ref1 = new ActionReference();
var idLyr = charIDToTypeID( "Lyr " );
var idOrdn = charIDToTypeID( "Ordn" );
var idTrgt = charIDToTypeID( "Trgt" );
ref1.putEnumerated( idLyr, idOrdn, idTrgt );
list1.putReference( ref1 );
desc2.putList( idnull, list1 );
var idTglO = charIDToTypeID( "TglO" );
desc2.putBoolean( idTglO, true );
executeAction( idShw, desc2, DialogModes.NO );
};
Copy link to clipboard
Copied
Question I see that your script does not replace the current Smart object layer content instead it update the layers object opens and edits the object. It places in the png and scaled it to fit the object canvas and hides the other content in the object.
// open smart object;
var smartObject = openSmartObject (theLayer);
var theLayer2 = smartObject.activeLayer;
// place file and fit to convas;
var theNewOne = placeScaleRotateFile (theFiles
scaleLayerToFitCanvas ();
hideOthers ();
// close;
smartObject.close(SaveOptions.SAVECHANGES);
I think there may be some problems there. I have never tried to update a smart object layer because of what I though might happen. If the png image has a transparent borders I think place may trim these. Additionally the png's file aspect ratio may be different than the work document canvas's aspect ratio so when the place layer is fitted for the canvas size there may be a border because of the aspect ratio mismatch. Then there is this if the template's current smart object was a Placed file it may be a raw file or ai file the object may open in ACR or Illustrator not Photoshop. Are my concerns ill founded?
Copy link to clipboard
Copied
Additionally the png's file aspect ratio may be different than the work document canvas's aspect ratio so when the place layer is fitted for the canvas size there may be a border because of the aspect ratio mismatch.
The current SO is square, so Replace Contents to some file with another aspect Ratio might cause more issues with the Warp for example.
The Script places the png in the SO and scales to fit according to its longest side.
This seems to make the most sense to me considering that I don’t know if all designs will have the same aspect ratio.
Copy link to clipboard
Copied
Hi, I found your comment when i was searching for the solution of this problem.
I tried your script, but this error occured.
The smart object was selected when i ran this script, and i choosen the folder of PNGs file.
Could you please help me?
Thank you very much
Copy link to clipboard
Copied
The script works fine for me but I have one issue here - I need the png placed in the top center of the Smart Object, so if the image is shorter it will be still on top.
Copy link to clipboard
Copied
You can either include an additional Alignment step in the Script or try to change the line
layerY = ((docHeight*docRes/144) - (layerY+layerHeight/2));
to provide the result you want to achieve.
Copy link to clipboard
Copied
To be honest I have no idea how to do it. I don't know anything about scripting
Copy link to clipboard
Copied
Do your PNG files have transparent border?
Are all your PNG files the same size and resolution as the object in your mockup?
If your PNG has transparent borders these may be trimmed during place the smart object layer object size may not be the size of the PNG file canvas.
If your png files do not have the same aspect ratio as your mockup object when they are resize to fit the mockup object canvas size a border or two most like will be introduced. The resize to fit must be a constrained resize otherwise the image will distort.
If the png contains text if the png files is not the same size as the mockup object the resize text may not be acceptable.
It there is no transparent borders in your png files and all the png are the same size as the mockup object and the object type is associated with Photoshop I think the script will work for you,
Copy link to clipboard
Copied
To be honest I have no idea how to do it. I don't know anything about scripting
If you want to use Scripts you should familiarise yourself with Scripting basics.
You can insert this line but you should figure out where yourself:
activeDocument.activeLayer.translate(0, activeDocument.activeLayer.bounds[1] * (-1))
Copy link to clipboard
Copied
Thank you for your help regarding this script. I placed the lane and it works fine but a got an error on one of the mockups. I guess it is the problem with the file. I will do more tests with different mockups. Thanks again
Copy link to clipboard
Copied
If you need help trouble-shooting that issue please state the exact error message and provide the file.
Copy link to clipboard
Copied
Copy link to clipboard
Copied
Is a Smart Object selected when you run the Script?
Copy link to clipboard
Copied
Yes, it is. This error appears after the first image is placed onto the mockup.
Copy link to clipboard
Copied
The message state that »Edit Contents« cannot be run, most likely because the selected Layer is not a Smart Object.
Please post a screenshot at error-time including the Layers Panel.
Copy link to clipboard
Copied
You are right! For some reason it moves the selection to the layer under the SO. When I run the script if it's not selected the SO the script replies that the selected layer is not SO, therefore I can't run the script if it's on any other layer. Weird!
Copy link to clipboard
Copied
That does not seem to make sense as the Script includes no step to change the selected Layer in the containing document.
You could reselect the originally selected Layer with
myDocument.activeLayer = theLayer;
Copy link to clipboard
Copied
Please provide the image and the code you use at current.
Copy link to clipboard
Copied
I think I figured the issue out – setting back the HistoryState can result in changing the Layer selection.
Inserting
myDocument.activeLayer = theLayer;
after the HistoryState-line should address that.
Copy link to clipboard
Copied
I found that I must save the psd with the SO selected, otherwise the script resets the file and then the selected layer may be different, that's why I got the error. Tried several times with different mockups and it works great. Thanks again for your cooperation regarding this script
Copy link to clipboard
Copied
I found that I must save the psd with the SO selected
If that is workable for you so much the better.
Good to read it worked out for you.
Copy link to clipboard
Copied
The only "problem" I've got now is with the saved name because it contains both the PNG and the Mockup names. I tried to modify the line //save jpg; few times but I've got different results and not the one I want. The jpg file must take the mockup name only. Would you be able to help with this as I've got everything else but not this? Thanks
Copy link to clipboard
Copied
Without testing I guess you would have to change
myDocument.saveAs((new File(thePath+"/"+theFiles
to
myDocument.saveAs((new File(thePath+"/"+theFiles