Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
0

Add effect Warp, Distort to batch processing

Participant ,
Feb 08, 2022 Feb 08, 2022

Hello.

 

So I know we can't add Effect in action directly but we must use Insert Menu Item but for effects it opens up additional menu that has to be OK-eyd. 

I tried applying effect and saving Graphics style in library and apply that as step in action but it just skips that step. Do I need to add graphic style to main window and if so how do I do that?

 

So, what is the solution to have working effect application to strokes/elements in batch processing?

 

If it is relevant, I have lines and I want to apply Wave Horizontal 100% on all of them, SVG files. 

 

At the moment I run action and click OK every few seconds when prompt as I watch videos or exercise. 

 

Thank you.

TOPICS
Scripting
1.1K
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe
Community Expert ,
Feb 08, 2022 Feb 08, 2022

Hi @Marinapomorac, see if this helps. A while ago I wrote a bunch of convenience functions for many of Illustrator's Live Effects. See repository.

Here is a script (using that code) that will apply Warp Horizontal to the selected items.

- Mark

/*

    From AI Live Effect Functions by m1b
    https://github.com/mark1bean/ai-live-effect-functions

*/

// see bottom of script for the part you
// want to edit


var LE = {
    /* helper object for Live Effect scripts */
    functionName: 'LE',
    testMode: false,
    debug: false,
    defaults: {},

    defaultsObject: function (item, defaults, options, func) {
        /* combines defaults and user-specified options along with a little admin work */
        LE.functionName = func.name;
        try {
            if (defaults == undefined && options == undefined) return {};
            if (defaults == undefined) return options;
            if (options == undefined) return defaults;
            if (options.debug) LE.debug = true;
            for (var key in options) {
                defaults[key] = options[key];
            }
            LE.defaults = defaults;
            return defaults;
        } catch (error) {
            throw new Error(func.name + ' failed to parse options object. ' + error)
        }
    },

    applyEffect: function (item, xml, expand) {
        /* applies the live effect, unless in test mode */
        if (LE.testMode) {
            LE.testResults.push({ timestamp: new Date(), functionName: LE.functionName, xml: xml });
            return xml;
        } else {
            // work out whether item is single item or multiple
            var items;
            if (item == undefined) {
                throw new Error(LE.functionName + ' failed. No item available.');
            } else if (item[0] == undefined && item.typename != undefined) {
                // a single item
                items = [item];
            }
            if (items.length == undefined) throw new Error(LE.functionName + ' failed. Unexpected item type. [1]');
            // applyEffect to each item
            for (var i = 0; i < items.length; i++) {
                if (items[i].typename == undefined) throw new Error(LE.functionName + ' failed. Unexpected item type. [2]');
                items[i].applyEffect(xml);
                if (expand) LE.expandAppearance(items[i]);
            }
            if (LE.debug) $.writeln(LE.functionName + ':\n' + xml);
        }
    },

    handleError: function (error) {
        /* called when errors happen */
        alert(error.message);
    },

    expandAppearance: function (item) {
        app.redraw();
        app.executeMenuCommand('expandStyle');
        item = app.activeDocument.selection[0];
    }
}


function LE_Warp_Wave(item, options) {
    /* example customization of LE_Warp */
    if (options == undefined || typeof options != 'object') options = {};
    options.warpType = 8;
    LE_Warp(item, options);
}

