How to write a script that does "Save for web" for mutiple resolutions in Adobe Illustrator? - adobe-illustrator

It's tedious to have to click to "Save for web" and change the resolution each time I want to create the image as a different resolution. Is there a way to write a script to automatically achieve this, for multiple resolutions as one?

For that i myself use this function
function saveDocumentAsPng(d, width, height) {
var fileName = d.fullName.toString();
if(fileName.lastIndexOf(".") >= 0) { fileName = fileName.substr(0, fileName.lastIndexOf("."));}
fileName += "_wxh.png".replace("w", width).replace("h", height);
var exportOptions = new ExportOptionsPNG24();
exportOptions.horizontalScale = exportOptions.verticalScale = 100 * Math.max(width/d.width, height/d.height);
var file = new File(fileName);
app.activeDocument = d;
d.exportFile(file, ExportType.PNG24, exportOptions);
}
Note that it names a resulting png's with “_[width]x[height]” suffix.
I wrote my function based on a sample from adobe's javascript reference http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/devnet/pdf/illustrator/scripting/illustrator_scripting_reference_javascript_cs5.pdf (page 59).

This is an old post, but it inspired me to create a different version for my Android project that I'd like to share.
Just create a 144x144 pixels document and run this:
var doc = app.activeDocument;
// This is the scale factor that you can see in "Percent" textbox of
// the "Save for Web..." dialog box while changing the size of the image
var scale = [100, 66.67, 50, 33.33]
// This is the image size for the PNGs files names
var size = [144, 96, 72, 48]
for(var i = 0; i<4; i++)
{
var fileName = doc.fullName.toString();
if (fileName.lastIndexOf(".") >= 0) {
// Get the file name without the extension
fileName = fileName.substr(0, fileName.lastIndexOf("."));
}
// Name each file with yours size to avoid overwrite
fileName += "_wxh.png".replace("w", size[i]).replace("h", size[i]);
var exportOptions = new ExportOptionsPNG24();
exportOptions.horizontalScale = exportOptions.verticalScale = scale[i];
exportOptions.artBoardClipping = true;
var file = new File(fileName);
doc.exportFile(file, ExportType.PNG24, exportOptions);
}
Window.alert ("Successfully exported!", "Success");
Thank you!

Here is the script that will export all files of the selected folder into PNG. You can specify resolution in this code and image quality will be good. In this code by default resolution is 600
var folder = Folder.selectDialog();
if (folder) {
var files = folder.getFiles("*.ai");
for (var i = 0; i < files.length; i++) {
var currentFile = files[i];
app.open(currentFile);
var activeDocument = app.activeDocument;
var pngFolder = Folder(currentFile.path + "/PNG");
if (!pngFolder.exists)
pngFolder.create();
var fileName = activeDocument.name.split('.')[0] + ".png";
var destinationFile = File(pngFolder + "/" + fileName);
// Export Artboard where you can set resolution for an image. Set to 600 by default in code.
var opts = new ImageCaptureOptions();
opts.resolution = 600;
opts.antiAliasing = true;
opts.transparency = true;
try {
activeDocument.imageCapture(new File(destinationFile), activeDocument.geometricBounds, opts);
} catch (e) {
}
activeDocument.close(SaveOptions.DONOTSAVECHANGES);
currentFile = null;
}
}
If you want to export in jpg format, just change extension of the file in the code in the following line
var fileName = activeDocument.name.split('.')[0] + ".png";
change to
var fileName = activeDocument.name.split('.')[0] + ".jpg"; // For jpg
Also, you can change the name of the file and where the exported file will be stored according to your requirement.
Hope my answer will help you.

Related

Photoshop paths to linear

I wonder if it's possible to loop over a Photoshop path and set all the points on it to be linear?
Unlike Illustrator, paths in Photoshop is not well documented and a bit cumbersome:
// Switch off any dialog boxes
displayDialogs = DialogModes.ERROR // ERRORS ONLY DialogModes 2
// create a document to work with
var docRef = app.documents.add(200, 200, 72, "untitled");
// call the source document
var srcDoc = app.activeDocument;
// create the array of PathPointInfo objects
var lineArray = new Array();
lineArray.push(new PathPointInfo());
lineArray[0].kind = PointKind.SMOOTHPOINT;
lineArray[0].anchor = new Array(50, 100); // A
lineArray[0].leftDirection = [0, 0];
lineArray[0].rightDirection = lineArray[0].anchor;
lineArray.push(new PathPointInfo());
lineArray[1].kind = PointKind.SMOOTHPOINT;
lineArray[1].anchor = new Array(150, 150); // B
lineArray[1].leftDirection = [0, 0];
lineArray[1].rightDirection = [0, 0];
// create a SubPathInfo object, which holds the line array in its entireSubPath property.
var lineSubPathArray = new Array();
lineSubPathArray.push(new SubPathInfo());
lineSubPathArray[0].operation = ShapeOperation.SHAPEXOR;
lineSubPathArray[0].closed = false;
lineSubPathArray[0].entireSubPath = lineArray;
pathName = "my path";
//create the path item, passing subpath to add method
var myPathItem = docRef.pathItems.add(pathName, lineSubPathArray);
// Set Display Dialogs back to normal
displayDialogs = DialogModes.ALL; // NORMAL
myPath = srcDoc.pathItems.getByName(pathName);
var subPathCount = myPath.subPathItems.length; // Count of subpaths
var msg = "";
msg += subPathCount + " path(s)\n";
for (var i = 0; i < myPath.subPathItems.length; i++)
{
msg += myPath.subPathItems[i] + "\n";
}
alert(msg);
Firstly, I'm having difficulty access the subPathItems items after I created the path.
Secondly, I don't know what the settings for the tangents (.leftDirection, .rightDirection) are for a linear path.
Apart from that it's peachy ;)

