Jump to content

1 Screenshot

About This File

ImageSearchDLL - Ultra-Fast Image Search

Overview

ImageSearchDLL is a high-performance dynamic link library (DLL) designed for ultra-fast image searching on the screen, within other images, or using bitmap handles. It leverages SIMD instructions (SSE2, AVX2, AVX512) for optimized performance and includes features like caching, scaling, tolerance matching, and integrated mouse click functionality. The DLL is compatible with Windows environments and supports both 32-bit (x86) and 64-bit (x64) architectures.

  • Author: Dao Van Trong - TRONG.PRO
  • DLL Version: v3.3
  • License: MIT

Two variants are provided:

  • ImageSearchDLL_XP.cpp: C++03 compatible, supports Windows XP+ (legacy systems).
  • ImageSearchDLL.cpp: Using modern c++, only supported from Win 7 SP1 (AVX2/AVX512 support on x64).

Support My Work

Enjoy my work? Buy me a 🍻 or tip via ❤️ PayPal

Your support helps me continue developing and maintaining this library for the community! 🙏

Features

  • Ultra-Fast Search: Uses SIMD-accelerated algorithms for rapid pixel matching.
  • Search Modes:
    • Screen search (capture and search on desktop or specific monitors).
    • Image-in-image search.
    • HBITMAP-based search.
  • Scaling Support: Search with variable scales (min/max scale, step size).
  • Tolerance Matching: Adjustable color tolerance for fuzzy matches.
  • Transparency Handling: Optional alpha channel support.
  • Caching System:
    • In-memory LRU cache for locations and bitmaps
    • Persistent disk cache (survives DLL reload)
    • Optional cache control via iUseCache parameter
    • Automatic cache validation and cleanup
  • Multi-Monitor Support: Handles virtual screens and specific monitors.
  • Mouse Click Integration: Click at found positions or windows with customizable speed and buttons.
  • Debug Output: Optional detailed debug information in results.
  • System Info: Retrieve CPU features, screen details, and cache status.
  • Pool Management: Efficient memory pooling for pixel buffers.

Requirements

  • Operating System:
    • XP Version: Windows XP or later.
    • Modern Version: Windows 7 or later (recommended for AVX support).
  • Compiler: Microsoft Visual C++ (MSVC) or compatible.
  • Dependencies: GDI+ (included in Windows), no external libraries needed.
  • CPU: SSE2 required for basic functionality; AVX2/AVX512 for enhanced performance on x64.

For AutoIt Users

⚠️ AutoIt users should use the UDF wrapper instead of calling DLL directly.

The ImageSearchDLL_UDF.au3 wrapper provides:

  • Easy-to-use functions with AutoIt-friendly syntax
  • Automatic error handling and validation
  • Multi-monitor support with WinAPI fallback (v3.3)
  • Built-in monitor enumeration and coordinate conversion
  • Reliable mouse operations on all configurations

👉 See README_UDF.md for AutoIt documentation and examples.

Installation (C++/Other Languages)

  1. Build the DLL:

    • Open the .cpp file in Visual Studio.
    • Set platform to x86 or x64.
    • Build as a DLL project.
    • Output: ImageSearchDLL_x64.dll or ImageSearchDLL_x86.dll
  2. Usage in Code:

    • Load the DLL dynamically using LoadLibraryW.
    • Get function pointers with GetProcAddress.
    • See C++ examples below.

API Reference

The DLL exports several functions. All string parameters are wide strings (wchar_t*). Results are returned as const wchar_t* strings in formats like {error_code}[results]<error_message> or 1|x|y|w|h|scale|source for successful matches.

