i have a really annoyong problem.
var Scriptfile = new File($.fileName);
var basePath = Scriptfile.path;
var topFolder = new Folder(basePath+"/actions");
var fileandfolderAr = scanSubFolders(topFolder,/\.(atn)$/i);
var fileList = fileandfolderAr[0];
for (var a = 0 ;a < fileList.length; a++) {
var atnFile = new File(fileList[a]);
alert(atnFile.name);
var rex = new RegExp (decodeURI(atnFile.name.replace(/\.[^\.]+$/, '')), "g");
if (!atnFile.exists) {
alert("Your ActionSet does not exist!\nPlease contact your administrator.");
return false;
}
var actionList = getActionSets();
//if ActionSet Exists remove it.
var flag = 0;
for (var d in actionList) {
if (decodeURI(actionList[d]).match(rex)) {
flag = 1;
continue;
}
}
if (!atnFile.exists) {
alert("File does not exist");
return false;
}
if (flag == 0) {
app.load(atnFile);
}
}
This piece of code is working very well if the atn file isn't placed in a folder or subfolder which contains a white space in it's name.
If i have a folder name like "photoshop script" it won't load my atn file.
Any ideas?
Thank you a lot!
It seems that nobody knows how to solve this, you big programmers. I found the solution. All i have to do is to decode the path to the file. I just replaced the var atnFile = new File(fileList[a]); with var atnFile= new File(decodeURI(fileList[a])); . I hope this will help someone sometime.
Related
I've created to a simple illustrator script to loop through the artboards and export each as a PNG back into the folder that the original illustrator file is in. At least I thought I had. I don't need to do anything complicated with layers or different formats this is just a speed up production sort of a thing. I'm a bit rusty on .jsx and appreciate there are similar solutions out there, but I can't get this to run. It seems to fail on the doc.ExportFile line but I really can't see what I'm doing wrong. I'd appreciate anyone taking a look:
var doc = activeDocument;;//Gets the active document
var numArtboards = doc.artboards.length;//returns the number of artboards in the document
var basePath = new File($.fileName).parent.fsName;
$.writeln(doc)
var options;
options = new ExportOptionsPNG24();
options.artBoardClipping = true;
options.matte = false;
options.horizontalScale = 100;
options.verticalScale = 100;
options.transparency = true;
for (var i = 0; i < numArtboards; i++ ) {
doc.artboards.setActiveArtboardIndex( i );
var artboardName = doc.artboards[i].name;
var destFile = new File('/' + artboardName + ".png");
doc.exportFile(destFile, ExportFormat.PNG24 , options);
}
The main problem seemed to be that you hve to have a destination path with the file name. This now seems to work: (You may need to altter the fileNamr generation as code just gets the first nune letters of a filename)
var doc = app.activeDocument;;//Gets the active document
var fleName = doc.name.slice(0, 9)//Get the file code number not the full name;
var numArtboards = doc.artboards.length;//returns the number of artboards in the document
var filePath = (app.activeDocument.fullName.parent.fsName).toString().replace(/\\/g, '/');
$.writeln("fleName= ",fleName)
$.writeln("numArtboards= ",numArtboards)
$.writeln("filePath= ",filePath);
var options = new ExportOptionsPNG24();
for (var i = 0; i < numArtboards; i++ ) {
doc.artboards.setActiveArtboardIndex( i );
options.artBoardClipping = true;
options.matte = false;
options.horizontalScale = 100;
options.verticalScale = 100;
options.transparency = true;
var artboardName = doc.artboards[i].name;
$.writeln("artboardName= ", artboardName);
var destFile = new File(filePath + "/" + fleName + " " + artboardName + ".png");
$.writeln("destFile= ",destFile);
doc.exportFile(destFile,ExportType.PNG24,options);
}
I have a script (with a lot of stolen parts you may recognise) that runs through a selected group of images, copies the image and filename and applies to a template in Photoshop. Everything works just fine, except that Photoshop somehow strips umlauts from my strings, ie, Björn becomes Bjorn.
"Logging" through an alert inside of Photoshop (line #30 below) shows that it has the correct string all the way until it's applied as the textItem.contents.
Code provided below, thanks for any help!
#target photoshop
app.displayDialogs = DialogModes.NO;
var templateRef = app.activeDocument;
var templatePath = templateRef.path;
var photo = app.activeDocument.layers.getByName("Photo"); // keycard_template.psd is the active document
// Check if photo layer is SmartObject;
if (photo.kind != "LayerKind.SMARTOBJECT") {
alert("selected layer is not a smart object")
} else {
// Select Files;
if ($.os.search(/windows/i) != -1) {
var photos = File.openDialog("Select photos", "*.png;*.jpg", true)
} else {
var photos = File.openDialog("Select photos", getPhotos, true)
};
if (photos.length) replaceItems();
}
function replaceItems() {
for (var m = 0; m < photos.length; m++) {
if (photos.length > 0) {
// Extract name
var nameStr = photos[m].name;
var nameNoExt = nameStr.split(".");
var name = nameNoExt[0].replace(/\_/g, " ");
// Replace photo and text in template
photo = replacePhoto(photos[m], photo);
// alert(name);
replaceText(templateRef, 'Name', name);
templateRef.saveAs((new File(templatePath + "/keycards/" + name + ".jpg")), jpgOptions, true);
}
}
}
// OS X file picker
function getPhotos(thePhoto) {
if (thePhoto.name.match(/\.(png|jpg)$/i) != null || thePhoto.constructor.name == "Folder") {
return true
};
};
// JPG output options;
var jpgOptions = new JPEGSaveOptions();
jpgOptions.quality = 12; //enter number or create a variable to set quality
jpgOptions.embedColorProfile = true;
jpgOptions.formatOptions = FormatOptions.STANDARDBASELINE;
// Replace SmartObject Contents
function replacePhoto(newFile, theSO) {
app.activeDocument.activeLayer = theSO;
// =======================================================
var idplacedLayerReplaceContents = stringIDToTypeID("placedLayerReplaceContents");
var desc3 = new ActionDescriptor();
var idnull = charIDToTypeID("null");
desc3.putPath(idnull, new File(newFile));
var idPgNm = charIDToTypeID("PgNm");
desc3.putInteger(idPgNm, 1);
executeAction(idplacedLayerReplaceContents, desc3, DialogModes.NO);
return app.activeDocument.activeLayer
};
// Replace text strings
function replaceText(doc, layerName, newTextString) {
for (var i = 0, max = doc.layers.length; i < max; i++) {
var layerRef = doc.layers[i];
if (layerRef.typename === "ArtLayer") {
if (layerRef.name === layerName && layerRef.kind === LayerKind.TEXT) {
layerRef.textItem.contents = decodeURI(newTextString);
}
} else {
replaceText(layerRef, layerName, newTextString);
}
}
}
Had the same problem and tried everything I had in my developer toolbox... for around 3 hours ! without any success and then I found a little hack !
It seems that photoshop is uri encoding the name of the file but don't do it in a way that allow us to do a decodeURI() and get back those special characters.
For exemple instead of "%C3%A9" that should be "é" we get "e%CC%81". So what i do is a replace on the file name to the right UTF-8 code and then a decodeURI. Exemple :
var fileName = file.name
var result = fileName.replace(/e%CC%81/g, '%C3%A9') // allow é in file name
var myTextLayer.contents = decodeURI(result);
Then you can successfully get special chars and in my case accent from filename in your text layer.
You can do a replace for each characters you need for me it was :
'e%CC%81': '%C3%A9', //é
'o%CC%82': '%C3%B4', //ô
'e%CC%80': '%C3%A8', //è
'u%CC%80': '%C3%B9', //ù
'a%CC%80': '%C3%A0', //à
'e%CC%82': '%C3%AA' //ê
I took UTF-8 code from this HTML URL Encoding reference : https://www.w3schools.com/tags/ref_urlencode.asp
Hope it will help somebody one day because nothing existed online on this bug.
I have the below script and its cutting out at about 214 files recovered and sent to the new orphaned folder when I have over 2000 orphaned. I would appreciate any advice
function myFunction(findOrphaned) {
var allFiles = DocsList.getAllFiles();
var orphaned = DocsList.getFolder('Orphaned');
for (var i = 0; i < allFiles.length; i++) {
if (allFiles[i].getParents().length === 0) {
allFiles[i].addToFolder(orphaned);
}
}
}
I think this will do what you're attempting, using the newer DriveApp API since, as rchang pointed out, the DocsList API is deprecated and set to be decommissioned in April.
function collectOrphans(findOrphaned) {
var folder = DriveApp.getFoldersByName('Orphaned').next();
var files = DriveApp.getFiles();
var orphanCount = 0;
while(files.hasNext()){
var file = files.next();
if(!file.getParents().hasNext()){
folder.addFile(file);
orphanCount++;
}
}
Logger.log('Moved ' + orphanCount + ' orphans successfully.');
}
I'm hacking together a little Dropbox image slideshow. I use the Dropbox Public folder to share the index.html file which looks in the 'img' folder for a bunch of images to create slides.
I do this with the following, it's hacky but works
var findFiles = function(slideLimit){
var limit = slideLimit;
var img = [];
for(var i = 1; i < limit; i++){
var src = "<li class='slide slide-"+i+"'><img src='img/"+i+".png' onerror='imgError(this);''></li>"
$('.frame ul').append(src);
}
}
That works great, but I'd like to provide a solution that doesn't rely on the user having to use .png.
I was hoping omitting the extension would work on Dropbox but turns out no:
var src = "<li class='slide slide-"+i+"'><img src='img/"+i+"' onerror='imgError(this);''></li>"
I've been racking my brains, ideally I'd like
if( mimeType = png)
i + '.png'
else if (mimeType = gif)
i + '.gif'
etc
Bit stuck for solutions. Anyone got any good ideas? Might require me taking different a different direction...
Best way, make the users tell you the extension
var findFiles = function(slideLimit, ext){
var limit = slideLimit,
img = [],
lis = [];
ext = ext || "png";
for (var i = 1; i < limit; i++) {
lis.push("<li class='slide slide-"+i+"'><img src='img/"+i+"."+ext+"' onerror='imgError(this);''></li>");
}
$('.frame ul').append(lis.join(""));
}
Ping the server for the file, downside it takes time to keep hitting the server to see if the file it there
var findFiles = function(slideLimit){
var limit = slideLimit,
img = [],
lis = [],
extList = ["png","gif"];
function testExt () {
var ext = extList.shift();
if (ext) {
var img = new Image();
img.onload = function () {
load(ext);
};
img.onerror = testExt;
img.src="img/1." + ext;
}
}
function load (ext){
for (var i = 1; i < limit; i++) {
lis.push("<li class='slide slide-"+i+"'><img src='img/"+i+"."+ext+"' onerror='imgError(this);''></li>");
}
$('.frame ul').append(lis.join(""));
}
testExt();
}
[note both code snipplets are untested, wrote them here in the editor]
I have a folder with a lot of subfolders, each with a bunch of TIFs and PSD files inside. Some of these have transparency in them while some don't. These files vary massively in size.
I need all the files to be turned into JPGs, or if they contain transparency, PNGs. I require the files to be 200kb or less and don't really mind how large they are as long as they aren't scaled up.
Someone on a forum (who I'm insanely thankful for) wrote a fair bit of code for it, which my friend modified to suit exactly what I was asking and we're nearly there now.
It worked fine, the only problem being that a lot of images came out 1x1 pixel and a solid block of colour.
We've found this was consistently happening with the same images for some reason, but couldn't work out what exactly it was in these images.
Now Mr forum blokey ( http://www.photoshopgurus.com/forum/members/paul-mr.html ) modified the script and it now seems to work fine with PSDs.
It's working with TIFs with transparency but some of the TIFs with 100% opacity it just won't work on. I can't find much that's consistent with these files other than the colour blue, though this just could be a massive coincidence and probably is (there's a lot of blue in the images I've been dealing with).
Below is a link to the thread in which the code was first written. Paul MR seems to think the colorsampler bit is a little suspect so perhaps that's what's causing the problems (blueness?).
http://www.photoshopgurus.com/forum/photoshop-actions-automation/34745-batching-tiffs-jpg-png-w-automatic-resize-based-filesize.html
I wish I could do a little more to try and work this out myself but I've barely a speck of understanding on this stuff, I just know when there's a situation where a bit of scripting could help out.
Below is the script as it currently stands:
#target PhotoshopString.prototype.endsWith = function(str) {
return (this.match(str + "$") == str)
} String.prototype.startsWith = function(str) {
return this.indexOf(str) == 0;
};
var desiredFileSize = 200000;
app.bringToFront();
app.displayDialogs = DialogModes.NO;
main();
//app.displayDialogs = DialogModes.YES;
function main() {
var topLevelFolder = Folder.selectDialog("Please select top level folder.");
if (topLevelFolder == null)return;
var FileList = [];
getFileList(topLevelFolder);
var startRulerUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;
for (var f in FileList) {
app.open(FileList[f]);
activeDocument.changeMode(ChangeMode.RGB);
try {
activeDocument.mergeVisibleLayers();
} catch(e) {} var Name = decodeURI(app.activeDocument.name).replace(/.[^.] + $ /, '');
if (hasTransparency(FileList[f])) {
var saveFile = File(FileList[f].path + "/" + Name + ".png");
SavePNG(saveFile);
app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
} else {
var saveFile = File(FileList[f].path + "/" + Name + ".jpg");
SaveForWeb(saveFile, 80);
app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
} app.preferences.rulerUnits = startRulerUnits;
} function getFileList(folder) {
var fileList = folder.getFiles();
for (var i = 0; i < fileList.length; i++) {
var file = fileList[i];
if (file instanceof Folder) {
getFileList(file);
} else {
if ((file.name.endsWith("tiff") || file.name.endsWith("tif") || file.name.endsWith("psd")) && ! file.name.startsWith("._"))FileList.push(file);
}
}
} alert(FileList.length + " files have been modified.");
} function hasTransparency(file) {
if (file.name.endsWith("tiff") || file.name.endsWith("tif")) {
var sample = app.activeDocument.colorSamplers.add([new UnitValue(1.5, 'px'), new UnitValue(1.5, 'px')]);
try {
sample.color.rgb.hexValue;
sample.remove();
return false;
} catch(e) {
sample.remove();
return true;
}
} var doc = activeDocument;
if (doc.activeLayer.isBackgroundLayer)return false;
var desc = new ActionDescriptor();
var ref = new ActionReference();
ref.putProperty(charIDToTypeID("Chnl"), charIDToTypeID("fsel"));
desc.putReference(charIDToTypeID("null"), ref);
var ref1 = new ActionReference();
ref1.putEnumerated(charIDToTypeID("Chnl"), charIDToTypeID("Chnl"), charIDToTypeID("Trsp"));
desc.putReference(charIDToTypeID("T "), ref1);
executeAction(charIDToTypeID("setd"), desc, DialogModes.NO);
var w = doc.width.as('px');
var h = doc.height.as('px');
var transChannel = doc.channels.add();
doc.selection.store(transChannel);
if (transChannel.histogram[255] != (h * w)) {
transChannel.remove();
return true;
} else {
transChannel.remove();
return false;
}
};
function SavePNG(saveFile) {
pngSaveOptions = new PNGSaveOptions();
activeDocument.saveAs(saveFile, pngSaveOptions, true, Extension.LOWERCASE);
var actualFilesize = saveFile.length;
var ratio = desiredFileSize / actualFilesize;
if (ratio < 1) {
var imageScale = Math.sqrt(ratio);
activeDocument.resizeImage(activeDocument.width * imageScale, activeDocument.height * imageScale, activeDocument.resolution, ResampleMethod.BICUBICSMOOTHER);
activeDocument.saveAs(saveFile, pngSaveOptions, true, Extension.LOWERCASE);
}
}
function SaveForWeb(saveFile, jpegQuality) {
var sfwOptions = new ExportOptionsSaveForWeb();
sfwOptions.format = SaveDocumentType.JPEG;
sfwOptions.includeProfile = false;
sfwOptions.interlaced = 0;
sfwOptions.optimized = true;
sfwOptions.quality = jpegQuality;
activeDocument.exportDocument(saveFile, ExportType.SAVEFORWEB, sfwOptions);
var actualFilesize = saveFile.length;
var ratio = desiredFileSize / actualFilesize;
if (ratio < 1) {
var imageScale = Math.sqrt(ratio);
activeDocument.resizeImage(activeDocument.width * imageScale, activeDocument.height * imageScale, activeDocument.resolution, ResampleMethod.BICUBICSMOOTHER);
activeDocument.exportDocument(saveFile, ExportType.SAVEFORWEB, sfwOptions);
}
}