主题
解析匹配图像多结果JSON - ParseMatchImageAllJson
函数简介
解析匹配图像 JSON 数组,按索引取出其中某一条匹配结果的详细信息。
接口名称
ParseMatchImageAllJsonDLL调用
c
int ParseMatchImageAllJson(string str, int parseIndex, int* matchState, int* x, int* y, int* width, int* height, double* matchVal, double* angle, int* index);参数说明
| 参数名 | 类型 | 说明 |
|---|---|---|
| str | 字符串 | 匹配图像 JSON 字符串(须为数组格式)。 |
| parseIndex | 整数型 | 要解析的下标,从 0 开始。 |
| matchState | 整数型指针 | 输出:匹配状态(非 0 表示匹配成功)。 |
| x | 整数型指针 | 输出:匹配点 X 坐标。 |
| y | 整数型指针 | 输出:匹配点 Y 坐标。 |
| width | 整数型指针 | 输出:匹配图片宽度。 |
| height | 整数型指针 | 输出:匹配图片高度。 |
| matchVal | 双精度浮点数指针 | 输出:匹配值。 |
| angle | 双精度浮点数指针 | 输出:匹配角度。 |
| index | 整数型指针 | 输出:匹配索引(JSON 内 Index 字段)。 |
适用场景与联动
本接口解析多结果 JSON 数组中的某一项。常见来源:
| 来源接口 | 说明 |
|---|---|
| MatchImageFromPathAll | 路径多结果匹配 |
| MatchImageFromPtrAll | 内存图多结果匹配 |
| MatchImagePtrFromPathAll | 指针模板多结果 |
| FindImagePtrFromPathAll | 内存源图 + 路径模板,全部结果 |
| 同类 All 接口 | 如 FindImage*All、MatchWindows*All、FindWindows*All 等 |
| SortPosDistance | 排序后仍为本格式数组 |
与 GetMatchImageAllCount 联动(推荐写法):
MatchImageFromPathAll / MatchImageFromPtrAll / ...
↓
GetStringFromPtr 取出 JSON 数组文本
↓
count = GetMatchImageAllCount(json)
↓
for parseIndex = 0 .. count-1:
ParseMatchImageAllJson(json, parseIndex, ...)单结果对象请用 ParseMatchImageJson。
不要越界:parseIndex必须满足0 <= parseIndex < GetMatchImageAllCount(json)。
示例
下面演示两类常见用法:
- 遍历全部命中点:
GetMatchImageAllCount→ 循环ParseMatchImageAllJson - 实用筛选:在循环中挑出
MatchVal最高的一项,并取模板中心作为点击坐标
SDK 若已直接返回
MatchData/MatchResult列表,一般直接遍历列表即可;本接口主要用于原生 DLL、易语言rawstring、SortPosDistance排序后的 JSON 等场景。
SDK 调用
cpp
#include "OLAPlugServer.h"
#include <cstdio>
OLAPlugServer ola;
// 多结果 JSON:与 MatchImageFromPathAll / SortPosDistance(type=2) 返回格式一致
const char* resultJson =
"[{\"MatchState\":true,\"X\":120,\"Y\":80,\"Width\":32,\"Height\":32,\"MatchVal\":0.88,\"Angle\":0,\"Index\":0},"
"{\"MatchState\":true,\"X\":300,\"Y\":200,\"Width\":32,\"Height\":32,\"MatchVal\":0.95,\"Angle\":0,\"Index\":1},"
"{\"MatchState\":true,\"X\":50,\"Y\":400,\"Width\":32,\"Height\":32,\"MatchVal\":0.91,\"Angle\":15,\"Index\":2}]";
int32_t count = ola.GetMatchImageAllCount(resultJson);
if (count <= 0) {
// 无匹配结果(空数组或格式不符)
return;
}
int32_t bestX = 0, bestY = 0, bestW = 0, bestH = 0, bestIndex = -1;
double bestVal = -1.0;
for (int32_t i = 0; i < count; i++) {
int32_t matchState = 0, x = 0, y = 0, width = 0, height = 0, index = 0;
double matchVal = 0, angle = 0;
int32_t ret = ola.ParseMatchImageAllJson(
resultJson, i, &matchState, &x, &y, &width, &height, &matchVal, &angle, &index);
if (ret != 1 || matchState == 0) {
continue; // 解析失败或该项未命中
}
// 左上角 (x,y)、宽高、相似度、角度、JSON 内 Index
std::printf("hit[%d] pos=(%d,%d) size=%dx%d val=%.3f angle=%.1f index=%d\n",
i, x, y, width, height, matchVal, angle, index);
if (matchVal > bestVal) {
bestVal = matchVal;
bestX = x; bestY = y; bestW = width; bestH = height; bestIndex = index;
}
}
if (bestIndex >= 0) {
// 点击模板中心(也可直接用左上角 bestX/bestY)
int32_t clickX = bestX + bestW / 2;
int32_t clickY = bestY + bestH / 2;
std::printf("best Index=%d MatchVal=%.3f click=(%d,%d)\n",
bestIndex, bestVal, clickX, clickY);
}csharp
using System;
using OLAPlug;
var ola = new OLAPlugServer();
string resultJson =
"[{\"MatchState\":true,\"X\":120,\"Y\":80,\"Width\":32,\"Height\":32,\"MatchVal\":0.88,\"Angle\":0,\"Index\":0},"
+ "{\"MatchState\":true,\"X\":300,\"Y\":200,\"Width\":32,\"Height\":32,\"MatchVal\":0.95,\"Angle\":0,\"Index\":1},"
+ "{\"MatchState\":true,\"X\":50,\"Y\":400,\"Width\":32,\"Height\":32,\"MatchVal\":0.91,\"Angle\":15,\"Index\":2}]";
int count = ola.GetMatchImageAllCount(resultJson);
if (count <= 0)
{
Console.WriteLine("无匹配结果");
return;
}
int bestX = 0, bestY = 0, bestW = 0, bestH = 0, bestIndex = -1;
double bestVal = -1;
for (int i = 0; i < count; i++)
{
int ret = ola.ParseMatchImageAllJson(
resultJson, i,
out int matchState, out int x, out int y, out int width, out int height,
out double matchVal, out double angle, out int index);
if (ret != 1 || matchState == 0) continue;
Console.WriteLine($"hit[{i}] pos=({x},{y}) size={width}x{height} val={matchVal:F3} angle={angle} index={index}");
if (matchVal > bestVal)
{
bestVal = matchVal;
bestX = x; bestY = y; bestW = width; bestH = height; bestIndex = index;
}
}
if (bestIndex >= 0)
{
int clickX = bestX + bestW / 2;
int clickY = bestY + bestH / 2;
Console.WriteLine($"best Index={bestIndex} MatchVal={bestVal:F3} click=({clickX},{clickY})");
}python
from OLAPlugServer import OLAPlugServer
ola = OLAPlugServer()
result_json = (
'[{"MatchState":true,"X":120,"Y":80,"Width":32,"Height":32,"MatchVal":0.88,"Angle":0,"Index":0},'
'{"MatchState":true,"X":300,"Y":200,"Width":32,"Height":32,"MatchVal":0.95,"Angle":0,"Index":1},'
'{"MatchState":true,"X":50,"Y":400,"Width":32,"Height":32,"MatchVal":0.91,"Angle":15,"Index":2}]'
)
count = ola.GetMatchImageAllCount(result_json)
if count <= 0:
print("无匹配结果")
else:
best = None # (match_val, x, y, width, height, index)
for i in range(count):
ret, match_state, x, y, width, height, match_val, angle, index = (
ola.ParseMatchImageAllJson(result_json, i)
)
if ret != 1 or match_state == 0:
continue
print(f"hit[{i}] pos=({x},{y}) size={width}x{height} "
f"val={match_val:.3f} angle={angle} index={index}")
if best is None or match_val > best[0]:
best = (match_val, x, y, width, height, index)
if best:
match_val, x, y, width, height, index = best
click_x, click_y = x + width // 2, y + height // 2
print(f"best Index={index} MatchVal={match_val:.3f} click=({click_x},{click_y})")java
import com.olaplug.OLAPlugServer;
import com.olaplug.model.ApiResult;
import com.olaplug.model.MatchResult;
OLAPlugServer ola = new OLAPlugServer();
String resultJson =
"[{\"MatchState\":true,\"X\":120,\"Y\":80,\"Width\":32,\"Height\":32,\"MatchVal\":0.88,\"Angle\":0,\"Index\":0},"
+ "{\"MatchState\":true,\"X\":300,\"Y\":200,\"Width\":32,\"Height\":32,\"MatchVal\":0.95,\"Angle\":0,\"Index\":1},"
+ "{\"MatchState\":true,\"X\":50,\"Y\":400,\"Width\":32,\"Height\":32,\"MatchVal\":0.91,\"Angle\":15,\"Index\":2}]";
int count = ola.GetMatchImageAllCount(resultJson);
if (count <= 0) {
System.out.println("无匹配结果");
return;
}
MatchResult best = null;
for (int i = 0; i < count; i++) {
ApiResult<MatchResult> ar = ola.ParseMatchImageAllJson(resultJson, i);
if (ar == null || !ar.isSuccess() || ar.data == null || !ar.data.MatchState) {
continue;
}
MatchResult m = ar.data;
System.out.printf("hit[%d] pos=(%d,%d) size=%dx%d val=%.3f angle=%.1f index=%d%n",
i, m.X, m.Y, m.Width, m.Height, m.MatchVal, m.Angle, m.Index);
if (best == null || m.MatchVal > best.MatchVal) {
best = m;
}
}
if (best != null) {
int clickX = best.X + best.Width / 2;
int clickY = best.Y + best.Height / 2;
System.out.printf("best Index=%d MatchVal=%.3f click=(%d,%d)%n",
best.Index, best.MatchVal, clickX, clickY);
}go
import (
"fmt"
"github.com/ola/olaplug/olaplug"
)
ola, _ := olaplug.NewOLAPlugServer("OLAPlug_x64.dll")
defer ola.ReleaseObj()
resultJson := "[" +
"{\"MatchState\":true,\"X\":120,\"Y\":80,\"Width\":32,\"Height\":32,\"MatchVal\":0.88,\"Angle\":0,\"Index\":0}," +
"{\"MatchState\":true,\"X\":300,\"Y\":200,\"Width\":32,\"Height\":32,\"MatchVal\":0.95,\"Angle\":0,\"Index\":1}," +
"{\"MatchState\":true,\"X\":50,\"Y\":400,\"Width\":32,\"Height\":32,\"MatchVal\":0.91,\"Angle\":15,\"Index\":2}]"
count := ola.GetMatchImageAllCount(resultJson)
if count <= 0 {
fmt.Println("无匹配结果")
return
}
bestX, bestY, bestW, bestH, bestIndex := 0, 0, 0, 0, int32(-1)
bestVal := -1.0
for i := int32(0); i < count; i++ {
var matchState, x, y, width, height, index int32
var matchVal, angle float64
ret := ola.ParseMatchImageAllJson(resultJson, i, &matchState, &x, &y, &width, &height, &matchVal, &angle, &index)
if ret != 1 || matchState == 0 {
continue
}
fmt.Printf("hit[%d] pos=(%d,%d) size=%dx%d val=%.3f angle=%.1f index=%d\n",
i, x, y, width, height, matchVal, angle, index)
if matchVal > bestVal {
bestVal = matchVal
bestX, bestY, bestW, bestH, bestIndex = int(x), int(y), int(width), int(height), index
}
}
if bestIndex >= 0 {
clickX := bestX + bestW/2
clickY := bestY + bestH/2
fmt.Printf("best Index=%d MatchVal=%.3f click=(%d,%d)\n", bestIndex, bestVal, clickX, clickY)
}rust
use olaplug::OLAPlugServer;
let ola = OLAPlugServer::new("OLAPlug_x64.dll").unwrap();
let result_json = concat!(
r#"[{"MatchState":true,"X":120,"Y":80,"Width":32,"Height":32,"MatchVal":0.88,"Angle":0,"Index":0},"#,
r#"{"MatchState":true,"X":300,"Y":200,"Width":32,"Height":32,"MatchVal":0.95,"Angle":0,"Index":1},"#,
r#"{"MatchState":true,"X":50,"Y":400,"Width":32,"Height":32,"MatchVal":0.91,"Angle":15,"Index":2}]"#
);
let count = ola.get_match_image_all_count(result_json);
if count <= 0 {
println!("无匹配结果");
} else {
let mut best_val = -1.0f64;
let mut best = (0i32, 0i32, 0i32, 0i32, -1i32); // x,y,w,h,index
for i in 0..count {
let mut match_state = 0i32;
let mut x = 0i32;
let mut y = 0i32;
let mut width = 0i32;
let mut height = 0i32;
let mut index = 0i32;
let mut match_val = 0.0f64;
let mut angle = 0.0f64;
let ret = ola.parse_match_image_all_json(
result_json, i,
&mut match_state, &mut x, &mut y, &mut width, &mut height,
&mut match_val, &mut angle, &mut index,
);
if ret != 1 || match_state == 0 {
continue;
}
println!(
"hit[{i}] pos=({x},{y}) size={width}x{height} val={match_val:.3} angle={angle} index={index}"
);
if match_val > best_val {
best_val = match_val;
best = (x, y, width, height, index);
}
}
let (bx, by, bw, bh, bi) = best;
if bi >= 0 {
let click_x = bx + bw / 2;
let click_y = by + bh / 2;
println!("best Index={bi} MatchVal={best_val:.3} click=({click_x},{click_y})");
}
}cpp
var ola = com("OlaPlug.OlaSoft")
var resultJson = "[{\"MatchState\":true,\"X\":120,\"Y\":80,\"Width\":32,\"Height\":32,\"MatchVal\":0.88,\"Angle\":0,\"Index\":0},{\"MatchState\":true,\"X\":300,\"Y\":200,\"Width\":32,\"Height\":32,\"MatchVal\":0.95,\"Angle\":0,\"Index\":1},{\"MatchState\":true,\"X\":50,\"Y\":400,\"Width\":32,\"Height\":32,\"MatchVal\":0.91,\"Angle\":15,\"Index\":2}]"
var count = ola.GetMatchImageAllCount(resultJson)
if (count <= 0) {
traceprint("无匹配结果")
} else {
var bestVal = -1.0, bestX = 0, bestY = 0, bestW = 0, bestH = 0, bestIndex = -1
for (var i = 0; i < count; i++) {
var matchState = 0, x = 0, y = 0, width = 0, height = 0, index = 0
var matchVal = 0.0, angle = 0.0
var ret = ola.ParseMatchImageAllJson(resultJson, i, matchState, x, y, width, height, matchVal, angle, index)
if (ret == 1 && matchState != 0) {
traceprint("hit[" + i + "] (" + x + "," + y + ") val=" + matchVal)
if (matchVal > bestVal) {
bestVal = matchVal
bestX = x; bestY = y; bestW = width; bestH = height; bestIndex = index
}
}
}
if (bestIndex >= 0) {
var clickX = bestX + bestW / 2
var clickY = bestY + bestH / 2
traceprint("best Index=" + bestIndex + " click=(" + clickX + "," + clickY + ")")
}
}vbscript
Set ola = CreateObject("OlaPlug.OlaSoft")
resultJson = "[{\""MatchState\"":true,\""X\"":120,\""Y\"":80,\""Width\"":32,\""Height\"":32,\""MatchVal\"":0.88,\""Angle\"":0,\""Index\"":0},{\""MatchState\"":true,\""X\"":300,\""Y\"":200,\""Width\"":32,\""Height\"":32,\""MatchVal\"":0.95,\""Angle\"":0,\""Index\"":1},{\""MatchState\"":true,\""X\"":50,\""Y\"":400,\""Width\"":32,\""Height\"":32,\""MatchVal\"":0.91,\""Angle\"":15,\""Index\"":2}]"
count = ola.GetMatchImageAllCount(resultJson)
If count <= 0 Then
TracePrint "无匹配结果"
Else
bestVal = -1
bestX = 0 : bestY = 0 : bestW = 0 : bestH = 0 : bestIndex = -1
For i = 0 To count - 1
Dim matchState, x, y, width, height, matchVal, angle, index
ret = ola.ParseMatchImageAllJson(resultJson, i, matchState, x, y, width, height, matchVal, angle, index)
If ret = 1 And matchState <> 0 Then
TracePrint "hit[" & i & "] (" & x & "," & y & ") val=" & matchVal
If matchVal > bestVal Then
bestVal = matchVal
bestX = x : bestY = y : bestW = width : bestH = height : bestIndex = index
End If
End If
Next
If bestIndex >= 0 Then
clickX = bestX + bestW \ 2
clickY = bestY + bestH \ 2
TracePrint "best Index=" & bestIndex & " click=(" & clickX & "," & clickY & ")"
End If
End Iftext
.局部变量 ola, OLAPlug
.局部变量 retData, MatchData, , 数组
.局部变量 findCount, 整数型
.局部变量 rawstring, 文本型
.局部变量 count, 整数型
.局部变量 i, 整数型
.局部变量 ret, 整数型
.局部变量 matchState, 整数型
.局部变量 x, 整数型
.局部变量 y, 整数型
.局部变量 width, 整数型
.局部变量 height, 整数型
.局部变量 matchVal, 双精度小数型
.局部变量 angle, 双精度小数型
.局部变量 index, 整数型
.局部变量 bestVal, 双精度小数型
.局部变量 bestX, 整数型
.局部变量 bestY, 整数型
.局部变量 bestW, 整数型
.局部变量 bestH, 整数型
.局部变量 bestIndex, 整数型
.局部变量 clickX, 整数型
.局部变量 clickY, 整数型
ola.创建 ()
' 易语言 SDK 与其它语言不同:Match*All 返回找到数量,结果写入 retData;日常一般直接遍历 retData,无需本接口
' 本示例演示 rawstring 场景:需要 ParseMatchImageAllJson / SortPosDistance 时再传 rawstring
findCount = ola.MatchImageFromPathAll (“images/scene.png”, “img/template.bmp”, 0.9, 1, 0, 1, retData, rawstring)
.如果真 (findCount ≤ 0)
调试输出 (“未找到匹配”)
.如果真结束
' rawstring 为原始 JSON 数组;C++/C#/Python 等若已拿到列表,一般直接遍历列表即可
count = ola.GetMatchImageAllCount (rawstring)
bestVal = -1
bestIndex = -1
.计次循环首 (count, i)
' 易语言计次循环 i 从 1 开始,parseIndex 从 0 开始,故传 i-1
ret = ola.ParseMatchImageAllJson (rawstring, i - 1, matchState, x, y, width, height, matchVal, angle, index)
.如果真 (ret = 1 并且 matchState ≠ 0)
调试输出 (“hit[”, i - 1, “] (”, x, “,”, y, “) val=”, matchVal, “ angle=”, angle)
.如果真 (matchVal > bestVal)
bestVal = matchVal
bestX = x
bestY = y
bestW = width
bestH = height
bestIndex = index
.如果真结束
.如果真结束
.计次循环尾 ()
.如果真 (bestIndex ≥ 0)
clickX = bestX + bestW ÷ 2
clickY = bestY + bestH ÷ 2
调试输出 (“最佳 Index=”, bestIndex, “ MatchVal=”, bestVal, “ 点击中心=(”, clickX, “,”, clickY, “)”)
' 日常也可直接用 retData[1].X / retData[1].Y(易语言数组下标从 1 开始),无需 Parse
.如果真结束aardio
import OLAPlugServer;
var ola = OLAPlugServer();
var resultJson = "["
+ "{\"MatchState\":true,\"X\":120,\"Y\":80,\"Width\":32,\"Height\":32,\"MatchVal\":0.88,\"Angle\":0,\"Index\":0},"
+ "{\"MatchState\":true,\"X\":300,\"Y\":200,\"Width\":32,\"Height\":32,\"MatchVal\":0.95,\"Angle\":0,\"Index\":1},"
+ "{\"MatchState\":true,\"X\":50,\"Y\":400,\"Width\":32,\"Height\":32,\"MatchVal\":0.91,\"Angle\":15,\"Index\":2}]";
var count = ola.GetMatchImageAllCount(resultJson);
if(count <= 0){
io.print("无匹配结果");
}else{
var bestVal = -1.0, bestX = 0, bestY = 0, bestW = 0, bestH = 0, bestIndex = -1;
for(i = 0; i < count; i++){
var matchState, x, y, width, height, matchVal, angle, index;
var ret = ola.ParseMatchImageAllJson(resultJson, i, matchState, x, y, width, height, matchVal, angle, index);
if(ret == 1 && matchState != 0){
io.print("hit[", i, "] (", x, ",", y, ") val=", matchVal);
if(matchVal > bestVal){
bestVal = matchVal;
bestX = x; bestY = y; bestW = width; bestH = height; bestIndex = index;
}
}
}
if(bestIndex >= 0){
var clickX = bestX + math.floor(bestW / 2);
var clickY = bestY + math.floor(bestH / 2);
io.print("best Index=", bestIndex, " click=(", clickX, ",", clickY, ")");
}
}text
变量 ola <类型 = OLAPlugServer>
ola = 新建 OLAPlugServer
文本型 resultJson = "[{\"MatchState\":true,\"X\":120,\"Y\":80,\"Width\":32,\"Height\":32,\"MatchVal\":0.88,\"Angle\":0,\"Index\":0},{\"MatchState\":true,\"X\":300,\"Y\":200,\"Width\":32,\"Height\":32,\"MatchVal\":0.95,\"Angle\":0,\"Index\":1},{\"MatchState\":true,\"X\":50,\"Y\":400,\"Width\":32,\"Height\":32,\"MatchVal\":0.91,\"Angle\":15,\"Index\":2}]"
整数 count = ola.GetMatchImageAllCount(resultJson)
如果真 (count <= 0)
调试输出 ("无匹配结果")
否则
双精度小数 bestVal = -1
整数 bestX = 0
整数 bestY = 0
整数 bestW = 0
整数 bestH = 0
整数 bestIndex = -1
计次循环首 (count)
整数 i = 取循环索引 () - 1
整数 matchState = 0
整数 x = 0
整数 y = 0
整数 width = 0
整数 height = 0
整数 index = 0
双精度小数 matchVal = 0
双精度小数 angle = 0
整数 ret = ola.ParseMatchImageAllJson(resultJson, i, matchState, x, y, width, height, matchVal, angle, index)
如果真 (ret == 1 且 matchState != 0)
调试输出 ("hit[", i, "] (", x, ",", y, ") val=", matchVal)
如果真 (matchVal > bestVal)
bestVal = matchVal
bestX = x
bestY = y
bestW = width
bestH = height
bestIndex = index
如果真结束
如果真结束
计次循环尾 ()
如果真 (bestIndex >= 0)
整数 clickX = bestX + bestW / 2
整数 clickY = bestY + bestH / 2
调试输出 ("best Index=", bestIndex, " click=(", clickX, ",", clickY, ")")
如果真结束
如果真结束cpp
#include "OLAPlugServer.h"
#include <cstdio>
OLAPlugServer ola;
const char* resultJson =
"[{\"MatchState\":true,\"X\":120,\"Y\":80,\"Width\":32,\"Height\":32,\"MatchVal\":0.88,\"Angle\":0,\"Index\":0},"
"{\"MatchState\":true,\"X\":300,\"Y\":200,\"Width\":32,\"Height\":32,\"MatchVal\":0.95,\"Angle\":0,\"Index\":1},"
"{\"MatchState\":true,\"X\":50,\"Y\":400,\"Width\":32,\"Height\":32,\"MatchVal\":0.91,\"Angle\":15,\"Index\":2}]";
int32_t count = ola.GetMatchImageAllCount(resultJson);
if (count <= 0) {
return;
}
int32_t bestX = 0, bestY = 0, bestW = 0, bestH = 0, bestIndex = -1;
double bestVal = -1.0;
for (int32_t i = 0; i < count; i++) {
int32_t matchState = 0, x = 0, y = 0, width = 0, height = 0, index = 0;
double matchVal = 0, angle = 0;
int32_t ret = ola.ParseMatchImageAllJson(
resultJson, i, &matchState, &x, &y, &width, &height, &matchVal, &angle, &index);
if (ret != 1 || matchState == 0) continue;
std::printf("hit[%d] (%d,%d) val=%.3f index=%d\n", i, x, y, matchVal, index);
if (matchVal > bestVal) {
bestVal = matchVal;
bestX = x; bestY = y; bestW = width; bestH = height; bestIndex = index;
}
}
if (bestIndex >= 0) {
int32_t clickX = bestX + bestW / 2;
int32_t clickY = bestY + bestH / 2;
std::printf("best Index=%d click=(%d,%d)\n", bestIndex, clickX, clickY);
}原生 DLL 调用(MatchImageFromPathAll → Count → Parse 完整联动)
cpp
long instance = CreateCOLAPlugInterFace();
// 1. 多结果匹配 → JSON 数组指针
long ptr = MatchImageFromPathAll(
instance, "images/scene.png", "img/template.bmp", 0.9, 1, 0, 1);
if (ptr == 0) {
return; // 未找到或匹配失败
}
// 2. 取出 JSON 文本后即可释放指针
char json[8192] = {0};
GetStringFromPtr(ptr, json, sizeof(json));
FreeStringPtr(instance, ptr);
// 3. 可选:按锚点距离排序(type=2 图像识别),仍为本接口可解析的数组格式
// long sortedPtr = SortPosDistance(instance, json, 2, 400, 300);
// GetStringFromPtr(sortedPtr, json, sizeof(json));
// FreeStringPtr(instance, sortedPtr);
// 4. Count + 逐条 Parse;同时挑出最高相似度
int count = GetMatchImageAllCount(instance, json);
int bestX = 0, bestY = 0, bestW = 0, bestH = 0, bestIndex = -1;
double bestVal = -1.0;
for (int i = 0; i < count; i++) {
int matchState = 0, x = 0, y = 0, width = 0, height = 0, index = 0;
double matchVal = 0, angle = 0;
int ret = ParseMatchImageAllJson(
instance, json, i, &matchState, &x, &y, &width, &height, &matchVal, &angle, &index);
if (ret != 1 || matchState == 0) {
continue;
}
// 第 i 个命中:左上角 (x,y),中心可点 (x+width/2, y+height/2)
if (matchVal > bestVal) {
bestVal = matchVal;
bestX = x; bestY = y; bestW = width; bestH = height; bestIndex = index;
}
}
if (bestIndex >= 0) {
int clickX = bestX + bestW / 2;
int clickY = bestY + bestH / 2;
// 后续:MouseClick(instance, clickX, clickY) 等
}csharp
using System;
using System.Runtime.InteropServices;
using System.Text;
[DllImport("OLAPlug_x64.dll", CallingConvention = CallingConvention.StdCall)]
static extern long CreateCOLAPlugInterFace();
[DllImport("OLAPlug_x64.dll", CallingConvention = CallingConvention.StdCall)]
static extern long MatchImageFromPathAll(long ola, string source, string templ, double matchVal, int type, double angle, double scale);
[DllImport("OLAPlug_x64.dll", CallingConvention = CallingConvention.StdCall)]
static extern int GetStringFromPtr(long ptr, StringBuilder lpString, int size);
[DllImport("OLAPlug_x64.dll", CallingConvention = CallingConvention.StdCall)]
static extern int GetStringSize(long ptr);
[DllImport("OLAPlug_x64.dll", CallingConvention = CallingConvention.StdCall)]
static extern int FreeStringPtr(long ptr);
[DllImport("OLAPlug_x64.dll", CallingConvention = CallingConvention.StdCall)]
static extern int GetMatchImageAllCount(long ola, string str);
[DllImport("OLAPlug_x64.dll", CallingConvention = CallingConvention.StdCall)]
static extern int ParseMatchImageAllJson(long ola, string str, int parseIndex, out int matchState, out int x, out int y, out int width, out int height, out double matchVal, out double angle, out int index);
long instance = CreateCOLAPlugInterFace();
long ptr = MatchImageFromPathAll(instance, "images/scene.png", "img/template.bmp", 0.9, 1, 0, 1);
if (ptr == 0) return;
var sb = new StringBuilder(GetStringSize(ptr) + 1);
GetStringFromPtr(ptr, sb, sb.Capacity);
string json = sb.ToString();
FreeStringPtr(ptr);
int count = GetMatchImageAllCount(instance, json);
int bestX = 0, bestY = 0, bestW = 0, bestH = 0, bestIndex = -1;
double bestVal = -1;
for (int i = 0; i < count; i++)
{
int ret = ParseMatchImageAllJson(
instance, json, i,
out int matchState, out int x, out int y, out int width, out int height,
out double matchVal, out double angle, out int index);
if (ret != 1 || matchState == 0) continue;
Console.WriteLine($"hit[{i}] ({x},{y}) val={matchVal:F3} index={index}");
if (matchVal > bestVal)
{
bestVal = matchVal;
bestX = x; bestY = y; bestW = width; bestH = height; bestIndex = index;
}
}
if (bestIndex >= 0)
{
int clickX = bestX + bestW / 2;
int clickY = bestY + bestH / 2;
Console.WriteLine($"best click=({clickX},{clickY}) val={bestVal:F3}");
}python
from ctypes import CDLL, c_int, c_int64, c_double, create_string_buffer
ola = CDLL("OLAPlug_x64.dll")
ola.CreateCOLAPlugInterFace.restype = c_int64
ola.MatchImageFromPathAll.restype = c_int64
instance = ola.CreateCOLAPlugInterFace()
ptr = ola.MatchImageFromPathAll(
instance, b"images/scene.png", b"img/template.bmp",
c_double(0.9), c_int(1), c_double(0), c_double(1))
if ptr == 0:
raise RuntimeError("match failed or empty")
size = ola.GetStringSize(ptr)
buf = create_string_buffer(size + 1)
ola.GetStringFromPtr(ptr, buf, size + 1)
ola.FreeStringPtr(instance, ptr) # 按所用封装签名调整
result_json = buf.value
count = ola.GetMatchImageAllCount(instance, result_json)
match_state = c_int(0)
x = c_int(0)
y = c_int(0)
width = c_int(0)
height = c_int(0)
index = c_int(0)
match_val = c_double(0)
angle = c_double(0)
best = None
for i in range(count):
ret = ola.ParseMatchImageAllJson(
instance, result_json, i,
match_state, x, y, width, height, match_val, angle, index)
if ret != 1 or match_state.value == 0:
continue
item = (match_val.value, x.value, y.value, width.value, height.value, index.value)
print(f"hit[{i}] ({item[1]},{item[2]}) val={item[0]:.3f}")
if best is None or item[0] > best[0]:
best = item
if best:
mv, bx, by, bw, bh, bi = best
click_x, click_y = bx + bw // 2, by + bh // 2
print(f"best Index={bi} MatchVal={mv:.3f} click=({click_x},{click_y})")返回值
错误码含义见 JSON 错误码说明。
| 返回值 | 说明 |
|---|---|
1 | 成功。 |
0 | 失败(格式不符、索引越界等)。 |
注意事项
| 项目 | 说明 |
|---|---|
| parseIndex 从 0 开始 | 第 1 条为 0,最后一条为 count - 1。 |
| 先 Count 再 Parse | 推荐先 GetMatchImageAllCount 再循环,避免越界。 |
| 输入须为数组 | 单结果对象请用 ParseMatchImageJson。 |
| 输出参数 | 所有输出参数须提供有效指针/变量。 |
| SDK 结构化返回 | C++/C#/Python 等 SDK 的 MatchImageFromPathAll 已直接返回列表时,一般直接遍历列表即可;易语言 SDK 则写入 retData(MatchData 数组)并返回数量,日常也直接遍历 retData。本接口主要用于原生 DLL、易语言 rawstring、SortPosDistance 等仍持有原始 JSON 数组的场景。 |