/* -------------------------------------------------------------------------------------------- */
function LE_Warp(item, options) {
    try {
        var defaults = {
            warpType: 0,             /* 0 = Arc, 1 = ArcLower, 2 = ArcUpper, 3 = Arch, 4 = Bulge, 5 = ShellLower,
                                        6 = ShellUpper, 7 = Flag, 8 = Wave, 9 = Fish, 10 = Rise, 11 = FishEye,
                                        12 = Inflate, 13 = Squeeze, 14 = Twist */
            warpAmount: 50,          /* percentage */
            isVertical: false,       /* if true, effect goes on the other axis */
            deformHorizontal: 0,     /* percentage */
            deformVertical: 0,       /* percentage */
            expandAppearance: false
        };
        var o = LE.defaultsObject(item, defaults, options, arguments.callee)
        o.warpName = ['Arc', 'ArcLower', 'ArcUpper', 'Arch', 'Bulge', 'ShellLower', 'ShellUpper', 'Flag', 'Wave', 'Fish', 'Rise', 'FishEye', 'Inflate', 'Squeeze', 'Twist'][o.warpType];
        var xml = '<LiveEffect name="Adobe Deform"><Dict data="S DisplayString Warp:#1 I DeformStyle #2 B Rotate #3 R DeformValue #4 R DeformHoriz #5 R DeformVert #6 "/></LiveEffect>'
            .replace(/#1/, o.warpName)
            .replace(/#2/, o.warpType + 1)
            .replace(/#3/, o.isVertical ? 1 : 0)
            .replace(/#4/, o.warpAmount / 100)
            .replace(/#5/, o.deformHorizontal / 100)
            .replace(/#6/, o.deformVertical / 100);
        LE.applyEffect(item, xml, o.expandAppearance);
    } catch (error) {
        LE.handleError(error);
    }
}


// this is where you should play around

var warpOptions = {
    warpAmount: 100,         /* percentage */
    isVertical: false,       /* if true, effect goes on the other axis */
    deformHorizontal: 0,     /* percentage */
    deformVertical: 0,       /* percentage */
    expandAppearance: false  /* expand after applying effect */
};

var items = app.activeDocument.selection;
// loop over all selected items
for (var i = 0; i < items.length; i++) {
    var item = items[i];
    LE_Warp_Wave(item, warpOptions)
}

 

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Valorous Hero ,
Feb 08, 2022 Feb 08, 2022

@m1b has the scripting answer. To help clear up your original difficulties, the fact of the matter is - yes, the graphic style must be present in the document. It is easy to import a graphic style by opening up a document with a shape that has this style applied to it and copy-pasting it into your work document. The named graphic style will now appear in the document palette. At this point your action will be able to apply this style by name.
This process can be automated by recording a file-open action which always opens up the same file which contains your graphic style shape and does the pasting process. (Also maybe delete the pasted path immediately to clean up.)

As long as the action only opens, selects and copies, it can also close that document without changes and not block your batch action processing with a dialog alert.

 

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Feb 08, 2022 Feb 08, 2022

Thank you both.

 

I literally two weeks ago solved the problem of applying custom brush to some strokes in document by having the original document with tiny path with brush applied and copy pasting it in the new document as it opens in batch run.

 

I thought I can do the same, just copy paste object with graphic style somewhere around the artboard and then select graphic style.  But problem is now I need to have two items copied.

In files I have lines with black stroke and objects with black fill.

I have black dot in clipboard so the action can run the paste to back function and then "select same stroke color" option and then apply effect only on those selected.

Maybe if the object I am copy pasting has black stroke AND effect applied it will work for both then copy pasting it will bring that effect style in to the document PLUS I will be able to select only objects with same appearance and apply effect on them.

 

Regarding script, not sure how would I be able to smash combine my additional steps in to it (scale transform of everything, expand and fit to selected art). 

I will definitely try the copy pasting now and let you know did it work.

 

 

 

 

 

 

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Feb 08, 2022 Feb 08, 2022

Can you just have both items on the clipboard? When you paste two items, both graphic styles will appear.

- Mark

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Feb 09, 2022 Feb 09, 2022

Marinapomorac_1-1644400182353.png

 

I tried to copy paste graphic style but it changes all the shapes stroke color.
My image explanation:
1. This is my starting point. I have rectangles in two shades stroke, no fill and star with no stroke black fill

2. Select all objects with stroke (any stroke) and apply Distort or Effect on them without changing their stroke or fill
3. Select all objects on artboard and apply Distort or Effect on them without changing their stroke or fill
4. Select all objects with black stroke only and apply Distort or Effect on them without changing their stroke or fill

I "resolved" #2 by recording action where I have dummy file open and one small path in it with same stroke weight as in all the documents. I copy that to clipboard and then action goes:
a) paste in back
b) select same stroke weight
c) group
d) apply effect
e) expand appearance
f) Fit to selected art
g) save
h) close
and then I run action with clickin OK everytime at step d)
#3 is same just select all on artboard instead of steps a) and b)
#4 I have in open dummy file path with black stroke and I copy that to clipboard and then 
a) paste
b) select same stroke color
end the rest of the action is the same.

The only issue is the asking me to confirm the effect charateristics with OK for each file.

When I copy path that has effect on it and saved Graphic style in cases above it changes all objects stroke/fill color. 
Can you have just effect as Graphic style so it doesnt change the stroke and fill to objects?

And another question. I am looking at programs that simulate clicking of enter or any key on keyboard every specified time. I am thinking starting action and running that program that clicks ENTER every 5 seconds.
Not sure does that program exist and will it work with Adobe running.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Feb 09, 2022 Feb 09, 2022

UPDATE
I found Autohotkey and set script that clicks ENTER every 8 seconds and it works for Warp Effects but not Distort.

So I set my actions as above and after first effect window pops up in action I set the value and H/V and then I run ENTER timer script. It clicks enter every 8 seconds in Adobe and action works.

But for Distort, if I set distort to 36% unlike warp when new window pops up for distort it is revertet back to default 5%. So this combo of action + Enter key timer script is only good for Warp effect where AI keeps the previous settings in new window, but for Distort it flops. 

 

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Valorous Hero ,
Feb 09, 2022 Feb 09, 2022

Try using WindowSpy to see if you can differentiate the Illustrator dialogs by something in their title.
Then you would be able to use hard-coded conditional statements or text-based 'data packages' (of text) to get a handle on a set of dialog inputs appropriate for the one at hand, and send any tab & other keys to fill out the dialog dynamically.

