26 Replies Latest reply on Jan 21, 2018 6:43 AM by Kukurykus

    Script - stack images from folder + text from excel sheet

    VictoriaEllis Level 1

      Hi everyone!

       

      I've been using photoshop for a while but it is the first time I want to use the script features. Thus, I'm a little bit confused...

      I've been searching among previous subjects but did not find any answer related to my issue.

       

      I want to do the following :

      > I have a folder with 100 pictures.

      > I have an excel sheet with 100 quotes (1 per row in the first column, from row 1 to 100).

      > I have a template.psd containing 4 layers (from foreground to background):

           - 1 for the quote from the excel sheet.

           - 1 for a static text which has to be on every picture.

           - 1 for a "filter" (black square with 50% as opacity, in order to make the background image darker).

           - 1 for the image from the folder (which has to be set as background).

      > I want to stack on the template the relevant picture and quote, from 1 to 100.

       

      I've been told that I could run a script that, from 1 to 100, takes the picture number x, quote number x, assign them at the right place in the template and export the result in a folder.

       

      However, as I am totally new to photoshop scripting, I really don't know where to start. Therefore, my questions are :

      > what should I write in my script so that it executes the actions I want to perform?

      > how to launch such a script?

       

      I really hope that you guys can help me with that!

       

      Victoria

        • 1. Re: Script - stack images from folder + text from excel sheet
          SuperMerlin Level 5

          You may not need a script, check out Data driven Variables.

           

          Working with Variables in Photoshop - YouTube

          Creating data-driven graphics in Photoshop

          1 person found this helpful
          • 2. Re: Script - stack images from folder + text from excel sheet
            Tomas Sinkunas Adobe Community Professional

            Hello Victoria.

            I could help you out, but for that I'd need your setup.

            Could you please upload some files that you are describing above? I dont want to go guessing if I get a correct setup as you have. So having your files would speed up process very much.

             

            Thank you.

            • 3. Re: Script - stack images from folder + text from excel sheet
              VictoriaEllis Level 1

              Hi Tomas!

               

              I don't know how to upload on the forum the files (excel and .psd) thus I will try to explain and join screenshots

               

              First, I'm not sure if this is relevant but I use a mac.

               

              The images I use are these kind of images :

              951 Landscape Pictures | Free HD Stock Photos | Unsplash

              I download them and store them in a folder.

               

              The quotes are stored in the first column of a excel document (the other columns contain other informations but I can erase them) as follow :

              excel.png

               

              As you can see, some of the quotes are longer or shorter than the average. Thus I would love that my script be able to adapt my template to these variations of the quote's length (like automatically line breaking or size-reducing).

               

              Here is a screenshot of my psd template :

              psd.png

              A few comments :

              > as you can see, it is squared. Thus, I'd like the images to adapt to this shape.

              > there are 4 layers :

                   - "Quote" (which has to be replaced by the ones in the excel sheet),

                   - "logo" (my name at the bottom of the template),

                   - "filtre" (a black square which has to make the background image look darker)

                   - and "image". it is a white square which has to be replaced by the images in the folder.

               

              As an output, I want the images to be stored as .png files in another folder. I would love if they could have a number as name. I would like to specify the first number, and that the script automatically raise this number by 1 for every following picture (example : if I choose "300", the first picture would be named 300.png, the following picture 301.png, and so on).

               

              I think these are all the informations I can provide you with...

              Do you see anything else I should tell you?

               

              Many thanks for your help, it really saves me!!

               

              Victoria

              • 4. Re: Script - stack images from folder + text from excel sheet
                Tomas Sinkunas Adobe Community Professional

                Ok, it all starts to fall together. That's nice.

                But what about images for the background? Do you want the script to pick random pictures from the folder you provide?

                • 5. Re: Script - stack images from folder + text from excel sheet
                  VictoriaEllis Level 1

                  No, I would like that the script takes the images in a certain order (because I try to get a link between the images and quotes).

                  Thus, the images are called in a certain way in the folder (like the first one is called "1", the second "2", and so on).

                  I assume that in that way, they are well sorted in the folder (I mean that "1" is on top of the folder, "2" follows, and so on).

                  • 6. Re: Script - stack images from folder + text from excel sheet
                    Tomas Sinkunas Adobe Community Professional

                    Aha, so First quote gets first image in the folder, second quote gets second image in the folder etc etc?

                    • 8. Re: Script - stack images from folder + text from excel sheet
                      Tomas Sinkunas Adobe Community Professional

                      Ok, this will take some time. So don't hold your breath:)

                      I might have something usable for tomorrow.

                      • 9. Re: Script - stack images from folder + text from excel sheet
                        VictoriaEllis Level 1

                        Oh thanks Tomas, that is very sweet of you!

                        • 10. Re: Script - stack images from folder + text from excel sheet
                          Jarda Bereza Level 4

                          SuperMerlin: It's always the same. Nobody care that there is buil-in and ready to use function right for this cases which reads data from excel and can generate images according data.

                           

                          Everybody wants spend several hours/days with writing custom difficult scripting even if they don't have experience with scripting.

                           

                          I don't get it. :-D :-D

                          • 11. Re: Script - stack images from folder + text from excel sheet
                            Tomas Sinkunas Adobe Community Professional

                            Jarda Bereza I don't think your comment helps anyone in this thread. If you don't feel like providing any help - that's your choice. I personally love scripting, so I just go and do that.

                            • 12. Re: Script - stack images from folder + text from excel sheet
                              Tomas Sinkunas Adobe Community Professional

                              Hi VictoriaEllis. I managed to build something, but there are some things to consider:

                              1. There's no way to vertically center-align text in Paragraph. You will have to tinker text layer manually, after the script is finished working.

                              2. You also have to save you Quotes spreadsheet file as CSV file with ; as a delimiter. If you use different delimiter, you have to update scripts quotesArray variable on line 154 (second argument). Also, script assumes your quotes are on first column. If not, then you have to set column number in quotesArray variable (third argument)

                              3. Script saves final files as PSD files, so you can go in and adjust TextLayers as you need;

                               

                              (function(){
                                  #target photoshop;
                              
                              
                                  var prefs = { // Create global object to store values
                                      templateFile : undefined,
                                      quotesFile : undefined,
                                      imagesFolder : undefined,
                                      outputFolder : undefined,
                                      saveNumber : undefined,
                                  }
                              
                              
                                  buildUI();
                              
                              
                                  function buildUI() {
                                      var txtWidth = 100;
                                      var inputSize = 226;
                                      var minSpace = 2;
                              
                              
                                      var win = new Window('dialog', "Queter");
                                          win.alignChildren = ["fill", "fill"];
                                          win.spacing = 5;
                              
                              
                                          win.grpTemplateFile = win.add("group");
                                          win.grpTemplateFile.spacing = minSpace;
                                          win.grpTemplateFile.stTemplateFile = win.grpTemplateFile.add('statictext', undefined, "Template File");
                                          win.grpTemplateFile.etTemplateFile = win.grpTemplateFile.add('edittext', undefined, ""); 
                                          win.grpTemplateFile.btnSelectTemplateFile = win.grpTemplateFile.add('button', undefined, "...");
                                          win.grpTemplateFile.stTemplateFile.preferredSize.width = txtWidth;
                                          win.grpTemplateFile.etTemplateFile.preferredSize.width = inputSize;
                              
                              
                                          win.grpTemplateFile.btnSelectTemplateFile.onClick = function () {
                                              var templateFile = selectFiles(false, "psd");
                                              if (templateFile === null) return;
                                              win.grpTemplateFile.etTemplateFile.text = File.decode(templateFile);
                                          }
                              
                              
                                          win.grpQuotesFile = win.add("group");
                                          win.grpQuotesFile.spacing = minSpace;
                                          win.grpQuotesFile.stQuotesFile = win.grpQuotesFile.add('statictext', undefined, "Quotes File");
                                          win.grpQuotesFile.etQuotesFile = win.grpQuotesFile.add('edittext', undefined, ""); 
                                          win.grpQuotesFile.btnSelectQuotesFile = win.grpQuotesFile.add('button', undefined, "...");
                                          win.grpQuotesFile.stQuotesFile.preferredSize.width = txtWidth;
                                          win.grpQuotesFile.etQuotesFile.preferredSize.width = inputSize;
                              
                              
                                          win.grpQuotesFile.btnSelectQuotesFile.onClick = function () {
                                              var quotesFile = selectFiles(false, "csv");
                                              if (quotesFile === null) return;
                                              win.grpQuotesFile.etQuotesFile.text = File.decode(quotesFile);
                                          }
                              
                              
                                          win.grpImagesFolder = win.add("group");
                                          win.grpImagesFolder.spacing = minSpace;
                                          win.grpImagesFolder.stImagesFolder = win.grpImagesFolder.add('statictext', undefined, "Images Folder");
                                          win.grpImagesFolder.etImagesFolder = win.grpImagesFolder.add('edittext', undefined, ""); 
                                          win.grpImagesFolder.btnSelectImagesFolder = win.grpImagesFolder.add('button', undefined, "...");
                                          win.grpImagesFolder.stImagesFolder.preferredSize.width = txtWidth;
                                          win.grpImagesFolder.etImagesFolder.preferredSize.width = inputSize;
                              
                              
                                          win.grpImagesFolder.btnSelectImagesFolder.onClick = function () {
                                              var imagesFolder = Folder.selectDialog("Select images folder");
                                              if (imagesFolder === null) return;
                                              win.grpImagesFolder.etImagesFolder.text = File.decode(imagesFolder);
                                          }
                              
                              
                                          win.grpOutputFolder = win.add("group");
                                          win.grpOutputFolder.spacing = minSpace;
                                          win.grpOutputFolder.stOutputFolder = win.grpOutputFolder.add('statictext', undefined, "Output Folder");
                                          win.grpOutputFolder.etOutputFolder = win.grpOutputFolder.add('edittext', undefined, ""); 
                                          win.grpOutputFolder.btnSelectOutputFolder = win.grpOutputFolder.add('button', undefined, "...");
                                          win.grpOutputFolder.stOutputFolder.preferredSize.width = txtWidth;
                                          win.grpOutputFolder.etOutputFolder.preferredSize.width = inputSize;
                              
                              
                                          win.grpOutputFolder.btnSelectOutputFolder.onClick = function () {
                                              var outputFolder = Folder.selectDialog("Select output folder");
                                              if (outputFolder === null) return;
                                              win.grpOutputFolder.etOutputFolder.text = File.decode(outputFolder);
                                          }
                              
                              
                                          win.grpSaveIndex = win.add("group");
                                          win.grpSaveIndex.spacing = minSpace;
                                          win.grpSaveIndex.stSaveNumber = win.grpSaveIndex.add('statictext', undefined, "Save Start #");
                                          win.grpSaveIndex.etSaveNumber = win.grpSaveIndex.add('edittext', undefined, 0); 
                                          win.grpSaveIndex.stSaveNumber.preferredSize.width = txtWidth;
                                          win.grpSaveIndex.etSaveNumber.preferredSize.width = inputSize;
                              
                              
                                          win.grpActionButtons = win.add("group");
                                          win.grpActionButtons.spacing = minSpace;
                                          win.grpActionButtons.margins.top = 20;
                                          win.grpActionButtons.alignChildren = ["fill", "fill"];
                                          win.grpActionButtons.btnCloseWindow = win.grpActionButtons.add('button',undefined, "Cancel");
                                          win.grpActionButtons.btnRunScript  = win.grpActionButtons.add('button',undefined, "Run Script");
                              
                              
                                          win.grpActionButtons.btnCloseWindow.onClick = function () {
                                              win.close();
                                          }
                              
                              
                                          win.grpActionButtons.btnRunScript.onClick = function () {
                                              if (!File(win.grpTemplateFile.etTemplateFile.text).exists) {
                                                  win.grpTemplateFile.etTemplateFile.active = true;
                                                  return alert("Please select Template File");
                                              } else if (!File(win.grpQuotesFile.etQuotesFile.text).exists) {
                                                  win.grpQuotesFile.etQuotesFile.active = true;
                                                  return alert("Please select Quotes File");
                                              } else if (!Folder(win.grpImagesFolder.etImagesFolder.text).exists) {
                                                  win.grpImagesFolder.etImagesFolder.active = true;
                                                  return alert("Please select Images Folder");
                                              } else if (!Folder(win.grpOutputFolder.etOutputFolder.text).exists) {
                                                  win.grpOutputFolder.etOutputFolder.active = true;
                                                  return alert("Please select Output Folder");
                                              } else if (isNaN(parseInt(win.grpSaveIndex.etSaveNumber.text)) || parseInt(win.grpSaveIndex.etSaveNumber) < 0) {
                                                  win.grpSaveIndex.etSaveNumber.active = true;
                                                  return alert("Please enter valid Save Start Number");
                                              }
                              
                              
                                              prefs.templateFile  = File(win.grpTemplateFile.etTemplateFile.text);
                                              prefs.quotesFile    = File(win.grpQuotesFile.etQuotesFile.text);
                                              prefs.imagesFolder  = Folder(win.grpImagesFolder.etImagesFolder.text);
                                              prefs.outputFolder  = Folder(win.grpOutputFolder.etOutputFolder.text);
                                              prefs.saveNumber    = parseInt(win.grpSaveIndex.etSaveNumber.text);
                              
                              
                                              win.close();
                              
                              
                                              main();
                                          }
                              
                              
                                      win.show();
                                  }
                              
                              
                                  function main() {
                                      try {
                                          // Move all quotes to an array;
                                          // Provide quotes File, delimiter and columnNumber
                                          var quotesArray = readQuotes(prefs.quotesFile, ";", 0);
                                         
                                          // Move all image file to an array
                                          var imagesArray = prefs.imagesFolder.getFiles(/\.(png|jpg|tif)$/i);
                              
                              
                                          // Establish For loop length
                                          var loopLength = quotesArray.length;
                                          if (loopLength < imagesArray)
                                              loopLength = imagesArray.length;
                              
                              
                              
                              
                                          var templateDoc = app.open(prefs.templateFile);           
                                          var quotesLayer = templateDoc.layers[0];
                                          var backgroundDoc,
                                              backgroundLayer,
                                              oldBackgroundLayer;
                              
                              
                                          for (var i = 0; i < loopLength; i ++) {
                                              if (quotesLayer.kind !== LayerKind.TEXT)
                                                  return;
                              
                              
                                              // Update text layer with new Quote
                                              quotesLayer.textItem.contents = quotesArray[i];
                              
                              
                                              // Remove old background layer from the document
                                              oldBackgroundLayer = templateDoc.artLayers.getByName("Image") ;
                                              if (oldBackgroundLayer)
                                                  oldBackgroundLayer.remove();
                              
                              
                                              // Open background Image file and copy first layer to template document
                                              backgroundDoc = app.open(imagesArray[i]);
                                              backgroundDoc.changeMode(ChangeMode.RGB);
                                              backgroundLayer = backgroundDoc.layers[0].duplicate(templateDoc, ElementPlacement.PLACEATEND);
                                              backgroundDoc.close(SaveOptions.DONOTSAVECHANGES);
                                              backgroundLayer.name = "Image";
                              
                              
                                              resizeLayer(backgroundLayer, templateDoc);
                                              centerLayerInCanvas(backgroundLayer, templateDoc);
                                             
                                              savePSD(File(prefs.outputFolder + "/" + (prefs.saveNumber + i) + ".psd"))
                                          }
                              
                              
                                          templateDoc.close(SaveOptions.DONOTSAVECHANGES);
                              
                              
                                          alert("Done");
                              
                              
                                      } catch (e) {
                                          alert(e.toString() + "\nLine: " + e.line.toString());
                                      }     
                                  }
                              
                              
                                  ////// Helper Functions
                                 
                                  function centerLayerInCanvas(layer, doc) {
                                      var layerCenterHor = Number(layer.bounds[2] - layer.bounds[0]) / 2;
                                      var layerCenterVer = Number(layer.bounds[3] - layer.bounds[1]) / 2;
                              
                              
                                      var dX = doc.width/2  - layerCenterHor - Number(layer.bounds[0]);
                                      var dY = doc.height/2 - layerCenterVer - Number(layer.bounds[1]);
                              
                              
                                      layer.translate(dX, dY);
                                  }
                              
                              
                                  function resizeLayer(layer, doc) {
                                      var percent = calculatePercent(layer, doc);
                                      layer.resize(percent, percent, AnchorPosition.MIDDLECENTER);
                                 
                                      function calculatePercent(layer, doc) {
                                          var layerWidth  = Number(layer.bounds[2] - layer.bounds[0]);
                                          var layerHeight = Number(layer.bounds[3] - layer.bounds[1]);
                              
                              
                                          return percent  = (doc.width / layerWidth > doc.height / layerHeight)
                                                          ? 100 * doc.width / layerWidth
                                                          : 100 * doc.height / layerHeight;
                                      }
                                  }
                              
                              
                                  function savePSD(saveFile) {
                                      var saveOptions = new PhotoshopSaveOptions();
                                          saveOptions.embedColorProfile = true;
                                          saveOptions.alphaChannels = true;
                                          saveOptions.layers = true;
                              
                              
                                      activeDocument.saveAs(saveFile, saveOptions, true, Extension.LOWERCASE);
                                  };
                              
                              
                                  function readQuotes(quotesFile, deliminator, columnNumber) {
                                      var fileContent = readFile(quotesFile),
                                          lines = fileContent.split(/\n|\r/),
                                          quotesArray = [],
                                          singleQuote = "";
                                     
                                      for (var i = 0, il = lines.length; i < il; i ++) {
                                          singleQuote = lines[i].split(deliminator)[columnNumber];
                                          if (singleQuote !== "")
                                              quotesArray.push(singleQuote);
                                      }
                              
                              
                                      return quotesArray;
                              
                              
                                      function readFile(file) {
                                          file.open('r');
                                          var fileContent = file.read();
                                          file.close();
                                          return fileContent;
                                      }
                                  }
                                 
                                  function selectFiles (multiSelect, extension) {
                                      var theString = "Please select file",
                                          theFiles;
                              
                              
                                      if ($.os.search(/windows/i) != -1)
                                          theFiles = File.openDialog(theString, "*." + extension, multiSelect);
                                      else
                                          theFiles = File.openDialog(theString, getFiles, multiSelect);
                              
                              
                                      function getFiles(theFile) {
                                          var re = new RegExp("\.(" + extension + ")$","i");
                                          if (theFile.name.match(re) || theFile.constructor.name == "Folder")
                                              return true
                                      }
                              
                              
                                      return theFiles;
                                  }
                              })();
                              
                              • 13. Re: Script - stack images from folder + text from excel sheet
                                Jarda Bereza Level 4

                                No Problem. It is your time. Not mine. I am just saying that you and many other people are doing something what Adobe already done. :-)

                                 

                                This would help somebody who wants save time which is not your case. But it could be handy for somebody else who will read this topic in future. :-)

                                • 14. Re: Script - stack images from folder + text from excel sheet
                                  Jarda Bereza Level 4

                                   

                                   

                                  1. There's no way to vertically center-align text in Paragraph. You will have to tinker text layer manually, after the script is finished working.

                                  You can convert paragraph text to "point" text. Line breaks will remain. This will change layer bounds and you can center layer itself. Then you can: 1) select all canvas 2) center layer to selection 3)deselect 4) save 5) do some undos before point 1 if needed

                                   

                                  If you work with artboards, you don't need selection.

                                  • 15. Re: Script - stack images from folder + text from excel sheet
                                    Tomas Sinkunas Adobe Community Professional

                                    Updated version of the script with some notes:

                                    1. First layer in template file has to be paragraph text and has to be the size of available space for text. Final quote is aligned based on paragraph center. Thanks to Jarda Bereza I didn't know one can convert POINTTEXT to PARAGRAPH text. Live and learn.

                                    2. You also have to save you Quotes spreadsheet file as CSV file with ; as a delimiter. If you use different delimiter, you have to update scripts quotesArray variable on line 159 (second argument). Also, script assumes your quotes are on first column. If not, then you have to set column number in quotesArray variable (third argument)

                                    3. Script saves final files as PSD files, so you can go in and adjust TextLayers as you need;

                                     

                                    function(){
                                        #target photoshop;
                                    
                                    
                                        var prefs = { // Create global object to store values
                                            templateFile : undefined,
                                            quotesFile : undefined,
                                            imagesFolder : undefined,
                                            outputFolder : undefined,
                                            saveNumber : undefined,
                                        }
                                    
                                    
                                        buildUI();
                                    
                                    
                                        function buildUI() {
                                            var txtWidth = 100;
                                            var inputSize = 226;
                                            var minSpace = 2;
                                    
                                    
                                            var win = new Window('dialog', "Queter");
                                                win.alignChildren = ["fill", "fill"];
                                                win.spacing = 5;
                                    
                                    
                                                win.grpTemplateFile = win.add("group");
                                                win.grpTemplateFile.spacing = minSpace;
                                                win.grpTemplateFile.stTemplateFile = win.grpTemplateFile.add('statictext', undefined, "Template File");
                                                win.grpTemplateFile.etTemplateFile = win.grpTemplateFile.add('edittext', undefined, ""); 
                                                win.grpTemplateFile.btnSelectTemplateFile = win.grpTemplateFile.add('button', undefined, "...");
                                                win.grpTemplateFile.stTemplateFile.preferredSize.width = txtWidth;
                                                win.grpTemplateFile.etTemplateFile.preferredSize.width = inputSize;
                                    
                                    
                                                win.grpTemplateFile.btnSelectTemplateFile.onClick = function () {
                                                    var templateFile = selectFiles(false, "psd");
                                                    if (templateFile === null) return;
                                                    win.grpTemplateFile.etTemplateFile.text = File.decode(templateFile);
                                                }
                                    
                                    
                                                win.grpQuotesFile = win.add("group");
                                                win.grpQuotesFile.spacing = minSpace;
                                                win.grpQuotesFile.stQuotesFile = win.grpQuotesFile.add('statictext', undefined, "Quotes File");
                                                win.grpQuotesFile.etQuotesFile = win.grpQuotesFile.add('edittext', undefined, ""); 
                                                win.grpQuotesFile.btnSelectQuotesFile = win.grpQuotesFile.add('button', undefined, "...");
                                                win.grpQuotesFile.stQuotesFile.preferredSize.width = txtWidth;
                                                win.grpQuotesFile.etQuotesFile.preferredSize.width = inputSize;
                                    
                                    
                                                win.grpQuotesFile.btnSelectQuotesFile.onClick = function () {
                                                    var quotesFile = selectFiles(false, "csv");
                                                    if (quotesFile === null) return;
                                                    win.grpQuotesFile.etQuotesFile.text = File.decode(quotesFile);
                                                }
                                    
                                    
                                                win.grpImagesFolder = win.add("group");
                                                win.grpImagesFolder.spacing = minSpace;
                                                win.grpImagesFolder.stImagesFolder = win.grpImagesFolder.add('statictext', undefined, "Images Folder");
                                                win.grpImagesFolder.etImagesFolder = win.grpImagesFolder.add('edittext', undefined, ""); 
                                                win.grpImagesFolder.btnSelectImagesFolder = win.grpImagesFolder.add('button', undefined, "...");
                                                win.grpImagesFolder.stImagesFolder.preferredSize.width = txtWidth;
                                                win.grpImagesFolder.etImagesFolder.preferredSize.width = inputSize;
                                    
                                    
                                                win.grpImagesFolder.btnSelectImagesFolder.onClick = function () {
                                                    var imagesFolder = Folder.selectDialog("Select images folder");
                                                    if (imagesFolder === null) return;
                                                    win.grpImagesFolder.etImagesFolder.text = File.decode(imagesFolder);
                                                }
                                    
                                    
                                                win.grpOutputFolder = win.add("group");
                                                win.grpOutputFolder.spacing = minSpace;
                                                win.grpOutputFolder.stOutputFolder = win.grpOutputFolder.add('statictext', undefined, "Output Folder");
                                                win.grpOutputFolder.etOutputFolder = win.grpOutputFolder.add('edittext', undefined, ""); 
                                                win.grpOutputFolder.btnSelectOutputFolder = win.grpOutputFolder.add('button', undefined, "...");
                                                win.grpOutputFolder.stOutputFolder.preferredSize.width = txtWidth;
                                                win.grpOutputFolder.etOutputFolder.preferredSize.width = inputSize;
                                    
                                    
                                                win.grpOutputFolder.btnSelectOutputFolder.onClick = function () {
                                                    var outputFolder = Folder.selectDialog("Select output folder");
                                                    if (outputFolder === null) return;
                                                    win.grpOutputFolder.etOutputFolder.text = File.decode(outputFolder);
                                                }
                                    
                                    
                                                win.grpSaveIndex = win.add("group");
                                                win.grpSaveIndex.spacing = minSpace;
                                                win.grpSaveIndex.stSaveNumber = win.grpSaveIndex.add('statictext', undefined, "Save Start #");
                                                win.grpSaveIndex.etSaveNumber = win.grpSaveIndex.add('edittext', undefined, 0); 
                                                win.grpSaveIndex.stSaveNumber.preferredSize.width = txtWidth;
                                                win.grpSaveIndex.etSaveNumber.preferredSize.width = inputSize;
                                    
                                    
                                                win.grpActionButtons = win.add("group");
                                                win.grpActionButtons.spacing = minSpace;
                                                win.grpActionButtons.margins.top = 20;
                                                win.grpActionButtons.alignChildren = ["fill", "fill"];
                                                win.grpActionButtons.btnCloseWindow = win.grpActionButtons.add('button',undefined, "Cancel");
                                                win.grpActionButtons.btnRunScript  = win.grpActionButtons.add('button',undefined, "Run Script");
                                    
                                    
                                                win.grpActionButtons.btnCloseWindow.onClick = function () {
                                                    win.close();
                                                }
                                    
                                    
                                                win.grpActionButtons.btnRunScript.onClick = function () {
                                                    if (!File(win.grpTemplateFile.etTemplateFile.text).exists) {
                                                        win.grpTemplateFile.etTemplateFile.active = true;
                                                        return alert("Please select Template File");
                                                    } else if (!File(win.grpQuotesFile.etQuotesFile.text).exists) {
                                                        win.grpQuotesFile.etQuotesFile.active = true;
                                                        return alert("Please select Quotes File");
                                                    } else if (!Folder(win.grpImagesFolder.etImagesFolder.text).exists) {
                                                        win.grpImagesFolder.etImagesFolder.active = true;
                                                        return alert("Please select Images Folder");
                                                    } else if (!Folder(win.grpOutputFolder.etOutputFolder.text).exists) {
                                                        win.grpOutputFolder.etOutputFolder.active = true;
                                                        return alert("Please select Output Folder");
                                                    } else if (isNaN(parseInt(win.grpSaveIndex.etSaveNumber.text)) || parseInt(win.grpSaveIndex.etSaveNumber) < 0) {
                                                        win.grpSaveIndex.etSaveNumber.active = true;
                                                        return alert("Please enter valid Save Start Number");
                                                    }
                                    
                                    
                                                    prefs.templateFile  = File(win.grpTemplateFile.etTemplateFile.text);
                                                    prefs.quotesFile    = File(win.grpQuotesFile.etQuotesFile.text);
                                                    prefs.imagesFolder  = Folder(win.grpImagesFolder.etImagesFolder.text);
                                                    prefs.outputFolder  = Folder(win.grpOutputFolder.etOutputFolder.text);
                                                    prefs.saveNumber    = parseInt(win.grpSaveIndex.etSaveNumber.text);
                                    
                                    
                                                    win.close();
                                    
                                    
                                                    main();
                                                }
                                    
                                    
                                            win.show();
                                        }
                                    
                                    
                                        function main() {
                                            try {
                                                // Change project unites to Pixels
                                                var originalUnits = app.preferences.rulerUnits;
                                                app.preferences.rulerUnits = Units.PIXELS;
                                    
                                    
                                                // Move all quotes to an array;
                                                // Provide quotes File, delimiter and columnNumber
                                                var quotesArray = readQuotes(prefs.quotesFile, ";", 0);
                                               
                                                // Move all image file to an array
                                                var imagesArray = prefs.imagesFolder.getFiles(/\.(png|jpg|tif)$/i);
                                    
                                    
                                                // Establish For loop length
                                                var loopLength = (quotesArray.length <= imagesArray.length) ? quotesArray.length : imagesArray.length;
                                    
                                    
                                                var templateDoc = app.open(prefs.templateFile);           
                                                var quotesLayer = templateDoc.layers[0];
                                                if (quotesLayer.kind !== LayerKind.TEXT || quotesLayer.textItem.kind !== TextType.PARAGRAPHTEXT)
                                                    return alert("First layer has to be Paragraph text.");
                                    
                                    
                                                // Store paragraph layer data
                                                var paragraphData = {
                                                    width : quotesLayer.textItem.width,
                                                    height : quotesLayer.textItem.height,
                                                    position : quotesLayer.textItem.position,
                                                    center : {
                                                        x : Number(quotesLayer.textItem.width/2 + quotesLayer.textItem.position[0]),
                                                        y : Number(quotesLayer.textItem.height/2 + quotesLayer.textItem.position[1])
                                                    }
                                                };
                                    
                                    
                                                var backgroundDoc, backgroundLayer, oldBackgroundLayer;
                                    
                                    
                                                for (var i = 0; i < loopLength; i ++) {
                                                    // Update text layer with new Quote
                                                    quotesLayer.textItem.contents = quotesArray[i];
                                                    quotesLayer.textItem.kind = TextType.POINTTEXT;
                                                    moveLayer(quotesLayer, paragraphData.center);
                                                    quotesLayer.textItem.kind = TextType.PARAGRAPHTEXT;
                                    
                                    
                                                    // Remove old background layer from the document
                                                    oldBackgroundLayer = templateDoc.artLayers.getByName("Image") ;
                                                    oldBackgroundLayer && oldBackgroundLayer.remove();
                                    
                                    
                                                    // Open background Image file and copy first layer to template document
                                                    backgroundDoc = app.open(imagesArray[i]);
                                                    backgroundDoc.changeMode(ChangeMode.RGB);
                                                    backgroundLayer = backgroundDoc.layers[0].duplicate(templateDoc, ElementPlacement.PLACEATEND);
                                                    backgroundDoc.close(SaveOptions.DONOTSAVECHANGES);
                                                    backgroundLayer.name = "Image";
                                    
                                    
                                                    resizeLayer(backgroundLayer, templateDoc);
                                                    moveLayer(backgroundLayer);
                                                   
                                                    savePSD(File(prefs.outputFolder + "/" + (prefs.saveNumber + i) + ".psd"));
                                    
                                    
                                                    // Restor original Paragraph layer data.
                                                    quotesLayer.textItem.width = paragraphData.width;
                                                    quotesLayer.textItem.height = paragraphData.height;
                                                    quotesLayer.textItem.position = paragraphData.position;
                                                }
                                    
                                    
                                                templateDoc.close(SaveOptions.DONOTSAVECHANGES);
                                    
                                    
                                                app.preferences.rulerUnits = originalUnits;
                                    
                                    
                                                alert("Done");
                                    
                                    
                                            } catch (e) {
                                                alert(e.toString() + "\nLine: " + e.line.toString());
                                            }     
                                        }
                                    
                                    
                                        ////// Helper Functions
                                       
                                        function moveLayer(layer, position) {
                                            position = position || {
                                                x : app.activeDocument.width/2,
                                                y : app.activeDocument.height/2
                                            };
                                    
                                    
                                            var layerCenterHor = Number(layer.bounds[2] - layer.bounds[0]) / 2;
                                            var layerCenterVer = Number(layer.bounds[3] - layer.bounds[1]) / 2;
                                    
                                    
                                            var dX = position.x - layerCenterHor - Number(layer.bounds[0]);
                                            var dY = position.y - layerCenterVer - Number(layer.bounds[1]);
                                    
                                    
                                            layer.translate(dX, dY);
                                        }
                                    
                                    
                                        function resizeLayer(layer, doc) {
                                            var percent = calculatePercent(layer, doc);
                                            layer.resize(percent, percent, AnchorPosition.MIDDLECENTER);
                                       
                                            function calculatePercent(layer, doc) {
                                                var layerWidth  = Number(layer.bounds[2] - layer.bounds[0]);
                                                var layerHeight = Number(layer.bounds[3] - layer.bounds[1]);
                                    
                                    
                                                return percent  = (doc.width / layerWidth > doc.height / layerHeight)
                                                                ? 100 * doc.width / layerWidth
                                                                : 100 * doc.height / layerHeight;
                                            }
                                        }
                                    
                                    
                                        function savePSD(saveFile) {
                                            var saveOptions = new PhotoshopSaveOptions();
                                                saveOptions.embedColorProfile = true;
                                                saveOptions.alphaChannels = true;
                                                saveOptions.layers = true;
                                    
                                    
                                            activeDocument.saveAs(saveFile, saveOptions, true, Extension.LOWERCASE);
                                        };
                                    
                                    
                                        function readQuotes(quotesFile, deliminator, columnNumber) {
                                            var fileContent = readFile(quotesFile),
                                                lines = fileContent.split(/\n|\r/),
                                                quotesArray = [],
                                                singleQuote = "";
                                           
                                            for (var i = 0, il = lines.length; i < il; i ++) {
                                                singleQuote = lines[i].split(deliminator)[columnNumber];
                                                if (singleQuote !== "")
                                                    quotesArray.push(singleQuote);
                                            }
                                    
                                    
                                            return quotesArray;
                                    
                                    
                                            function readFile(file) {
                                                file.open('r');
                                                var fileContent = file.read();
                                                file.close();
                                                return fileContent;
                                            }
                                        }
                                       
                                        function selectFiles (multiSelect, extension) {
                                            var theString = "Please select file",
                                                theFiles;
                                    
                                    
                                            if ($.os.search(/windows/i) != -1)
                                                theFiles = File.openDialog(theString, "*." + extension, multiSelect);
                                            else
                                                theFiles = File.openDialog(theString, getFiles, multiSelect);
                                    
                                    
                                            function getFiles(theFile) {
                                                var re = new RegExp("\.(" + extension + ")$","i");
                                                if (theFile.name.match(re) || theFile.constructor.name == "Folder")
                                                    return true
                                            }
                                    
                                    
                                            return theFiles;
                                        }
                                    })();
                                    
                                    • 16. Re: Script - stack images from folder + text from excel sheet
                                      Jarda Bereza Level 4

                                      If you convert paragraph to point text, there is possibility, that text which overflow frame will be removed. So make sure that your frame is enought big or catch these cases with script ;-)

                                      • 17. Re: Script - stack images from folder + text from excel sheet
                                        VictoriaEllis Level 1

                                        Hi guys!

                                         

                                        Thank you very much for your help and especially, thank a lot to Tomas! You may have spend a lot of time on that, I am really grateful, it saves me a lot!

                                        I tried to run the script but I am not sure about how it works.. I exported the script as a .js file and open it using file > scripts > browse, but it didn't work... I had the following message printing :

                                         

                                        Line: 2

                                        ->  <?mso-application progid="Word.Document"?>

                                         

                                        What did I do wrong?

                                         

                                        Once again, thanks a lot Tomas!!

                                         

                                        Victoria

                                        • 18. Re: Script - stack images from folder + text from excel sheet
                                          Tomas Sinkunas Adobe Community Professional

                                          That error sounds like your Quotes file is not CSV file.

                                          For script to work you need to export your file to CSV first, with ; as delimiter.

                                          • 19. Re: Script - stack images from folder + text from excel sheet
                                            VictoriaEllis Level 1

                                            This shown up before I selected the Excel file thus I don't think that this is related to the file not beeing a CSV..

                                            • 20. Re: Script - stack images from folder + text from excel sheet
                                              Jarda Bereza Level 4

                                              You shouldn't write script in Word. Use notepad instead ;-) And you need rename file extension from .txt to .jsx

                                              You maybe will need change settings to show extension.

                                              • 21. Re: Script - stack images from folder + text from excel sheet
                                                VictoriaEllis Level 1

                                                I exported the script using Webstorm editor as .jsx file, it didn't work too. Then I tried with .js file but it was not better.

                                                In both cases, it printed :

                                                 

                                                Ligne: 331

                                                ->  })(); 

                                                • 22. Re: Script - stack images from folder + text from excel sheet
                                                  _FLEX4U Level 1

                                                  these adobe charges of software a terrible

                                                  • 23. Re: Script - stack images from folder + text from excel sheet
                                                    mubashara78943322 Level 1

                                                    Hi Tomas! I got this error while I load your updated script on photoshop.

                                                     

                                                    "Error 23: ) does not have a value.

                                                    Line: 331 ->"

                                                     

                                                    This script does not load. I have Photoshop CC

                                                    • 24. Re: Script - stack images from folder + text from excel sheet
                                                      Kukurykus Adobe Community Professional

                                                      I had the same problem with other script converting paragraph to point. That cut some side text. I am not sure was that solution I found but probably I changed text composition from ADOBEEVERYLINE, when it was still PARAGRAPHTEXT to:

                                                       

                                                      (tI = activeDocument.activeLayer.textItem).textComposer = TextComposer.ADOBESINGLELINE, tI.kind = TextType.POINTTEXT
                                                      
                                                      • 25. Re: Script - stack images from folder + text from excel sheet
                                                        Kukurykus Adobe Community Professional

                                                        When you compare both version of code you'll notice there is lack of first character in second version code: (

                                                        • 26. Re: Script - stack images from folder + text from excel sheet
                                                          Kukurykus Adobe Community Professional

                                                          I think you may completely remove 1st and 331st lines or do like in previous post suggestion.