Set resolution when exporting artboards to PNG using script

Sorry that this is so similar to a recent post but I can't find the solution anywhere. I have created a simple script that loops through each artboard in an open illustrator document and exports it as a separate PNG file. All is working well except that I want to set the resolution to 150 dpi and not the default 72 dpi, for production reasons. This is an option that you can set when exporting manually to PNG but I don't seem to be able to set it in the PNG options in the code, although the script runs without errors it ignores the resolution setting. Could someone let me know how to do this, many thanks. Code as follows:
var doc = app.activeDocument;;//Gets the active document
var fileName = doc.name.slice(0, 9);//Gets the G Number
var numArtboards = doc.artboards.length;//returns the number of artboards in the document
var filePath = (app.activeDocument.fullName.parent.fsName).toString().replace(/\\/g, '/');
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 + "/" + fileName + " " + artboardName + ".png");
//$.writeln("destFile= ",destFile);
doc.exportFile(destFile,ExportType.PNG24,options);
}
After doing some digging I've found that if you use imageCapture you can set the resolutuion. So new script below. thanks to CarlosCanto for providing this link via the Adobe Forum https://forums.adobe.com/message/9075307#9075307
var doc = app.activeDocument;;//Gets the active document
var fileName = doc.name.slice(0, 9);//Gets the G Number
var numArtboards = doc.artboards.length;//returns the number of artboards in the document
var filePath = (app.activeDocument.fullName.parent.fsName).toString().replace(/\\/g, '/');
var options = new ImageCaptureOptions();
for (var i = 0; i < numArtboards; i++) {
doc.artboards.setActiveArtboardIndex(i);
var activeAB = doc.artboards[doc.artboards.getActiveArtboardIndex()];
options.artBoardClipping = true;
options.resolution = 150;
options.antiAliasing = true;
options.matte = false;
options.horizontalScale = 100;
options.verticalScale = 100;
options.transparency = true;
var artboardName = doc.artboards[i].name;
var destFile = new File(filePath + "/" + fileName + " " + artboardName + ".png");
doc.imageCapture(destFile, activeAB.artboardRect, options);
}

Extendscript with Photoshop: Importing an image

I'm trying to select some image files via a prompt, then add those files to the active document. Here's what I have so far:
#target photoshop
doc = app.activeDocument;
// choose image files
var files = File.openDialog(undefined,undefined,true);
// for each image, add to new layer and insert into doc
for (var file in files) {
var layer = doc.artLayers.add();
layer.image = file; // this doesn't work.
}
What's layer.image? ArtLayer doesn't have this property. Maybe placing will work better in your case:
doc = app.activeDocument;
// choose image files
var files = File.openDialog(undefined, undefined, true);
// for each image, add to new layer and insert into doc
for (var i = 0; i < files.length; i++)
{
var layer = placeImage(files[i]);
}
function placeImage(imageFile)
{
var desc554 = new ActionDescriptor();
desc554.putPath(cTID('null'), imageFile);
desc554.putEnumerated(cTID('FTcs'), cTID('QCSt'), cTID('Qcsa'));
var desc555 = new ActionDescriptor();
desc555.putUnitDouble(cTID('Hrzn'), cTID('#Pxl'), 0.000000);
desc555.putUnitDouble(cTID('Vrtc'), cTID('#Pxl'), 0.000000);
desc554.putObject(cTID('Ofst'), cTID('Ofst'), desc555);
executeAction(cTID('Plc '), desc554, DialogModes.NO);
return activeDocument.activeLayer
};
function cTID(s)
{
return app.charIDToTypeID(s);
};
function sTID(s)
{
return app.stringIDToTypeID(s);
};
Also Photoshop doesn't like when for...in loops are used on Array (sometimes it works, sometimes it doesn't: in case of File object it doesn't work)

Replacing smart objects in bulk with Photoshop

