Copy link to clipboard
Copied
Hi,
I am new to After Effects scripting (I did a bit of work using the C++ SDK though), so before diving into the documentation I was wondering if what I want to do is possible by scripting.
I want to programmatically modify the color parameter of one of AE's effects that is applied to my composition, and save the current frame each time in a different PNG file.
Do you think I can achieve this with a script? Does anyone have any references I could start looking at?
Thanks in advance for any suggestions.
Copy link to clipboard
Copied
Yes it is possible.
Below is something to start with, probably not exactly what you want but you can tweak it.
It changes the color for all "Fill" effects on the selected layer, then takes a screenshot at comp time and saves it.
Two buttons, one to launch the process, one to define/store the destination folder.
If you want to tweak something, better start with what the script actually does than with the UI
(when you enter the ScriptUI stuff, you can never know when you go out...)
Xavier
(function (thisObj){
//=======================================
// aux
//=======================================
function hexToColor(_0xRRGGBB){
// Dan Ebberts http://forums.adobe.com/message/5680721#5680721
var r = _0xRRGGBB >> 16;
var g = (_0xRRGGBB & 0x00ff00) >> 8;
var b = _0xRRGGBB & 0xff;
return [r/255, g/255, b/255];
};
function colorToHex(rgb){
// rgb=[r,g,b] with all entries in [0,1]
var r = Math.round(rgb[0]*255);
var g = Math.round(rgb[1]*255);
var b = Math.round(rgb[2]*255);
return 65536 * r + 256 * g + b;
};
function selectFolder(){
var folder;
if (outputFolder instanceof Folder && outputFolder.exists)
{
folder = outputFolder.selectDlg("Please select a new location for the screenshots.");
if (folder && folder.exists) outputFolder=folder;
}
else
{
outputFolder = Folder.selectDialog("The output folder is no longer valid. Please select a new location for the screenshots.");
};
return;
};
function getEffects(layer, matchName){
var matchingEffects = [];
var N,n;
if (layer.effect)
{
N = layer.effect.numProperties;
for (n=1; n<=N; n++) if (layer.effect(n).matchName===matchName) matchingEffects.push(layer.effect(n));
};
return matchingEffects;
};
function doSomething(){
var comp, layer, matchingEffects, initColor, color;
comp = app.project.activeItem;
if (comp instanceof CompItem && comp.selectedLayers.length>0)
{
layer = comp.selectedLayers[0];
// this gathers all 'Fill" effects into an array
matchingEffects = getEffects(layer, "ADBE Fill");
if (matchingEffects.length>0)
{
// get the current color of the 1st occurence to iitialise the color picker (not necessary, $.colorPicker() works with no argument too):
// color is [R,G,B] with each entry in [0,1] >>> convert to hex
initColor = matchingEffects[0].property("ADBE Fill-0002").value;
initColor = colorToHex(initColor);
// launch the color picker with initial value initColor;
do {color = $.colorPicker(initColor);} while (color<0 && confirm("Retry ?"));
if (color>=0)
{
// now color is a hex, convert back to [r,g,b];
color = hexToColor(color);
// this set the value for the "Color" property of all "fill" effects to: color
for (n=0; n<matchingEffects.length; n++) matchingEffects
// screenshot
if (!outputFolder.exists) selectFolder();
if (outputFolder.exists) comp.saveFrameToPng(comp.time, File(outputFolder.fsName + "/" + comp.name + (new Date().getTime()/1000) + ".png"))
else {}; // do nothing
};
}
else
{
alert("The selected layer should have at least one \"Fill\" effect.", "Wrong script selection");
};
}
else
{
alert("Select a layer with a \"Fill\" effect.", "Wrong script selection");
};
return;
};
//=======================================
// code
//=======================================
// global variables:
var pal, outputFolder;
// this var might change - only a starting default
outputFolder = Folder.desktop;
pal = (thisObj instanceof Panel) ? thisObj : new Window("palette", "hi", undefined, {resizeable: true}); // type, title, bounds, properties
pal.onResize = pal.onResizing = function(){this.layout.resize()};
pal.orientation = 'row';
pal.margins = 5;
pal.spacing= 5;
pal.btn1 = pal.add("button", undefined, 'do color', {}); // type, bounds, text, properties
pal.btn1.size = [75,20];
pal.btn1.onClick = doSomething;
pal.btn2 = pal.add("button", undefined, 'set folder', {});
pal.btn2.size = [75,20];
pal.btn2.onClick = selectFolder;
if (pal instanceof Panel) {pal.layout.layout(true);}
else {pal.center(); pal.show();};
return;
})(this);
Copy link to clipboard
Copied
Thank you Xavier, I'll give it a try.
Copy link to clipboard
Copied
One thing: if you use the color picker, there is a mistake in the above code.
I modified the hexToColor() function sligtly (it returns [r,g,b] instead of the original [r,g,b,1]), and forgot to make sure the parameter color is a Array[4] : [r,g,b,a].
So you'll have to set color[3] = 1 just before setting the value.
(If you set a color value to [r,g,b], After Effects tolerates it, but if you try the same thing by expression, you'll get an error:
app.project.item(1).layer(1).effect("ADBE Fill").property("ADBE Fill-0002").setValue([0.2,0.5,0.8]); // not correct but tolerated
app.project.item(1).layer(1).effect("ADBE Fill").property("ADBE Fill-0002").expression = '[0.2,0.5,0.8]'; // ===> error)
Xavier
Copy link to clipboard
Copied
Thanks for the detail.
I didn't need the ColorPicker as my script is very simple. Also, I figured out for the color parameter by looking at the previous Property.value before trying to set it.
Now my script is running fine, thanks again!
Get ready! An upgraded Adobe Community experience is coming in January.
Learn more