Core Search Functions

  • const wchar_t* WINAPI ImageSearch(const wchar_t* sImageFile, int iLeft=0, int iTop=0, int iRight=0, int iBottom=0, int iScreen=0, int iTolerance=10, int iResults=1, int iCenterPOS=1, float fMinScale=1.0f, float fMaxScale=1.0f, float fScaleStep=0.1f, int iReturnDebug=0, int iUseCache=0)

    • Searches for image(s) on the screen.
    • sImageFile: Path to target image(s), supports wildcards (e.g., *img*.png).
    • Region: iLeft, iTop, iRight, iBottom (0 for full screen).
    • iScreen: Monitor index (1-based; 0 for primary, negative for virtual).
    • iUseCache: 0=disabled (default), 1=enabled (use persistent cache).
    • Returns: Number of matches followed by details, or error.
  • const wchar_t* WINAPI ImageSearch_InImage(const wchar_t* sSourceImageFile, const wchar_t* sTargetImageFile, int iTolerance=10, int iResults=1, int iCenterPOS=1, float fMinScale=1.0f, float fMaxScale=1.0f, float fScaleStep=0.1f, int iReturnDebug=0, int iUseCache=0)

    • Searches for target image within a source image file.
    • iUseCache: 0=disabled (default), 1=enabled (use persistent cache).
  • const wchar_t* WINAPI ImageSearch_hBitmap(HBITMAP hBitmapSource, HBITMAP hBitmapTarget, int iTolerance, int iLeft, int iTop, int iRight, int iBottom, int iResults=1, int iCenter=1, float fMinScale=1.0f, float fMaxScale=1.0f, float fScaleStep=0.1f, int iReturnDebug=0, int iUseCache=0)

    • Searches using bitmap handles.
    • iUseCache: 0=disabled (default), 1=enabled (use persistent cache).

Utility Functions

  • HBITMAP WINAPI ImageSearch_CaptureScreen(int iLeft=0, int iTop=0, int iRight=0, int iBottom=0, int iScreen=0)

    • Captures a screen region as HBITMAP.
  • HBITMAP WINAPI ImageSearch_hBitmapLoad(const wchar_t* sImageFile, int iAlpha=0, int iRed=0, int iGreen=0, int iBlue=0)

    • Loads image as HBITMAP with optional background color.
  • void WINAPI ImageSearch_ClearCache()

    • Clears location and bitmap caches.
  • const wchar_t* WINAPI ImageSearch_GetVersion()

    • Returns DLL version string.
  • const wchar_t* WINAPI ImageSearch_GetSysInfo()

    • Returns system info (CPU features, screen size, cache stats).

Mouse Click Functions

  • int WINAPI ImageSearch_MouseMove(int iX, int iY, int iSpeed, int iScreen)

    • Moves mouse cursor to screen coordinates.
    • Returns: 1 on success, 0 on failure.
    • Note: UDF v3.3 uses WinAPI fallback for reliable multi-monitor support.
  • int WINAPI ImageSearch_MouseClick(const wchar_t* sButton, int iX, int iY, int iClicks, int iSpeed, int iScreen)

    • Clicks at screen coordinates.
    • sButton: "left", "right", "middle" (case-insensitive).
    • iX, iY: Virtual desktop coordinates (supports negative values for multi-monitor).
    • iScreen: Monitor index (-1=all, 1=first, 2=second, etc.).
    • Returns: 1 on success, 0 on failure.
    • Note: UDF v3.3 uses WinAPI fallback for reliable multi-monitor support.
  • int WINAPI ImageSearch_MouseClickWin(const wchar_t* sTitle, const wchar_t* sText, int iX, int iY, const wchar_t* sButton, int iClicks, int iSpeed)

    • Clicks relative to a window (found by title/text).
    • Returns: 1 on success, 0 on failure.

Usage Examples

C++ Example: Basic Screen Search

#include <windows.h>
#include <iostream>

typedef const wchar_t* (WINAPI* PFN_ImageSearch)(
    const wchar_t*, int, int, int, int, int, int, int, int, 
    float, float, float, int, int);

int main() {
    // Load DLL
    HMODULE hDll = LoadLibraryW(L"ImageSearchDLL_x64.dll");
    if (!hDll) {
        std::wcerr << L"Failed to load DLL" << std::endl;
        return 1;
    }

    // Get function pointer
    auto pImageSearch = (PFN_ImageSearch)GetProcAddress(hDll, "ImageSearch");
    if (!pImageSearch) {
        std::wcerr << L"Failed to get ImageSearch function" << std::endl;
        FreeLibrary(hDll);
        return 1;
    }

    // Call ImageSearch
    const wchar_t* result = pImageSearch(
        L"target.png",  // Image path
        0, 0,           // Left, Top (0 = full screen)
        1920, 1080,     // Right, Bottom
        -1,             // Screen (-1 = all monitors)
        10,             // Tolerance
        1,              // Max results
        1,              // Center position
        1.0f, 1.0f,     // Min/Max scale
        0.1f,           // Scale step
        1,              // Debug output
        0               // Cache disabled
    );

    std::wcout << L"Result: " << result << std::endl;

    // Parse result: {count}[x|y|w|h,...](debug info)
    // Example: {1}[640|480|32|32](time=50ms...)

    FreeLibrary(hDll);
    return 0;
}

C++ Example: Image-in-Image Search

#include <windows.h>
#include <iostream>

typedef const wchar_t* (WINAPI* PFN_ImageSearch_InImage)(
    const wchar_t*, const wchar_t*, int, int, int, 
    float, float, float, int, int);

int main() {
    HMODULE hDll = LoadLibraryW(L"ImageSearchDLL_x64.dll");
    if (!hDll) return 1;

    auto pFunc = (PFN_ImageSearch_InImage)GetProcAddress(hDll, "ImageSearch_InImage");
    if (!pFunc) {
        FreeLibrary(hDll);
        return 1;
    }

    const wchar_t* result = pFunc(
        L"screenshot.png",  // Source image
        L"button.png",      // Target image to find
        15,                 // Tolerance
        5,                  // Max results
        1,                  // Center position
        1.0f, 1.0f, 0.1f,  // Scale parameters
        1,                  // Debug
        0                   // Cache
    );

    std::wcout << L"Result: " << result << std::endl;

    FreeLibrary(hDll);
    return 0;
}

C++ Example: HBITMAP Search

#include <windows.h>
#include <iostream>
#include <gdiplus.h>

typedef const wchar_t* (WINAPI* PFN_ImageSearch_hBitmap)(
    HBITMAP, HBITMAP, int, int, int, int, int, int, int, 
    float, float, float, int, int);

int main() {
    HMODULE hDll = LoadLibraryW(L"ImageSearchDLL_x64.dll");
    if (!hDll) return 1;

    auto pFunc = (PFN_ImageSearch_hBitmap)GetProcAddress(hDll, "ImageSearch_hBitmap");
    if (!pFunc) {
        FreeLibrary(hDll);
        return 1;
    }

    // Load bitmaps (pseudo-code, use GDI+ or other methods)
    HBITMAP hSource = LoadBitmapFromFile(L"screenshot.bmp");
    HBITMAP hTarget = LoadBitmapFromFile(L"icon.bmp");

    const wchar_t* result = pFunc(
        hSource, hTarget,   // Source and target bitmaps
        10,                 // Tolerance
        0, 0, 0, 0,        // Search region (0 = entire source)
        1,                  // Max results
        1,                  // Center position
        1.0f, 1.0f, 0.1f,  // Scale
        1,                  // Debug
        0                   // Cache
    );

    std::wcout << L"Result: " << result << std::endl;

    DeleteObject(hSource);
    DeleteObject(hTarget);
    FreeLibrary(hDll);
    return 0;
}

Result Format

Results start with {code} for errors (e.g., {-1}[]<Invalid path or image format>). Positive numbers indicate match count.

Performance Tips

Search Performance

  • Enable Caching: Set iUseCache=1 for repeated searches (30-50% faster)
  • Cache Benefits:
    • In-memory cache: Instant lookup for recent searches
    • Disk cache: Persists across DLL reloads
    • Auto-validation: Removes stale entries after 3 misses
  • Adjust Tolerance: Higher tolerance = faster but less accurate
  • Scale Steps: Larger steps = faster but may miss matches
  • SIMD Support: On x64, ensure AVX2/AVX512 for best performance
  • Memory Pool: Automatic optimization, no manual tuning needed

Multi-Monitor Setup

  • Specific Monitor Search: Use iScreen=1 or iScreen=2 for 2-3x faster search
  • Virtual Desktop: Use iScreen=-1 to search across all monitors
  • Coordinate System: DLL returns virtual desktop coordinates (may be negative)
  • Mouse Operations: Use UDF v3.3 for reliable mouse movement/clicking on all monitors

Limitations

DLL Limitations

  • Max results: 1024
  • Image size limit: 32000x32000 pixels
  • Max pixel count: 100M pixels per image
  • Cache limits: 100 locations, 100 bitmaps (LRU eviction)
  • Thread-safe but single DLL instance recommended per process

Known Issues (DLL v3.3)

  • Mouse Functions: DLL mouse functions may not work reliably on multi-monitor setups
    • Solution: Use UDF v3.3 which provides WinAPI-based fallback
    • Impact: Mouse operations now 100% reliable on all monitor configurations
  • Negative Coordinates: DLL returns negative coords for monitors positioned left/above primary
    • Solution: UDF v3.3 handles this correctly with SetCursorPos

Related Documentation

  • README_UDF.md - AutoIt wrapper documentation with examples
  • ImageSearchDLL_UDF.au3 - AutoIt wrapper source code
  • ImageSearchDLL_TestSuite.au3 - Interactive GUI test application

Contributing & Support

For issues, contributions, or commercial licensing:


For AutoIt users: See README_UDF.md for easy-to-use wrapper functions and AutoIt examples.

Thank you for using ImageSearchDLL! 🚀

Edited by Trong
Update document!


What's New in Version v3.3

Released

💢 Note: There are a lot of changes that break the script (DLL &UDF)! 👈


User Feedback

Recommended Comments

OhItsThatGuy

Posted

Hi Trong, I love your work! Clean code, easy to read and use. I checked out your other projects as well!

Regarding your ImageSearch library, can I make a small request?

Having a scan function that can take a bitmap handle would be amazing. This would allow a finer control by eliminating the need to force a re-scan on each iteration of _ImageSearch(..)

_ImageSearch_ScanSnapshot($hImage = -1, $sImageFile, $iLeft = 0, $iTop = 0, $iRight = @DesktopWidth, $iBottom = @DesktopHeight, $iTolerance = 10, $iTransparent = -1, $iMultiResults = 1, $iCenterPos = 1, $iReturnDebug = 1, $fMinScale = 1.0, $fMaxScale = 1.0, $fScaleStep = 0.1, $iFindAllOccurrences = 0)

 

I realize we can use a delimiter | to search for multiple images but there are situations where a user would want to break images into categories and run different tolerance for each set, as well as focus on a particular area of the screen for each set.

We can take a snap shot using GDI+ through AutoIt as such:

Func _Img_TakeSnapshot($_iCanvasLeft=0,$_iCanvasTop=0,$_iCanvasWidth=@DesktopWidth,$_iCanvasHeight=@DesktopHeight)

    ; Clean up resources
    _GDIPlus_BitmapDispose($g_myImg_hImage)
    _WinAPI_DeleteObject($g_myImg_hMatWinCapture)

    ; Screen grab an area (should ideally be full screen)
    ; Use _Img_ScanSnapshotArea to scan

    ; Capture entire desktop or selected area
    $g_myImg_hMatWinCapture = _ScreenCapture_Capture("", $_iCanvasLeft, $_iCanvasTop, $_iCanvasWidth, $_iCanvasHeight, False)

    ; Create a Bitmap object from a bitmap handle (Using previously taken SnapShot)
    $g_myImg_hImage = _GDIPlus_BitmapCreateFromHBITMAP($g_myImg_hMatWinCapture)

    ; Save last scanned box dimensions
    $g_myImg_aAreaLastScan[0] = $_iCanvasLeft                           ; X Left Upper
    $g_myImg_aAreaLastScan[1] = $_iCanvasTop                            ; Y Left Upper
    $g_myImg_aAreaLastScan[2] = $_iCanvasLeft + $_iCanvasWidth          ; X Right Lower
    $g_myImg_aAreaLastScan[3] = $_iCanvasTop + $_iCanvasHeight          ; Y Right Lower
    $g_myImg_aAreaLastScan[4] = $_iCanvasWidth                          ; Box Width
    $g_myImg_aAreaLastScan[5] = $_iCanvasHeight                         ; Box Height

    ; Debug
    ;If $g_myImg_bDebugConsole = True Then ConsoleWrite("+ Snapshot:: (" & $_iCanvasLeft & ", " & $_iCanvasTop & ", " & $_iCanvasWidth & ", " & $_iCanvasHeight & ")" & @CRLF)

EndFunc

Or perhaps that can be handled by the dll. Those are just my thoughts, I'm not an expert a this.

Thank you for putting together this amazing UDF!

tubaba

Posted

First of all, thank you for providing a great user experience. However, I do have an issue to bring up. It seems that your DLL automatically corrects parts that exceed the screen, confining them within the frame of 0,0,@DesktopWidth,@DesktopHeight. But there are many application scenarios with multiple screens, which means that screen coordinates should not be limited to the range of the first screen. In earlier versions, I found that the coordinate correction was done in the UDF.

1.thumb.png.e0948e0023942a08c11910f8814928f1.png

tubaba

Posted

 

Get information of all screens

Global $__MonitorList[1][5], $__MonitorListBase[1][5]
$__MonitorListBase[0][0] = 0



_GetMonitors()



Func  _GetMonitors()
    $__MonitorList = $__MonitorListBase
    Local $handle = DllCallbackRegister("_MonitorEnumProc", "int", "hwnd;hwnd;ptr;lparam")
    DllCall("user32.dll", "int", "EnumDisplayMonitors", "hwnd", 0, "ptr", 0, "ptr", DllCallbackGetPtr($handle), "lparam", 0)
    DllCallbackFree($handle)
EndFunc   ;==>_GetMonitors

Func _MonitorEnumProc($hMonitor, $hDC, $lRect, $lParam)
    Local $Rect = DllStructCreate("int left;int top;int right;int bottom", $lRect)
    $__MonitorList[0][0] += 1
    ReDim $__MonitorList[$__MonitorList[0][0] + 1][5]
    $__MonitorList[$__MonitorList[0][0]][0] = $hMonitor
    $__MonitorList[$__MonitorList[0][0]][1] = DllStructGetData($Rect, "left")
    $__MonitorList[$__MonitorList[0][0]][2] = DllStructGetData($Rect, "top")
    $__MonitorList[$__MonitorList[0][0]][3] = DllStructGetData($Rect, "right")
    $__MonitorList[$__MonitorList[0][0]][4] = DllStructGetData($Rect, "bottom")
    Return 1 ; Return 1 to continue enumeration
EndFunc   ;==>_MonitorEnumProc

 

tubaba

Posted

Scene Setup:
The user has two monitors. The primary monitor has a resolution of 1920×1080, corresponding to coordinates Left: 0, Top: 0, Right: 1920, Bottom: 1080.
The secondary monitor has a resolution of 1600×900, corresponding to coordinates Left: –1600, Top: 0, Right: 0, Bottom: 900.
The same image is searched sequentially across both monitors.


Test 1 – Target image present on both monitors: result returned correctly.
- Search Area: Left[0],Top[0],Right[1920],Bottom[1080]
>> DLL Return: {1}[274|195|28|30](time=109ms, backend=SSE2, Source=1920x1080, files=1, cache_hits=0, cache_misses=0, tolerance=10, scale=1-1:0.1, cpu=SSE2:Y, capture=0|0|1920|1080|1920x1080, screen=0)
- Search Area: Left[-1600],Top[0],Right[0],Bottom[900]
>> DLL Return: {1}[-1488|130|28|30](time=125ms, backend=SSE2, Source=3520x900, files=1, cache_hits=0, cache_misses=0, tolerance=10, scale=1-1:0.1, cpu=SSE2:Y, capture=-1600|0|0|900|1600x900, screen=0)
Found 2 match(es)!
Match #1 found at: 274, 195
Match #2 found at: -1488, 130


Test 2 – Target image absent on primary monitor but present on secondary: result returned correctly.
- Search Area: Left[0],Top[0],Right[1920],Bottom[1080]
>> DLL Return: {0}[](time=172ms, backend=SSE2, Source=1920x1080, files=1, cache_hits=0, cache_misses=0, tolerance=10, scale=1-1:0.1, cpu=SSE2:Y, capture=0|0|1920|1080|1920x1080, screen=0)
!> UDF ERROR: Invalid format from DLL. Could not find '{...}' and '[...]' parts.
- Search Area: Left[-1600],Top[0],Right[0],Bottom[900]
>> DLL Return: {1}[-1488|130|28|30](time=156ms, backend=SSE2, Source=3520x900, files=1, cache_hits=0, cache_misses=0, tolerance=10, scale=1-1:0.1, cpu=SSE2:Y, capture=-1600|0|0|900|1600x900, screen=0)
Found 1 match(es)!
Match #1 found at: -1488, 130


Test 3 – Target image present on primary monitor but absent on secondary: result returned incorrectly.
- Search Area: Left[0],Top[0],Right[1920],Bottom[1080]
>> DLL Return: {1}[274|195|28|30](time=94ms, backend=SSE2, Source=1920x1080, files=1, cache_hits=0, cache_misses=0, tolerance=10, scale=1-1:0.1, cpu=SSE2:Y, capture=0|0|1920|1080|1920x1080, screen=0)
- Search Area: Left[-1600],Top[0],Right[0],Bottom[900]
>> DLL Return: {1}[274|195|28|30](time=156ms, backend=SSE2, Source=3520x900, files=1, cache_hits=0, cache_misses=0, tolerance=10, scale=1-1:0.1, cpu=SSE2:Y, capture=-1600|0|0|900|1600x900, screen=0)
Found 2 match(es)!
Match #1 found at: 274, 195
Match #2 found at: 274, 195

2025-10-31_112041.thumb.png.d7f20d457630c98ea255e59f881f3ee7.png

out of range

 


Test 4 – Target image absent on both monitors: result returned correctly.
- Search Area: Left[0],Top[0],Right[1920],Bottom[1080]
>> DLL Return: {0}[](time=141ms, backend=SSE2, Source=1920x1080, files=1, cache_hits=0, cache_misses=0, tolerance=10, scale=1-1:0.1, cpu=SSE2:Y, capture=0|0|1920|1080|1920x1080, screen=0)
!> UDF ERROR: Invalid format from DLL. Could not find '{...}' and '[...]' parts.
- Search Area: Left[-1600],Top[0],Right[0],Bottom[900]
>> DLL Return: {0}[](time=203ms, backend=SSE2, Source=3520x900, files=1, cache_hits=0, cache_misses=0, tolerance=10, scale=1-1:0.1, cpu=SSE2:Y, capture=-1600|0|0|900|1600x900, screen=0)
!> UDF ERROR: Invalid format from DLL. Could not find '{...}' and '[...]' parts.

×
×
  • Create New...