SillyV_0-1644407365730.png

 

Also what do you mean by "Distort"? There's a Free Distort which is a rectangle-based control.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Valorous Hero ,
Feb 09, 2022 Feb 09, 2022

How about this: it may be possible to add a new graphic style with an action (I think I have previously done this, it has to be recorded with or without the Alt key or something) so that the new graphic style is coming from some selected art. Its new name will be an Illustrator-generated new default name "Graphic Style 1", etc.


Basically if you can make the new graphic styles appear, a follow-up script ought to be able to rename it to a custom name or take note of its name, record its name in some pathItem's notes, etc. It would also be able to apply it to things, it just all depends on how you wish to have the scripts and actions work together. 

 

An important rule to watch out for is that an action that plays a script which plays an action will cause Illustrator to crash, so either use a script that starts you out and can play actions or is using "actions-first" approach start with such an action that plays scripts and does anything that a script can't do but it can only do it with an action, between the scripts.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Feb 09, 2022 Feb 09, 2022

I checked, Graphic style won't work here at all since "graphic style is an all or nothing" .
There are two types of Graphic Styles - Group Styles and Object Styles.
In my case group styles should work, but they do not.

So at the moment the solution is to run action with asking me to OK the effect and run Autohotkey action that will click enter every x seconds. 
That is for Warp effects that memorises previous settings, for distort I have to see can default settings be fixed and changed before running action.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Valorous Hero ,
Feb 09, 2022 Feb 09, 2022

Well yea, that's where the script would have to necessarily apply the style just to the items you need.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Feb 09, 2022 Feb 09, 2022

Distort: 

Marinapomorac_0-1644407485715.png

Marinapomorac_1-1644407508375.png

Marinapomorac_2-1644407550278.png

 

Warp keeps previous settings, distort reverts to 5%.

 

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Feb 09, 2022 Feb 09, 2022

I feel like a freaking genius right now 😄 😄 😄

OK. So hold your horses and get ready to turn grey hair here (to all AI experts that will have facepalm moment after reading this, I am sorry, but until Adobe figures something better..)

I solved the warp by creating AutohotKey script that presses ENTER every 5 seconds (or how long it takes AI to process image, I check once and then adjust timing.
For Distort I created script that types number (AHA!) and presses enter so I get number in distor percentage box written and enter to apply the effect. 

Just tested it with 42 and it does exactly as planned, AI opens up roughen window, script types 42 and enter. And then AI continues with action.


Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Feb 09, 2022 Feb 09, 2022

You did it! 🙂

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Valorous Hero ,
Feb 09, 2022 Feb 09, 2022

Great work! You can get even fancier with the AHK by using an image-search to look for certain dialogs by using a screenshot of a part of those dialogs, or do a loop that checks if the win active title is "Warp Effect" or something - that way the timing would be all automatic.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Feb 09, 2022 Feb 09, 2022

I just discovered wheel and you are showing me blueprints of a Ferrari 😄
Jokes aside, it would be great to not guess the timing but to have it run and type as the window pops up.
Any link with useable tutorial I can follow to make something like what you describe?
So for example for script to recognize these two windows (at separate times) and place settings, how would the script for hotkey look like?

Marinapomorac_0-1644410140922.png

Marinapomorac_1-1644410182851.png

 






Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Valorous Hero ,
Feb 09, 2022 Feb 09, 2022
LATEST

Check out the material by Joe Glines at https://www.the-automator.com/

Here is an example which is a script that is only good for one of your dialogs. To do another dialog, another such script has to be created and launched.

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
#SingleInstance, Force
; #Warn  ; Enable warnings to assist with detecting common errors.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.
SetTitleMatchMode, 2

WinWait, Warp Options ; Set the wait for a window to pop up with the title "Warp Options". (It could be any app, be aware, unless more code is added to filter these things)
If ErrorLevel {
	MsgBox, Something went wrong.
	Exit
} Else {
	MsgBox, Here in Warp dialog!
	Sleep, 1000 ; Better make the changes in less than 1 second, or change this number here.
	reload
}

; Only ONE WinWait will work at a time, because they block each other. This one will have to be put into a different script.
;
; WinWait, Zig Zag ; Set the wait for a window to pop up with the title "Zig Zag".
; If ErrorLevel {
; 	MsgBox, Something went wrong.
; 	Exit
; } Else {
; 	MsgBox, Here in Zig Zag dialog!
; 	Sleep, 1000 ; Better make the changes in less than 1 second, or change this number here.
; 	reload
; }

#ifwinactive, AiEffectDialogs.ahk ; This makes AHK reload this script when it is saved in a code editor.
~^s::
reload
return
#ifwinactive

The next step would be to try and not have multiple scripts, but to implement the solution found here https://www.autohotkey.com/board/topic/21533-multiple-winwait-at-once/page-2 so that an activation of an application will file some even that some thing can listen and read a window title at that time.. But that's all the time I have for right now for this.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines