Skip to main content
mirza5313
Known Participant
May 14, 2017
Question

Action script that could automate quote placement via csv file?

  • May 14, 2017
  • 3 replies
  • 4814 views

I have a PSD template where I just paste in the quote and author name and save for web, but this is obviously a boring job. Is there any way to automate this process via action or scripting?

I just tried many ways to automate since i have about 100s of quotes to place on template but not find any clues how to do this via scripting... please help me in this regards...
I have a csv file for quotes and Photoshop template
HERE!!!

Thank you in advance...

This topic has been closed for replies.

3 replies

Kukurykus
Legend
February 5, 2018

I downloaded psd and csv you attached to your first post and tried to use my newest script with them. It was not designed for short 1-line texts, but much bigger with many paragraphs. Anyway I added some part to script that now it makes a loop over slogans & authors from .cvs file, then paste it to text layers and use algorithm from my script to fit it in text area as best as possible to save 28 separate .psd files in subfolder. I didn't have your font so tried with others. With some it works better with others worse, but accuracy is about 85%, so you had a little to change manually font size in about two - six of them:

function font(v1, v2) {

     if (v2 != false) rH = v2 ? v1 * prc = ~~(hgt / (sal = (v1 * tI.autoLeadingAmount / 100))) * sal / hgt : (prc = 1, v1);

     (ref1 = new ActionReference()).putProperty(sTT('property'), sTT(S = ((f = v2 == false) ? 'paragraph' : 'text' ) + 'Style'))

     ref1.putEnumerated(sTT('textLayer'), sTT('ordinal'), sTT('targetEnum')), (dsc1 = new ActionDescriptor()).putReference(sTT('null'), ref1);

     (dsc2 = new ActionDescriptor()).putInteger(sTT('textOverrideFeatureName'), 808460000 + (f ? 4692 : (5400 + (v1 ? 58 : 62))))

     if (!f) {

          dsc2.putInteger(sTT('typeStyleOperationType'), 3), v1 ? dsc2.putUnitDouble(sTT('size'), sTT('pointsUnit'), rH) : dsc2.putBoolean(sTT('autoLeading'), true)

     }

     else {

          dsc2.putDouble(sTT('autoLeadingPercentage'), ~~v1 / 100); for(n = !(i = 0); i < (wlg = ['Word', 'Letter', 'Glyph']).length; i++) {

               for(j = 0; j < (mdm = ['Minimum', 'Desired', 'Maximum']).length; j++) dsc2.putDouble(sTT('justification' + wlg + mdm), !!n); n--

          }

     }

     dsc1.putObject(sTT('to'), sTT(S), dsc2), executeAction(sTT('set'), dsc1, DialogModes.NO); if (v2 != false) return rH

}

function sTT(v) {return stringIDToTypeID(v)} displayDialogs = DialogModes.NO, preferences.typeUnits = TypeUnits.POINTS;

(fle = File(Folder.desktop + '/Quotes.csv')).open('r'), lns = fle.read().split('\n'), fle.close(), Folder(pth = fle.path + '/Slogans').create()

for(z = 0; z < lns.length; z++) {

     QaA = eval(lns.replace(/"(.*)",(.*)/g, '["$1", "$2"]')); (tI = (aL = (lyr = (aD = activeDocument).layers)[0]).textItem).contents = QaA[0]

     lyr[1].textItem.contents = QaA[1], font((wh = [tI.width, tI.height])[Math.abs(+!~~(wh[0] / wh[1]) - 1)] / tI.size * tI.size.as('px') * 1.125)

     font((hgt = tI.height / 72 * (res = aD.resolution)) / (sa = (font(tI.size / Math.sqrt(tI.contents.length/ (function() {return tI.hyphenation = false, font(50, false),

     arr = [], tI.contents = txt = tI.contents.replace(/\r/g, function(_, v) {return arr.push(v), ' '}), font(), aHS = aD.activeHistoryState, tI.kind = TextType.POINTTEXT,

     len = tI.contents.length, aD.activeHistoryState = aHS, len})()))) * (aLA = tI.autoLeadingAmount) / 100) / (((b = aL.bounds)[3] - b[1] ) / sa) * aLA / 72 * res * prc, false)

     i = 0; tI.contents =  txt.replace(/ /g, function(_, v) {return v == arr ? (i++, '\r' ) : ' '}) font(tI.size * Math.sqrt((r = hgt / (tI.size * tI.autoLeadingAmount / 100)) / (r + i)), true)

     font(tI.autoLeadingAmount * (!((function(){return len1 = tI.contents.length, aHS = aD.activeHistoryState, tI.kind = TextType.POINTTEXT, r = tI.contents.match(/\r|$/g).length,

     R = (con = len1 != len2 = tI.contents.length) ? tI.contents.match(/(.*)(?=\r+$)/)[1].length - 1 : (hgt / 72 * res) / (tI.size.as('px') * (tI.autoLeadingAmount / 100) * r),

     aD.activeHistoryState = aHS, con})()) ? R : ((put = tI.contents.slice(R).match(/\r/g)) ? r / (r + put.length + 1) : len2 / len1)), false), aD.saveAs(File(pth + '/' + (z + 1)))

}

Original code without changed values (that works for bigger texts): How to make text fit inside a paragraph bounding box

Stephen Marsh
Community Expert
Community Expert
May 15, 2017

Hi mirza5313, perhaps the example downloads in this old topic on Photoshop variables will help:

Re: Data-driven grahics

EDIT: Here is a quick visual:

This could be a two step process, the first step is to create the layered data set export. The next step would be to create the final PNG or other assets using the image processor pro script, which is running an action for the vertical alignment of the text and re-save the PSD. Easier to do than it sounds!

mirza5313
mirza5313Author
Known Participant
May 19, 2017

Sorry for delay, I have tried every thing but csv file is not seems working? 

JJMack
Community Expert
Community Expert
May 14, 2017

Check out Photoshop's Data Driven Graphics feature. You need to define Photoshop variables for the text layers in your template document and create the CSV file to relate the text data to the variables.

JJMack
mirza5313
mirza5313Author
Known Participant
May 14, 2017

Ok, I just tried to make data driven graphics option but when upload csv file there is error message popup please see attached?

also this will work on Photoshop action to automate this process?

JJMack
Community Expert
Community Expert
May 14, 2017

Seems the process does not like your CSV file does the first row identify the template layers variable names?

JJMack