Just facing this issue: I have a mockup in Photoshop with two smart-objects: Rectangle 14.psb and Place your logo.psb
I have 100+ images in png that should be applied to create mockups.
For this reason, I would like your help to create a script that:
Let me select the png file that I would like to use
Open the smart objects (Rectangle 14.psb and Place your logo.psb)
Re-Link the same png to the layers "place your logo" of both the smart objects.
Finally, the script should save the file as png with the same file name of the selected png file adding just _new after its name.
So far I have tried this code without any luck:
#target photoshop
if (app.documents.length > 0) {
var myDocument = app.activeDocument;
var theName = myDocument.name.match(/(.*)\.[^\.]+$/)[1];
var thePath = myDocument.path;
var theLayer = myDocument.activeLayer;
// PSD Options;
psdOpts = new PhotoshopSaveOptions();
psdOpts.embedColorProfile = true;
psdOpts.alphaChannels = true;
psdOpts.layers = true;
psdOpts.spotColors = true;
// Check if layer is SmartObject;
if (theLayer.kind != "LayerKind.SMARTOBJECT") {
alert("selected layer is not a smart object")
} else {
// Select Files;
if ($.os.search(/windows/i) != -1) {
var theFiles = File.openDialog("please select files",
"*.psd;*.tif;*.jpg;*.png", true)
} else {
var theFiles = File.openDialog("please select files", getFiles,
true)
};
if (theFiles) {
for (var m = 0; m < theFiles.length; m++) {
// Replace SmartObject
theLayer = replaceContents(theFiles[m], theLayer);
var theNewName = theFiles[m].name.match(/(.*)\.[^\.]+$/)[1];
// Save JPG
myDocument.saveAs((new File(thePath + "/" + theName + "_" +
theNewName + ".psd")), psdOpts, true);
}
}
}
};
// Get PSDs, TIFs and JPGs from files
function getFiles(theFile) {
if (theFile.name.match(/\.(psd|png|jpg)$/i) != null ||
theFile.constructor.name == "Folder") {
return true
};
};
// Replace SmartObject Contents
function replaceContents(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
};
The above code substitute the smart object but I would like just to re-link the layer withing the smartobject to a new image and save the file. Any help would be much appreciated!
Are you familiar with Scriptlistener? You can use it to get all the functions you need and then modify the output to run within your loop of 100 pngs, it should be straightforward.

How to create a single-color Bitmap to display a given hue?

I have a requirement to create an image based on a certain color. The color will vary and so will the size of the output image. I want to create the Bitmap and save it to the app's temporary folder. How do I do this?
My initial requirement came from a list of colors, and providing a sample of the color in the UI. If the size of the image is variable then I can create them for certain scenarios like result suggestions in the search pane.
This isn't easy. But it's all wrapped in this single method for you to use. I hope it helps. ANyway, here's the code to create a Bitmap based on a given color & size:
private async System.Threading.Tasks.Task<Windows.Storage.StorageFile> CreateThumb(Windows.UI.Color color, Windows.Foundation.Size size)
{
// create colored bitmap
var _Bitmap = new Windows.UI.Xaml.Media.Imaging.WriteableBitmap((int)size.Width, (int)size.Height);
byte[] _Pixels = new byte[4 * _Bitmap.PixelWidth * _Bitmap.PixelHeight];
for (int i = 0; i < _Pixels.Length; i += 4)
{
_Pixels[i + 0] = color.B;
_Pixels[i + 1] = color.G;
_Pixels[i + 2] = color.R;
_Pixels[i + 3] = color.A;
}
// update bitmap data
// using System.Runtime.InteropServices.WindowsRuntime;
using (var _Stream = _Bitmap.PixelBuffer.AsStream())
{
_Stream.Seek(0, SeekOrigin.Begin);
_Stream.Write(_Pixels, 0, _Pixels.Length);
_Bitmap.Invalidate();
}
// determine destination
var _Folder = Windows.Storage.ApplicationData.Current.TemporaryFolder;
var _Name = color.ToString().TrimStart('#') + ".png";
// use existing if already
Windows.Storage.StorageFile _File;
try { return await _Folder.GetFileAsync(_Name); }
catch { /* do nothing; not found */ }
_File = await _Folder.CreateFileAsync(_Name, Windows.Storage.CreationCollisionOption.ReplaceExisting);
// extract stream to write
// using System.Runtime.InteropServices.WindowsRuntime;
using (var _Stream = _Bitmap.PixelBuffer.AsStream())
{
_Pixels = new byte[(uint)_Stream.Length];
await _Stream.ReadAsync(_Pixels, 0, _Pixels.Length);
}
// write file
using (var _WriteStream = await _File.OpenAsync(Windows.Storage.FileAccessMode.ReadWrite))
{
var _Encoder = await Windows.Graphics.Imaging.BitmapEncoder
.CreateAsync(Windows.Graphics.Imaging.BitmapEncoder.PngEncoderId, _WriteStream);
_Encoder.SetPixelData(Windows.Graphics.Imaging.BitmapPixelFormat.Bgra8,
Windows.Graphics.Imaging.BitmapAlphaMode.Premultiplied,
(uint)_Bitmap.PixelWidth, (uint)_Bitmap.PixelHeight, 96, 96, _Pixels);
await _Encoder.FlushAsync();
using (var outputStream = _WriteStream.GetOutputStreamAt(0))
await outputStream.FlushAsync();
}
return _File;
}
Best of luck!