Script - stack images from folder + text from excel sheet

Guest
Mar 11, 2017 Mar 11, 2017

Copy link to clipboard

Copied

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

TOPICS
Actions and scripting

Views

1.4K

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Mar 11, 2017 Mar 11, 2017

Copy link to clipboard

Copied

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

Working with Variables in Photoshop - YouTube

Creating data-driven graphics in Photoshop

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Mar 11, 2017 Mar 11, 2017

Copy link to clipboard

Copied

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. 😄 😄

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Mar 12, 2017 Mar 12, 2017

Copy link to clipboard

Copied

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.

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Mar 12, 2017 Mar 12, 2017

Copy link to clipboard

Copied

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. 🙂

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Jul 29, 2022 Jul 29, 2022

Copy link to clipboard

Copied

LATEST

But you haven't clarified HOW to use that built in functionality. An explanation would be more valuable than scoffing and saying "don't you know, it could be waaay easier..." and leaving it at that.

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Mar 11, 2017 Mar 11, 2017

Copy link to clipboard

Copied

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.

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guest
Mar 11, 2017 Mar 11, 2017

Copy link to clipboard

Copied

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

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Mar 11, 2017 Mar 11, 2017

Copy link to clipboard

Copied

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?

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guest
Mar 11, 2017 Mar 11, 2017

Copy link to clipboard

Copied

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).

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Mar 11, 2017 Mar 11, 2017

Copy link to clipboard

Copied

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

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guest
Mar 11, 2017 Mar 11, 2017

Copy link to clipboard

Copied

Yes, you get it!

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Mar 11, 2017 Mar 11, 2017

Copy link to clipboard

Copied

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

I might have something usable for tomorrow.

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guest
Mar 11, 2017 Mar 11, 2017

Copy link to clipboard

Copied

Oh thanks Tomas, that is very sweet of you!

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Mar 12, 2017 Mar 12, 2017

Copy link to clipboard

Copied

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;

                // 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);

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

    }

})();

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Mar 12, 2017 Mar 12, 2017

Copy link to clipboard

Copied

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.

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Mar 12, 2017 Mar 12, 2017

Copy link to clipboard

Copied

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;

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

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

    }

})();

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guest
Mar 12, 2017 Mar 12, 2017

Copy link to clipboard

Copied

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

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Mar 12, 2017 Mar 12, 2017

Copy link to clipboard

Copied

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.

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guest
Mar 12, 2017 Mar 12, 2017

Copy link to clipboard

Copied

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..

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Jan 21, 2018 Jan 21, 2018

Copy link to clipboard

Copied

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

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jan 21, 2018 Jan 21, 2018

Copy link to clipboard

Copied

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

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Mar 12, 2017 Mar 12, 2017

Copy link to clipboard

Copied

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 😉

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jan 21, 2018 Jan 21, 2018

Copy link to clipboard

Copied

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

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Mar 12, 2017 Mar 12, 2017

Copy link to clipboard

Copied

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.

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines