Scripting unleashed

Log-in or register.

Scripting unleashed

Published by on October 3rd 2007.

It is boring to do the same thing over and over again. Or isn’t it? … Anyway, in case of photo editing, repetition gets boring pretty quick and many editors solve this problem with a scripting subsystem. And so will RealWorld Photos.

Using JavaScript

Scripting in previous (and upcoming) RW applications is based on the JavaScript language. It is easy to learn and many people are already familiar with it and able to understand the syntax. After reading the documentation on a couple of application specific objects and their methods, anyone should be able to create or modify a scripted filter.

The old news

Scripted operations are nothing new in RW apps. Current versions are capable of accessing the opened image pixel by pixel. It is also possible to define and display a configuration dialog to let the user pick a couple of parameters at runtime.

The enhancements

While accessing images pixel by pixel may be OK when working with small images, it is very slow when used on multi-megapixel photos. JScript is interpreted and no scripting language is in fact suitable for this kind of tasks.

RealWorld Photos will be the first of RW tools to deliver three important updates:

  1. Ability to run a filter from script. This may look as a triviality, but it is actually pretty powerful feature, because filter parameters can be computed by the script at runtime and based on properties of the image.
  2. Ability to use drawing tools from script. Drawing tool that support (a simple) scripting interface, can be called from the script. Again, parameters for the drawing tools can be specified from the script.
  3. Access to image metadata.

Because scripted filters do not need to access the data pixel by pixel anymore, they can actually be pretty fast.

Example

Lena with post stamp border

The post stamp border decoration was added by a script using a drop shadow filter, blend with background filter and Ellipse tool.

Here is a work-in-progress version of the script (things were simplified in the final version):

var sizeX = RasterImage.sizeX;
var sizeY = RasterImage.sizeY;
var border = Math.round(Math.sqrt(sizeX*sizeY)*0.06);
var radius = border*0.7;
var stepsX = Math.round((sizeX+border+border)/(border+border)-0.5);
var stepsY = Math.round((sizeY+border+border)/(border+border)-0.5);
var deltaX = (sizeX+border+border)/stepsX;
var deltaY = (sizeY+border+border)/stepsY;
// expand the canvas
RasterImage.FillResize(sizeX+border*2, sizeY+border*2, 1, 1, border, border, 0, 0, 0xffffffff);
// draw the half-circles around the edge
DrawTool.EditTool = "ELLIPSE";
DrawTool.SetColor1(0, 0, 0, 0);
DrawTool.BlendMode = DrawTool.BMReplace;
for (var i = 0; i < stepsX; ++i)
{
    DrawTool.Run(RasterImage, (i*deltaX)+",0,"+radius, "");
    DrawTool.Run(RasterImage, (sizeX+border+border-i*deltaX)+","+(sizeY+border+border)+","+radius, "");
}
for (var i = 1; i <= stepsY; ++i)
{
    DrawTool.Run(RasterImage, "0,"+(i*deltaY)+","+radius, "");
    DrawTool.Run(RasterImage, (sizeX+border+border)+","+(sizeY+border+border-i*deltaY)+","+radius, "");
}
// add shadow
Operation.OperationID = "179FED75-A48F-4708-AF14-56BFB2A2ADBC";
Operation.SetParameter("OffsetX", 0);
Operation.SetParameter("OffsetY", 0);
Operation.SetParameter("Size", border/4);
Operation.SetParameter("Resize", true);
Operation.Run(RasterImage);
// blend with background
Operation.OperationID = "BCD0FD69-A4BD-46B0-A7DA-8B48F18E8820";
Operation.SetParameter("Background", 0xfcfcfe);
Operation.Run(RasterImage);

And yes, scripted filers may be used in conjunction with batch processing…

Vlasta's blog RSS feed

Recent comments

user icon Anonymous
Vista & Win 7 icons
What about ICL files?
Select background
I wish there were...