Can .sikuli project be run from Java code?

Asked by NoBugs!

I've been using Sikulix IDE and it is really great at what it does, you can adjust matching click area, etc. and it's awesome!. However, it does seem quite slow when calling up Sikuli script from a standard Python script. (Selenium and other modules aren't available in Jython).

I've looked at the tutorial and the Javadocs, but I don't see anything that specifically lets you run a .sikuli project's py file from Java. Is there a way to do this so running .sikuli project repeatedly won't be slow starting up Java each time, OR a way to migrate .sikuli IDE project to Java without losing the image matching adjustment tools and stuff from Sikuli-IDE?

Thanks for a great program :)

Question information

Revision history for this message
NoBugs! (luke32j) said :
#1

I think I found the relevant code in Sikuli source code:
http://bazaar.launchpad.net/~sikuli-driver/sikuli/sikuli.git/view/head:/sikuli-ide/src/main/java/org/sikuli/ide/SikuliIDE.java

      protected void runPython(File f) throws Exception{
         ScriptRunner srunner = new ScriptRunner(getPyArgs());
         try{
            String path = SikuliIDE.getInstance().getCurrentBundlePath();
            srunner.addTempHeader("initSikuli()");
            srunner.runPython(path, f);
            srunner.close();
         }
         catch(Exception e){
            srunner.close();
            throw e;
         }
      }

So it looks like ScriptRunner is the class to use - unfortunately it's missing javadoc comments.
http://doc.sikuli.org/javadoc/

Revision history for this message
RaiMan (raimund-hocke) said :
#2

The startup of the JVM is not the reason for the delay, when starting a script from scratch.
Any method that starts a script from scratch will have this delay of 3 to 5 seconds due to the setup of the Jython/SikuliX runtime environment.

In the IDE a smaller part of this setup is done at IDE start and the rest when any script in this IDE session is run the first time.
the 2nd+ scriptrun reuses the existing Jython/SikuliX runtime environment and hence starts with no significant delay.
There is no API available currently, to use this "run a script in existing Jython/SikuliX environment" feature from outside, since all this is hard wired in the IDE code.

The code you found above is not supported any more for such specific things (old version).

So if you want to try something out your own, you should have a look into the actual version 1.1.0:
https://github.com/RaiMan/SikuliX-2014

The relevant features are in the package org.sikuli.scriptrunner in the IDE subproject.
But I have to apologise for little Javadocs at this level.
I have enough to do, to keep the public API docs up to date, not to talk about the top level docs ;-)

In version 2, I will split the IDE into some sub-services, so the SikuliX specific features like sript run and image handling will be useable in other environments too in an efficient way.

see next comment about Java coding and image handling.

Revision history for this message
RaiMan (raimund-hocke) said :
#3

This is an approach, to efficiently combine Java coding with SikuliX features and the SikuliX IDE support.

- have the complete image handling in the IDE, just setting up scripts only containing images
such a script will simply be a list of image file names.
The images are then available in the folder you-name-it.sikuli

- now you code in Java and access the images using setBundlePath() or more efficiently using the ImagePath features.
For these high level features some useable docs are available (start here: http://sikulix.com).

One caveat:
In the IDE you have the Preview feature, that lets you adjust the minimum similarity and the targetOffset resulting in a script code with this template:
Pattern("some-image.png").similar(n.nn).targetOffset(x, y) or
Pattern("some-image.png").exact().targetOffset(x, y) (which is a shortcut for similar(0.99))

So if you use the IDE Preview feature in this case, you will not have access in your Java code to the Pattern definitions, only the images and would have to define the Patterns on the Java level again (at least copy&paste could be used).

A helper in this situation would be some Java feature like this:
a class, that creates some image/pattern container, that analyses the script.py and allows to dynamically access the definitions:

ImageContainer myImages = new ImageContainer("path-to-some.sikuli")

and then use this:
Screen score = new Screen()
Match m = scr.find(myImages.get("somenameXYZ"))

where for the sake of simplicity ImageContainer.get() should simply return a dynamically created Pattern object in any case.

the script path-to-some.sikuli content:
somename1 = "someImage.png"
somename2 = Pattern("some-image.png").similar(n.nn).targetOffset(x, y)
... and more

which would be easy to scan using pattern matching together with some container map to store the attributes.

I guess the whole class will have about 20 - 30 lines of code and could even be used to reuse the image and pattern definitions in existing scripts, that are migrated to Java (in which case the ref-names might be the line number of the line the image ore pattern is defined if no name = is used.

I am just wondering, why not already someone has done and talked about this ;-)

Can you help with this problem?

Provide an answer of your own, or ask NoBugs! for more information if necessary.

To post a message you must log in.