Illustrator script (or action) to make 1 random layer visible per group - adobe-illustrator

Similar to this question but with adobe Illustrator: Photoshop action to make 1 random layer visible within each group
I want to use an illustrator script (or action) to generate images that are composed of a random sampling of grouped layers.
With in each of the 12 groups, I want to make 1 layer per group visible.
Export the visible layers as an svg. Bonus points if I can change the file format.
Repeat the process n times
I know this is similar to the code linked above though I want to be able to use illustrator instead of photoshop if possible.

It could be something like this:
function main() {
var doc = app.activeDocument;
// hide all items
var i = doc.pageItems.length;
while(i--) doc.pageItems[i].hidden = true;
// show one random item on every layer
var i = doc.layers.length;
while(i--) {
var items = doc.layers[i].pageItems;
var index = Math.round(Math.random()*(items.length-1));
items[index].hidden = false;
}
// save svg
var counter = 0;
var file = File(Folder.desktop + '/' + counter + '.svg') ;
while (file.exists) {
file = File(Folder.desktop + '/' + counter++ + '.svg');
}
doc.exportFile(file, ExportType.SVG);
// save png
var counter = 0;
var file = File(Folder.desktop + '/' + counter + '.png') ;
while (file.exists) {
file = File(Folder.desktop + '/' + counter++ + '.png');
}
var options = new ExportOptionsPNG24();
options.artBoardClipping = true;
doc.exportFile(file, ExportType.PNG24, options);
}
// repeat the script N times
var n = 3;
while(n--) main();
It hides all the page items, shows one random item on every layer, and saves the document as SVG and PNG in the desktop folder.

Related

Adobe illustrator linked file name to a layer name script

I want the layer enter image description here
to have the name of the linked file without .eps at the end.
Anyway, I found an answer. So for anyone looking here it is, although it does take to click on every layer, at least you don't have to type it.
function test() {
var sel_itemPlaced = app.activeDocument.selection[0]; // be sure that a linked item (and not an embedded) is selected
var fileName = sel_itemPlaced.file.name;
var textContents = fileName.replace(/\%20/g, " "); //change %20 to spaces
textContents = textContents.replace(/\.[^\.]*$/, ""); //remove extension
var _item = sel_itemPlaced;
while (_item.parent.typename != 'Layer') {
_item = _item.parent;
}
_item.parent.name = textContents;
}
test();
It does work for all placed images and all layers at once:
var images = app.activeDocument.placedItems;
for (var i=0; i<images.length; i++)
images[i].layer.name = images[i].file.name.replace(/\.[^\.]+$/, "");

Automating Photoshop to edit en rename +600 files with the name of the folder

I have +600 product images on my mac already cut out and catalogued in their own folder. They are all PSD's and I need a script that will do the following.
Grab the name of the folder
Grab all the PSD's in said folder
Combine them in one big PSD in the right order (the filenames are saved sequentially as 1843, 1845, 1846 so they need to open in that order)
save that PSD
save the separate layers as PNG with the name from the folder + _1, _2, _3
I have previous experience in Bash (former Linux user) and tried for hours in Automator but to no success.
Welcome to Stack Overflow. The quick answer is yes this is possible to do via scripting. I might even suggest breaking down into two scripts, one to grab and save the PSDs and the second to save out the layers.
It's not very clear about "combining" the PSDs or about "separate layers, only I don't know if they are different canvas sizes, where you want each PSD to be positioned (x, y offsets & layering) Remember none of use have your files infront of us to refer from.
In short, if you write out pseudo code of what is it you expect your code to do it makes it easier to answer your question.
Here's a few code snippets to get you started:
This will open a folder and retrieve alls the PSDs as an array:
// get all the files to process
var folderIn = Folder.selectDialog("Please select folder to process");
if (folderIn != null)
{
var tempFileList = folderIn.getFiles();
}
var fileList = new Array(); // real list to hold images, not folders
for (var i = 0; i < tempFileList.length; i++)
{
// get the psd extension
var ext = tempFileList[i].toString();
ext = ext.substring(ext.lastIndexOf("."), ext.length);
if (tempFileList[i] instanceof File)
{
if (ext == ".psd") fileList.push (tempFileList[i]);
// else (alert("Ignoring " + tempFileList[i]))
}
}
alert("Files:\n" + fileList.length);
You can save a png with this
function save_png(afilePath)
{
// Save as a png
var pngFile = new File(afilePath);
pngSaveOptions = new PNGSaveOptions();
pngSaveOptions.embedColorProfile = true;
pngSaveOptions.formatOptions = FormatOptions.STANDARDBASELINE;
pngSaveOptions.matte = MatteType.NONE; pngSaveOptions.quality = 1;
activeDocument.saveAs(pngFile, pngSaveOptions, false, Extension.LOWERCASE);
}
To open a psd just use
app.open(fileRef);
To save it
function savePSD(afilePath)
{
// save out psd
var psdFile = new File(afilePath);
psdSaveOptions = new PhotoshopSaveOptions();
psdSaveOptions.embedColorProfile = true;
psdSaveOptions.alphaChannels = true;
activeDocument.saveAs(psdFile, psdSaveOptions, false, Extension.LOWERCASE);
}

How to name tabs in pdf export to xls

I have a PDF form that has many form fields. My requirement is to export the form data (some of it anyway) into an excel (xls) format on a network drive that is being picked up and used by another process (that I do not have access or code to change) to load into a database using Acrobat Javascript when a button on the PDF is clicked. As this is a distributed form and the network drive is common, it did not make sense to setup ODBC connections to the database nor did I have access to do so.
The issues I am having are:
I need to specifically name the Worksheet so that the process correctly processes the xls file.
I need to save the information to the network drive without prompting the user, which the code below does.
The fieldNames seem to be losing spaces when they export to xls.
So far nothing I tried has worked nor do any of the references I have gone though provide such information. I can push data into a .csv and .txt files and have tried creating a new Report something like the following:
var rep = new Report();
var values = "";
...
rep.writeText(values);
var docRep = rep.open("myreport.pdf");
docRep.saveAs("/c/temp/Upload.txt","com.adobe.acrobat.plain-text")
docRep.closeDoc(true);
app.alert("Upload File Saved", 3);
but it only allows the .txt extension not the xls or csv extension. I managed to export the csv in another way.
Below is a small snippet of my code:
var fieldNames = [];
var result ="";
fieldNames.push("Inn Code");
fieldValues.push('"' + this.getField("Hotel Info Inn Code").value + '"');
fieldNames.push("Business Unit");
fieldValues.push('"' + this.getField("Hotel Info Business Unit").value + '"');
for ( var i=0; i < fieldNames.length; i++ ) {
result += (fieldNames[i] + "\t");
}
for ( var i=0; i < fieldValues.length; i++ ) {
result += (fieldValues[i] + "\t");
}
this.createDataObject({cName: "Upload.xls", cValue: cMyC});
this.exportDataObject({cName: "Upload.xls", nLaunch: 0});
Any help or suggestions provided would be greatly appreciated!
Update (For anyone else who encounters this need).
I determined that the tab name using the method above is the same as the save name. The other issue I encountered was that the xls file was really a csv with an xls extension. To resolve this I decided to export an csv I am formatting or a text file and an external process to reformat the file as an xls.
var fieldNames = [];
var fieldValues = [];
var result = '';
// FIELD VALUES
fieldNames.push('"Column Name 1"');
fieldValues.push('\r\n' + '"' + this.getField("Field Name 1").value + '"');
fieldNames.push('"Column Name 2"');
fieldValues.push('"' + this.getField("Field Name 2").value + '"');
for ( var i=0; i < fieldNames.length; i++ ) {
if (i != fieldNames.length-1){
result += (fieldNames[i] + ",");
} else {
result += (fieldNames[i]);
}
}
for ( var i=0; i < fieldValues.length; i++ ) {
if (i != fieldValues.length-1){
result += (fieldValues[i] + ",");
} else {
result += (fieldValues[i]);
}
}
I used the following to output a csv file:
this.createDataObject('UploadFile.csv', result);
this.exportDataObject({ cName:'UploadFile.csv', nLaunch:'0'});
The issue is that this prompts the user where to save the file and I wanted a silent specific location so I wound up doing the following in place of the create and export object above to output a txt file silently without prompting the user:
var rep = new Report();
rep.writeText(result);
var docRep = rep.open("myreport.pdf");
docRep.saveAs("/c/temp/UploadFile.txt","com.adobe.acrobat.plain-text")
docRep.closeDoc(true);
You will have to go into Edit > Preferences > Security (Enhanced) then choose the output folder (C:\Temp) in my case to output silently if you chose to employ this method.

Photoshop action for changing text number and saving with variable

I have a lot of graphic buttons that I need to make. I have 2 layers
TEXT (This is going to be numbers 1-48 for instance)
White Button image
I'm not sure how to go about writing this action or if I need a script. I need to have the text layer start at 1 and follow this progression.
save file w1.png (this yields a png with a button labeled with a "1"
change text to 2
save file w2.png (this yields a png with a button labeled with a "2"
change text to 3
. . . .
ect. . .all the way to 48. So this would make 48 images automatically. Can this be done with "actions" or do I need to learn scripting?
Save
You'll need a script for this, but it's going to be a rather simple one
function main() {
//this just checks if you have a text layer selected
try {
var textLayer = activeDocument.activeLayer.textItem
} catch (e) {
alert("active layer isn't a text layer");
return
};
var loops = 48,
pngSaveOptions = new PNGSaveOptions(),
outputFolder = Folder.selectDialog('', Folder.desktop); //this will ask for an output folder
for (var i = 0; i < loops; i++) {
var myNum = i + 1;
textLayer.contents = myNum; //this will change layer contents to number only. if you need some text here, write it in quotes like textLayer.contents = "my text" + myNum;
activeDocument.saveAs(new File(outputFolder + "/w" + myNum + ".png"), pngSaveOptions, true, Extension.LOWERCASE);
}
}
app.activeDocument.suspendHistory("temp", "main()");

Is there a better way to fix my AS2 preloader?

I have a game with a preloader in scene 1, with the following code on the time line.
stop();
loadingBar._xscale = 1;
var loadingCall:Number = setInterval(preloadSite, 50);
function preloadSite():Void {
var siteLoaded:Number = _root.getBytesLoaded();
var siteTotal:Number = _root.getBytesTotal();
var percentage:Number = Math.round(siteLoaded/siteTotal*100);
loadingBar._xscale = percentage;
bytesDisplay.text = percentage + "%";
if (siteLoaded >= siteTotal) {
clearInterval(loadingCall);
gotoAndPlay("StartMenu", 1);
}
}
The code works fine when there are no music files linked to frame 1. If there are music files linked, then everything loads before the preloader shows up.
I found this great webpage about preloaders, which speaks about the linkage issue, and suggests I put all the big files on frame 2, after the preloader, then skip them. I put my large files on frame 2 as suggested and the preloader worked again.
My question is, is there a better way to do this. This solution seems like a hack.
The only better option I can think of, is to NOT store the MP3 file in your Flash file, but rather load it in your preloader with your flash file's content. This is provided that you're storing your MP3 file somewhere else online (like on a server).
stop();
loadingBar._xscale = 1;
var sound:Sound = new Sound();
sound.loadSound("http://www.example.com/sound.mp3", false);
var loadingCall:Number = setInterval(preloadSite, 50);
function preloadSite():Void {
var siteLoaded:Number = _root.getBytesLoaded()+sound.getBytesLoaded();
var siteTotal:Number = _root.getBytesTotal()+sound.getBytesTotal();
var percentage:Number = Math.round(siteLoaded / siteTotal * 100);
loadingBar._xscale = percentage;
bytesDisplay.text = percentage + "%";
if (siteLoaded >= siteTotal) {
clearInterval(loadingCall);
gotoAndPlay("StartMenu", 1);
sound.start();
}
}