Core Concepts

Add-On Packages: Keeping GPAL Light

Why Some Capabilities Live Apart

Image matching needs OpenCV, and OpenCV brings about 90 MB of native libraries with it. Most workflows find elements by CSS, XPath or UIAutomation and never match a picture, so carrying that weight in every program would be a cost with nothing to show for it.

So GPAL itself stays light, and a capability like this ships as an add-on package. GPAL knows how to use it and calls on it when a workflow asks, but the library behind it arrives only in the programs that add the package.

NOTE

An image selector is written the same way with or without the package. The package decides whether the match can be made, not how the workflow is written.

Adding and Registering a Package

Add the package to the project, then register it once at startup, before the first time it is needed. For image matching that is the GPAL.Image package and one call to GPALImage.Register(). From then on every image selector, and ImageHelper.FindImage, uses it.

using GenerallyPositive;

using GenerallyPositive.Image;


// once, at startup, before the first image selector runs

GPALImage.Register();


Selector logo = GPAL.Selector

.WithImage((GPALFile)@"C: emplateslogo.png")

.ToGPALObject();

NOTE

If an image selector runs and nothing is registered, GPAL publishes one warning saying the GPAL.Image package is needed, and the selector finds nothing, the same as any selector with no match. The workflow keeps running and decides what to do, through CallIfNotFound or its own checks.

WARNING

OpenCV ships its native library for 64-bit Windows only, so a 32-bit process cannot load it. An AnyCPU program runs 32-bit when Prefer 32-bit is on, which is the default for a new project. Turn it off in the project's build settings, or target x64. In a 32-bit process GPALImage.Register() registers nothing and publishes a warning saying so.

Behind the Registration

GPALImage.Register() hands GPAL an image matcher: an object implementing IImageMatcher, which takes a capture of the screen or the browser, the picture to find, and how close a match has to be, and returns where the picture is. GPAL.RegisterImageMatcher is the call that receives it.

A workflow never calls RegisterImageMatcher itself, since the package does it. It is there so the matching can be swapped: a matcher of your own, registered the same way, is used by every image selector in its place.

OCR will return the same way, as its own package with its own Register() call.

public interface IImageMatcher

{

Rectangle FindImage(Bitmap screen, string templatePath, int matchingPercentage);

}


// what GPALImage.Register() does

GPAL.RegisterImageMatcher(new OpenCvImageMatcher());

NOTE

Registering again replaces the matcher that was there. Call it once near the top of the program rather than before each use.

💬 Ask GPAL