images - 图片处理
images - 图片处理
Stability: 2 - Stable
images模块提供了一些手机设备中常见的图片处理函数,包括截图、读写图片、图片剪裁、旋转、二值化、找色找图等。
该模块分为两个部分,图片处理部分和找图找色部分。
需要注意的是,image对象创建后尽量在不使用时进行回收,同时避免循环创建大量图片。因为图片是一种占用内存比较大的资源,尽管云控通过各种方式(比如图片缓存机制、垃圾回收时回收图片、脚本结束时回收所有图片)尽量降低图片资源的泄漏和内存占用,但是糟糕的代码仍然可以占用大量内存。
Image对象通过调用recycle()
函数来回收。例如:
// 读取图片
var img = images.read("./1.png");
// 对图片进行操作
...
// 回收图片
img.recycle();
例外的是,captureScreen()
返回的图片不需要回收。
图片处理
images.read(path)
path
{string} 图片路径
读取在路径path的图片文件并返回一个Image对象。如果文件不存在或者文件无法解码则返回null。
images.load(url)
url
{string} 图片URL地址
加载在地址URL的网络图片并返回一个Image对象。如果地址不存在或者图片无法解码则返回null。
images.copy(img)
img
{Image} 图片- 返回 {Image}
复制一张图片并返回新的副本。该函数会完全复制img对象的数据。
images.save(image, path[, format = "png", quality = 100])
image
{Image} 图片path
{string} 路径format
{string} 图片格式,可选的值为:png
jpeg
/jpg
webp
quality
{number} 图片质量,为0~100的整数值
把图片image以PNG格式保存到path中。如果文件不存在会被创建;文件存在会被覆盖。
// 把图片压缩为原来的一半质量并保存
var img = images.read("/sdcard/1.png");
images.save(img, "/sdcard/1.jpg", "jpg", 50);
app.viewFile("/sdcard/1.jpg");
images.fromBase64(base64)
base64
{string} 图片的Base64数据- 返回 {Image}
解码Base64数据并返回解码后的图片Image对象。如果base64无法解码则返回null
。
images.toBase64(img[, format = "png", quality = 100])
image
{image} 图片format
{string} 图片格式,可选的值为:png
jpeg
/jpg
webp
quality
{number} 图片质量,为0~100的整数值- 返回 {string}
把图片编码为base64数据并返回。
images.fromBytes(bytes)
bytes
{byte[]} 字节数组
解码字节数组bytes并返回解码后的图片Image对象。如果bytes无法解码则返回null
。
images.toBytes(img[, format = "png", quality = 100])
image
{image} 图片format
{string} 图片格式,可选的值为:png
jpeg
/jpg
webp
quality
{number} 图片质量,为0~100的整数值- 返回 {byte[]}
把图片编码为字节数组并返回。
images.readPixels(path)
path
{string} 图片的地址- 返回 {Object} 包括图片的像素数据和宽高,{data,width,height}
读取图片的像素数据和宽高。
images.clip(img, x, y, w, h)
img
{Image} 图片x
{number} 剪切区域的左上角横坐标y
{number} 剪切区域的左上角纵坐标w
{number} 剪切区域的宽度h
{number} 剪切区域的高度- 返回 {Image}
从图片img的位置(x, y)处剪切大小为w * h的区域,并返回该剪切区域的新图片。
var src = images.read("/sdcard/1.png");
var clip = images.clip(src, 100, 100, 400, 400);
images.save(clip, "/sdcard/clip.png");
images.resize(img, size[, interpolation])
[v4.1.0新增]
-
img
{Image} 图片 -
size
{Array} 两个元素的数组[w, h],分别表示宽度和高度;如果只有一个元素,则宽度和高度相等 -
interpolation
{string} 插值方法,可选,默认为"LINEAR"(线性插值),可选的值有:NEAREST
最近邻插值LINEAR
线性插值(默认)AREA
区域插值CUBIC
三次样条插值LANCZOS4
Lanczos插值 参见InterpolationFlags
-
返回 {Image}
调整图片大小,并返回调整后的图片。例如把图片放缩为200*300:images.resize(img, [200, 300])
。
images.scale(img, fx, fy[, interpolation])
[v4.1.0新增]
-
img
{Image} 图片 -
fx
{number} 宽度放缩倍数 -
fy
{number} 高度放缩倍数 -
interpolation
{string} 插值方法,可选,默认为"LINEAR"(线性插值),可选的值有:NEAREST
最近邻插值LINEAR
线性插值(默认)AREA
区域插值CUBIC
三次样条插值LANCZOS4
Lanczos插值 参见InterpolationFlags
-
返回 {Image}
放缩图片,并返回放缩后的图片。例如把图片变成原来的一半:images.scale(img, 0.5, 0.5)
。
images.rotate(img, degree[, x, y])
[v4.1.0新增]
img
{Image} 图片degree
{number} 旋转角度。x
{number} 旋转中心x坐标,默认为图片中点y
{number} 旋转中心y坐标,默认为图片中点- 返回 {Image}
将图片顺时针旋转degree度,返回旋转后的图片对象。
例如顺时针旋转90度为images.rotate(img, 90)
。
images.concat(img1, image2[, direction])
[v4.1.0新增]
img1
{Image} 图片1img2
{Image} 图片2direction
{string} 连接方向,默认为"RIGHT",可选的值有:LEFT
将图片2接到图片1左边RIGHT
将图片2接到图片1右边TOP
将图片2接到图片1上边BOTTOM
将图片2接到图片1下边
- 返回 {Image}
连接两张图片,并返回连接后的图像。如果两张图片大小不一致,小的那张将适当居中。
images.grayscale(img)
[v4.1.0新增]
img
{Image} 图片- 返回 {Image}
灰度化图片,并返回灰度化后的图片。
images.threshold(img, threshold, maxVal[, type])
[v4.1.0新增]
-
img
{Image} 图片 -
threshold
{number} 阈值 -
maxVal
{number} 最大值 -
type
{string} 阈值化类型,默认为"BINARY",参见ThresholdTypes, 可选的值:BINARY
BINARY_INV
TRUNC
TOZERO
TOZERO_INV
OTSU
TRIANGLE
-
返回 {Image}
将图片阈值化,并返回处理后的图像。可以用这个函数进行图片二值化。例如:images.threshold(img, 100, 255, "BINARY")
,这个代码将图片中大于100的值全部变成255,其余变成0,从而达到二值化的效果。如果img是一张灰度化图片,这个代码将会得到一张黑白图片。
可以参考有关博客(比如threshold函数的使用)或者OpenCV文档threshold。
images.adaptiveThreshold(img, maxValue, adaptiveMethod, thresholdType, blockSize, C)
[v4.1.0新增]
img
{Image} 图片maxValue
{number} 最大值adaptiveMethod
{string} 在一个邻域内计算阈值所采用的算法,可选的值有:MEAN_C
计算出领域的平均值再减去参数C的值GAUSSIAN_C
计算出领域的高斯均值再减去参数C的值
thresholdType
{string} 阈值化类型,可选的值有:BINARY
BINARY_INV
blockSize
{number} 邻域块大小C
{number} 偏移值调整量- 返回 {Image}
对图片进行自适应阈值化处理,并返回处理后的图像。
可以参考有关博客(比如threshold与adaptiveThreshold)或者OpenCV文档adaptiveThreshold。
images.cvtColor(img, code[, dstCn])
[v4.1.0新增]
img
{Image} 图片code
{string} 颜色空间转换的类型,可选的值有一共有205个(参见ColorConversionCodes),这里只列出几个:BGR2GRAY
BGR转换为灰度BGR2HSV
BGR转换为HSV- ``
dstCn
{number} 目标图像的颜色通道数量,如果不填写则根据其他参数自动决定。- 返回 {Image}
对图像进行颜色空间转换,并返回转换后的图像。
可以参考有关博客(比如颜色空间转换)或者OpenCV文档cvtColor。
images.inRange(img, lowerBound, upperBound)
[v4.1.0新增]
img
{Image} 图片lowerBound
{string} | {number} 颜色下界upperBound
{string} | {number} 颜色下界- 返回 {Image}
将图片二值化,在lowerBound~upperBound范围以外的颜色都变成0,在范围以内的颜色都变成255。
例如images.inRange(img, "#000000", "#222222")
。
images.interval(img, color, interval)
[v4.1.0新增]
img
{Image} 图片color
{string} | {number} 颜色值interval
{number} 每个通道的范围间隔- 返回 {Image}
将图片二值化,在color-interval ~ color+interval范围以外的颜色都变成0,在范围以内的颜色都变成255。这里对color的加减是对每个通道而言的。
例如images.interval(img, "#888888", 16)
,每个通道的颜色值均为0x88,加减16后的范围是[0x78,
0x98],因此这个代码将把#787878~#989898的颜色变成#FFFFFF,而把这个范围以外的变成#000000。
images.blur(img, size[, anchor, type])
[v4.1.0新增]
img
{Image} 图片size
{Array} 定义滤波器的大小,如[3, 3]anchor
{Array} 指定锚点位置(被平滑点),默认为图像中心type
{string} 推断边缘像素类型,默认为"DEFAULT",可选的值有:CONSTANT
iiiiii|abcdefgh|iiiiiii with some specified iREPLICATE
aaaaaa|abcdefgh|hhhhhhhREFLECT
fedcba|abcdefgh|hgfedcbWRAP
cdefgh|abcdefgh|abcdefgREFLECT_101
gfedcb|abcdefgh|gfedcbaTRANSPARENT
uvwxyz|abcdefgh|ijklmnoREFLECT101
same as BORDER_REFLECT_101DEFAULT
same as BORDER_REFLECT_101ISOLATED
do not look outside of ROI
- 返回 {Image}
对图像进行模糊(平滑处理),返回处理后的图像。
可以参考有关博客(比如实现图像平滑处理)或者OpenCV文档blur。
images.medianBlur(img, size)
[v4.1.0新增]
img
{Image} 图片size
{Array} 定义滤波器的大小,如[3, 3]- 返回 {Image}
对图像进行中值滤波,返回处理后的图像。
可以参考有关博客(比如实现图像平滑处理)或者OpenCV文档blur。
images.gaussianBlur(img, size[, sigmaX, sigmaY, type])
[v4.1.0新增]
img
{Image} 图片size
{Array} 定义滤波器的大小,如[3, 3]sigmaX
{number} x方向的标准方差,不填写则自动计算sigmaY
{number} y方向的标准方差,不填写则自动计算type
{string} 推断边缘像素类型,默认为"DEFAULT",参见images.blur
- 返回 {Image}
对图像进行高斯模糊,返回处理后的图像。
可以参考有关博客(比如实现图像平滑处理)或者OpenCV文档GaussianBlur。
images.getSimilarity(img1, img2, options)
-
img1
{Image} 图片1 -
img2
{Image} 图片2 -
options
{Object} 选项包括:type
{string} 比较相似度的算法(默认为MSSIM):MSSIM
平均结构相似性,在影像品质的衡量上更能符合人眼对影像品质的判断。结构相似性SSIM的取值范围是 [ 0 , 1 ] ,当两张图像越相似时,则SSIM越接近1。PNSR
峰值信噪比,是针对于像素绝对误差,通过均方误差(MSE)进行定义,当两幅图像的PSNR小于30时,那么这两幅图像可以说是比较相似的。
-
返回 {number}
比较两幅图片的相似性,返回相似度。
例如
log(images.getSimilarity(img1, img2, {
"type": "PNSR"
}));
images.matToImage(mat)
[v4.1.0新增]
mat
{Mat} OpenCV的Mat对象- 返回 {Image}
把Mat对象转换为Image对象。
找图找色
找图找色介绍了通过截图、匹配等搜索目标的不同方式,可以根据实际情况选择不同的方式:
- 找色、多点找色:通过描述颜色或颜色路径匹配图片中的像素,效率较高
- 基于ColorMaping的找色或多点找色:适合每次截图都有多次找色、多点找色的情况,可以进一步提升找色效率,效率最高
- 找图(模板匹配):通过在大图中依次匹配小图,搜索小图的位置,效率中等,但不同分辨率兼容性较差
- 全分辨率找图(特征匹配):通过计算大图和小图的特征点,匹配特征而计算小图的位置,效率比普通找图低,但兼容分辨率、旋转等变化
images.requestScreenCapture([landscape])
landscape
{boolean} 布尔值, 表示将要执行的截屏是否为横屏。如果landscape为false, 则表示竖屏截图; true为横屏截图。
向系统申请屏幕截图权限,返回是否请求成功。
第一次使用该函数会弹出截图权限请求,建议选择“总是允许”。(某些系统没有总是允许选项)
这个函数只是申请截图权限,并不会真正执行截图,真正的截图函数是captureScreen()
。
该函数在截图脚本中只需执行一次,而无需每次调用captureScreen()
都调用一次;若已有截图权限,则抛出异常。
如果不指定landscape值,则截图方向由当前设备屏幕方向决定,因此务必注意执行该函数时的屏幕
截图权限无法在脚本引擎之间共享。
建议在本软件界面运行该函数,在其他软件界面运行时容易出现一闪而过的黑屏现象;另外,某些定制ROM或者高版本Android不允许在后台弹出界面,在后台运行此函数时可能会一直阻塞。
示例:
// 请求截图
if(!requestScreenCapture()){
toastLog("请求截图失败");
exit();
}
// 连续截图10张图片(间隔1秒)并保存到存储卡目录
for(var i = 0; i < 10; i++){
captureScreen("/sdcard/screen_capture_" + i + ".png");
sleep(1000);
}
该函数也可以作为全局函数使用。
$images.requestScreenCapture(options)
options
{object} 申请截图选项width
{number} 截图宽度,默认为-1,即自动设置为设备屏幕宽度height
{number} 截图高度,默认为-1,即自动设置为设备屏幕高度orientation
{number} 截图方向,默认为0- -1:ORIENTATION_CURRENT, 检测当前的屏幕方向,用该方向作为申请截图的屏幕方向
- 0: ORIENTATION_AUTO, 自动适应截图方向(转屏时自动切换方向)
- 1: ORIENTATION_PORTRAIT, 竖屏截图
- 2: ORIENTATION_LANDSCAPE, 横屏截图
async
{boolean} 是否为异步截图。默认为false
向系统申请屏幕截图权限,返回是否请求成功。对于width和height参数,系统只会匹配相邻的合适的宽高。截图宽高不一定和指定的宽高完全一致。
requestScreenCapture({orientation: 0});
更多参数和说明参见上面的images.requestScreenCapture([landscape])
函数,这里只特别解释async
参数。
当async
为true时,申请截图将为异步截图,也即无法通过captureScreen()
来截图,而是通过事件screen_capture
来监听截图。
该事件将在屏幕变化时自动触发,对于屏幕刷新少的软件界面更加节能省电,对于游戏界面则可能无法达到省电效果。
// 请求截图权限, 注意参数 async: true
requestScreenCapture({async: true});
let target = $images.read('./test.png');
$events.on('exit', () => target.recycle());
// 监听屏幕截图
$images.on("screen_capture", capture => {
// 找图
let pos = $images.findImage(capture, target);
// 打印
console.log(pos);
});
$images.getScreenCaptureOptions()
- 返回 {object} | {null}
获取当前截图配置选项。如果并未申请截图权限,则返回null
。返回的对象有以下字段: *
width
{number} 截图宽度 *
height
{number} 截图高度 *
orientation
{number} 截图方向 * 0:
ORIENTATION_AUTO, 自动适应截图方向 * 1: ORIENTATION_PORTRAIT, 竖屏截图 * 2: ORIENTATION_LANDSCAPE, 横屏截图 *
density
{number} 截图像素密度 *
async
{boolean} 是否为异步截图
$images.stopScreenCapture()
释放截图权限。如果并未申请截图权限,则此函数没有任何作用。
images.captureScreen()
截取当前屏幕并返回一个Image对象。
没有截图权限时执行该函数会抛出SecurityException。
该函数不会返回null,两次调用可能返回相同的Image对象。这是因为设备截图的更新需要一定的时间,短时间内(一般来说是16ms)连续调用则会返回同一张截图。
截图需要转换为Bitmap格式,从而该函数执行需要一定的时间(0~20ms)。
另外在requestScreenCapture()执行成功后需要一定时间后才有截图可用,因此如果立即调用captureScreen(),会等待一定时间后(一般为几百ms)才返回截图。
例子:
// 请求横屏截图
requestScreenCapture(true);
// 截图
var img = captureScreen();
// 获取在点(100, 100)的颜色值
var color = images.pixel(img, 100, 100);
// 显示该颜色值
toastLog(colors.toString(color));
该函数也可以作为全局函数使用。
images.captureScreen(path)
path
{string} 截图保存路径
截取当前屏幕并以PNG格式保存到path中。如果文件不存在会被创建;文件存在会被覆盖。
该函数不会返回任何值。该函数也可以作为全局函数使用。
images.pixel(image, x, y)
image
{Image} 图片x
{number} 要获取的像素的横坐标。y
{number} 要获取的像素的纵坐标。
返回图片image在点(x, y)处的像素的ARGB值。
该值的格式为0xAARRGGBB,是一个"32位整数"(虽然JavaScript中并不区分整数类型和其他数值类型)。
坐标系以图片左上角为原点。以图片左侧边为y轴,上侧边为x轴。
images.findColor(image, color, options)
image
{Image} 图片color
{number} | {string} 要寻找的颜色的RGB值。如果是一个整数,则以0xRRGGBB的形式代表RGB值(A通道会被忽略);如果是字符串,则以"#RRGGBB"代表其RGB值。options
{Object} 选项
在图片中寻找颜色color。找到时返回找到的点Point,找不到时返回null。
选项包括:
region
{Array} 找色区域。是一个两个或四个元素的数组。(region[0], region[1])表示找色区域的左上角;region[2]*region[3]表示找色区域的宽高。如果只有region只有两个元素,则找色区域为(region[0], region[1])到图片右下角。如果不指定region选项,则找色区域为整张图片。threshold
{number} 找色时颜色相似度的临界值,范围为0 ~ 255(越小越相似,0为颜色相等,255为任何颜色都能匹配)。默认为4。threshold和浮点数相似度(0.0~1.0)的换算为 similarity = (255 - threshold) / 255.
该函数也可以作为全局函数使用。
一个循环找色的例子如下:
requestScreenCapture();
// 循环找色,找到红色(#ff0000)时停止并报告坐标
while(true){
var img = captureScreen();
var point = findColor(img, "#ff0000");
if(point){
toastLog("找到红色,坐标为(" + point.x + ", " + point.y + ")");
}
}
一个区域找色的例子如下:
// 读取本地图片/sdcard/1.png
var img = images.read("/sdcard/1.png");
// 判断图片是否加载成功
if(!img){
toastLog("没有该图片");
exit();
}
// 在该图片中找色,指定找色区域为在位置(400, 500)的宽为300长为200的区域,指定找色临界值为4
var point = findColor(img, "#00ff00", {
region: [400, 500, 300, 200],
threshold: 4
});
if(point){
toastLog("找到啦:" + point);
}else{
toastLog("没找到");
}
images.findColorInRegion(img, color, x, y[, width, height, threshold])
区域找色的简便方法。
相当于
images.findColor(img, color, {
region: [x, y, width, height],
threshold: threshold
});
该函数也可以作为全局函数使用。
images.findAllPointsForColor(img, color, options)
img
{Image} 图片color
{number} | {string} 要检测的颜色options
{Object} 选项包括:region
{Array} 找色区域。是一个两个或四个元素的数组。(region[0], region[1])表示找色区域的左上角;region[2]*region[3]表示找色区域的宽高。如果只有region只有两个元素,则找色区域为(region[0], region[1])到图片右下角。如果不指定region选项,则找色区域为整张图片。similarity
{number} 找色时颜色相似度,范围为0~1(越大越相似,1为颜色相等,0为任何颜色都能匹配)。threshold
{number} 找色时颜色相似度的临界值,范围为0 ~ 255(越小越相似,0为颜色相等,255为任何颜色都能匹配)。默认为4。threshold和浮点数相似度(0.0~1.0)的换算为 similarity = (255 - threshold) / 255 。相似度与阈值二选一,同时存在则以相似度为准。
- 返回 {Array}
在图片中寻找所有颜色为color的点。找到时返回找到的点Point的数组,找不到时返回null。
例如找出所有白色的点:
log(images.findAllPointsForColor(img, "#ffffff"));
images.findColorEquals(img, color[, x, y, width, height])
img
{Image} 图片color
{number} | {string} 要寻找的颜色x
{number} 找色区域的左上角横坐标y
{number} 找色区域的左上角纵坐标width
{number} 找色区域的宽度height
{number} 找色区域的高度- 返回 {Point}
在图片img指定区域中找到颜色和color完全相等的某个点,并返回该点的左边;如果没有找到,则返回null
。
找色区域通过x
,
y
,
width
,
height
指定,如果不指定找色区域,则在整张图片中寻找。
该函数也可以作为全局函数使用。
示例: (通过找QQ红点的颜色来判断是否有未读消息)
requestScreenCapture();
launchApp("QQ");
sleep(1200);
var p = findColorEquals(captureScreen(), "#f64d30");
if(p){
toastLog("有未读消息");
}else{
toastLog("没有未读消息");
}
images.findMultiColors(img, firstColor, colors[, options])
img
{Image} 要找色的图片firstColor
{number} | {string} 第一个点的颜色colors
{Array} 表示剩下的点相对于第一个点的位置和颜色的数组,数组的每个元素为[x, y, color]options
{Object} 选项,包括:region
{Array} 找色区域。是一个两个或四个元素的数组。(region[0], region[1])表示找色区域的左上角;region[2]*region[3]表示找色区域的宽高。如果只有region只有两个元素,则找色区域为(region[0], region[1])到图片右下角。如果不指定region选项,则找色区域为整张图片。threshold
{number} 找色时颜色相似度的临界值,范围为0 ~ 255(越小越相似,0为颜色相等,255为任何颜色都能匹配)。默认为4。threshold和浮点数相似度(0.0~1.0)的换算为 similarity = (255 - threshold) / 255.
多点找色,类似于按键精灵的多点找色,其过程如下:
- 在图片img中找到颜色firstColor的位置(x0, y0)
- 对于数组colors的每个元素[x, y, color],检查图片img在位置(x + x0, y + y0)上的像素是否是颜色color,是的话返回(x0, y0),否则继续寻找firstColor的位置,重新执行第1步
- 整张图片都找不到时返回
null
例如,对于代码images.findMultiColors(img, "#123456", [[10, 20, "#ffffff"], [30, 40, "#000000"]])
,假设图片在(100,
200)的位置的颜色为#123456, 这时如果(110, 220)的位置的颜色为#fffff且(130, 240)的位置的颜色为#000000,则函数返回点(100, 200)。
如果要指定找色区域,则在options中指定,例如:
var p = images.findMultiColors(img, "#123456", [[10, 20, "#ffffff"], [30, 40, "#000000"]], {
region: [0, 960, 1080, 960]
});
images.detectsColor(image, color, x, y[, threshold = 16, algorithm = "diff"])
image
{Image} 图片color
{number} | {string} 要检测的颜色x
{number} 要检测的位置横坐标y
{number} 要检测的位置纵坐标threshold
{number} 颜色相似度临界值,默认为16。取值范围为0 ~ 255。algorithm
{string} 颜色匹配算法,包括:-
"equal": 相等匹配,只有与给定颜色color完全相等时才匹配。
-
"diff": 差值匹配。与给定颜色的R、G、B差的绝对值之和小于threshold时匹配。
-
"rgb": rgb欧拉距离相似度。与给定颜色color的rgb欧拉距离小于等于threshold时匹配。
-
"rgb+": 加权rgb欧拉距离匹配(LAB Delta E)。
-
"hs": hs欧拉距离匹配。hs为HSV空间的色调值。
-
返回图片image在位置(x, y)处是否匹配到颜色color。用于检测图片中某个位置是否是特定颜色。
一个判断微博客户端的某个微博是否被点赞过的例子:
requestScreenCapture();
// 找到点赞控件
var like = id("ly_feed_like_icon").findOne();
// 获取该控件中点坐标
var x = like.bounds().centerX();
var y = like.bounds().centerY();
// 截图
var img = captureScreen();
// 判断在该坐标的颜色是否为橙红色
if(images.detectsColor(img, "#fed9a8", x, y)){
// 是的话则已经是点赞过的了,不做任何动作
}else{
// 否则点击点赞按钮
like.click();
}
images.detectsMultiColors(img, x, y, firstColor, colors, options)
img
{Image} 目标图片x
{number} 第一个点的x坐标y
{number} 第一个点的y坐标firstColor
{number} | {string} 第一个点的颜色colors
{Array} 表示剩下的点相对于第一个点的位置和颜色的数组,数组的每个元素为[x, y, color]options
{Object} 选项,包括:region
{Array} 找色区域。是一个两个或四个元素的数组。(region[0], region[1])表示找色区域的左上角;region[2]*region[3]表示找色区域的宽高。如果只有region只有两个元素,则找色区域为(region[0], region[1])到图片右下角。如果不指定region选项,则区域为整张图片。threshold
{number} 比色时颜色相似度的临界值,范围为0 ~ 255(越小越相似,0为颜色相等,255为任何颜色都能匹配)。默认为4。threshold和浮点数相似度(0.0~1.0)的换算为 similarity = (255 - threshold) / 255.
- 返回
boolean
多点比色,返回img在起始位置(x, y)处的多个点的颜色是否匹配。
参见images.findMultiColors()
多点找色的文档。
log(images.detectsMultiColors(img, 100, 200, "#000000", [[3, 4, "#123456"], [8, 10, "#ff0000"]]));
images.findImage(img, template[, options])
[v8.5.5新增]
img
{Image} 大图片template
{Image} 小图片(模板)options
{Object} 找图选项
找图。在大图片img中查找小图片template的位置(模块匹配),找到时返回位置坐标(Point),找不到时返回null。
选项包括:
threshold
{number} 图片相似度。取值范围为0~1的浮点数。默认值为0.9。region
{Array} 找图区域。参见findColor函数关于region的说明。level
{number} 一般而言不必修改此参数。不加此参数时该参数会根据图片大小自动调整。找图算法是采用图像金字塔进行的, level参数表示金字塔的层次, level越大可能带来越高的找图效率,但也可能造成找图失败(图片因过度缩小而无法分辨)或返回错误位置。因此,除非您清楚该参数的意义并需要进行性能调优,否则不需要用到该参数。
该函数也可以作为全局函数使用。
一个最简单的找图例子如下:
var img = images.read("/sdcard/大图.png");
var templ = images.read("/sdcard/小图.png");
var p = findImage(img, templ);
if(p){
toastLog("找到啦:" + p);
}else{
toastLog("没找到");
}
稍微复杂点的区域找图例子如下:
requestScreenCapture();
var wx = images.read("/sdcard/微信图标.png");
// 返回桌面
home();
// 截图并找图
var p = findImage(captureScreen(), wx, {
region: [0, 50],
threshold: 0.8
});
if(p){
toastLog("在桌面找到了微信图标啦: " + p);
}else{
toastLog("在桌面没有找到微信图标");
}
images.findImageInRegion(img, template, x, y[, width, height, threshold])
区域找图的简便方法。相当于:
images.findImage(img, template, {
region: [x, y, width, height],
threshold: threshold
})
该函数也可以作为全局函数使用。
images.matchTemplate(img, template, options)
[v4.1.0新增]
img
{Image} 大图片template
{Image} 小图片(模板)options
{Object} 找图选项:threshold
{number} 图片相似度。取值范围为0~1的浮点数。默认值为0.9。region
{Array} 找图区域。参见findColor函数关于region的说明。max
{number} 找图结果最大数量,默认为5transparentMask
{boolean} 是否使用透明模板找图。此选项开启后,传入的template参数可以是一个透明背景的图片对象用于匹配。此选项为 [Pro 8.0新增] 。level
{number} 一般而言不必修改此参数。不加此参数时该参数会根据图片大小自动调整。找图算法是采用图像金字塔进行的, level参数表示金字塔的层次, level越大可能带来越高的找图效率,但也可能造成找图失败(图片因过度缩小而无法分辨)或返回错误位置。因此,除非您清楚该参数的意义并需要进行性能调优,否则不需要用到该参数。
- 返回 {MatchingResult}
在大图片中搜索小图片,并返回搜索结果MatchingResult。该函数可以用于找图时找出多个位置,可以通过max参数控制最大的结果数量。也可以对匹配结果进行排序、求最值等操作。
images.findCircles(gray, options)
-
gray
{Image} 灰度图片 -
options
{Object} 选项包括:region
{Array} 找圆区域。是一个两个或四个元素的数组。(region[0], region[1])表示找圆区域的左上角;region[2]*region[3]表示找圆区域的宽高。如果只有region只有两个元素,则找圆区域为(region[0], region[1])到图片右下角。如果不指定region选项,则找圆区域为整张图片。dp
{number} dp是累加面与原始图像相比的分辨率的反比参数,dp=2时累计面分辨率是元素图像的一半,宽高都缩减为原来的一半,dp=1时,两者相同。默认为1。minDst
{number} minDist定义了两个圆心之间的最小距离。默认为图片高度的八分之一。param1
{number} param1是Canny边缘检测的高阈值,低阈值被自动置为高阈值的一半。默认为100,范围为0-255。param2
{number} param2是累加平面对是否是圆的判定阈值,默认为100。minRadius
{number} 定义了检测到的圆的半径的最小值,默认为0。maxRadius
{number} 定义了检测到的圆的半径的最大值,0为不限制最大值,默认为0。
-
返回 {Array}
在图片中寻找圆(做霍夫圆变换)。找到时返回找到的所有圆{x,y,radius}的数组,找不到时返回null。
一个寻找圆的例子:
// 请求截图
requestScreenCapture();
// 截图
let img = captureScreen();
// 灰度化图片
let gray = images.grayscale(img);
// 找圆
let arr = findCircles(gray, {
dp: 1,
minDst: 80,
param1: 100,
param2: 100,
minRadius: 50,
maxRadius: 80,
});
// 回收图片
gray.recycle();
$images.detectAndComputeFeatures(img[, options])
[v9.2新增]
-
img
{Image} 图片,要计算特征的图片 -
options
{object} 特征计算选项,可选参数:scale
{number} 计算特征时图片的缩放比例,缩放比例越小,计算特征越快,但可能因为放缩过度导致特征计算错误。对于宽度 * 高度 > 1000000的图片,scale参数默认为0.5,否则scale默认为1grayscale
{boolean} 是否灰度化后再计算特征,默认为true
method
{string} 图像特征匹配的方法,默认为SIFT
,也可指定为ORB
(不推荐)region
{Array} 图像的匹配区域,不填此字段时则为整个图片计算特征
-
返回 {ImageFeatures} 保存图片特征的对象,不用时需要调用
recycle()
回收
对给定图片计算特征,将图片计算后的特征信息返回。该特征信息对象可用于后续使用matchFeatures函数做特征匹配。
一般而言,小图的特征可以在程序开始时就计算,在程序结束时再回收。如果每次截图时都去读取小图、计算小图特征,不仅会导致程序运行效率低,而且会导致内存碎片,从而使得内存难以利用和更快耗尽。
$images.matchFeatures(scene, object[, options])
[v9.2新增]
-
scene
{ImageFeatures} 场景图片的特征对象(大图特征) -
object
{ImageFeatures} 目标图片的特征对象(小图特征) -
options
{object} 可选参数:matcher
{string} 特征匹配方式,默认为FLANNBASED
,可选的值有"FLANNBASED"
,"BRUTEFORCE"
,"BRUTEFORCE_L1"
,"BRUTEFORCE_HAMMING"
,"BRUTEFORCE_HAMMINGLUT"
,"BRUTEFORCE_SL2"
,除了FLANNBASED
外其他匹配方式未经过充分测试drawMatches
{string} 绘制图片匹配详情的路径,若为空则不绘制匹配详情。此选项一般为调试使用,在真正匹配时请勿指定,否则会增加耗时。thredshold
{number} 匹配阈值,默认为0.7
-
返回 {ObjectFrame} | {null} 小图在大图中的匹配位置,若未找到则返回
null
特征匹配提供了全分辨率找图功能,可以识别检测图像中明显的特征并根据特征来查找类似图片。即使图片的分辨率、形状、旋转有差异也能识别出来,但匹配速度相对较慢。
需要注意的是,计算特征的过程也比较耗时,因此请勿在每次匹配时才计算小图的特征,小图若不变可以提前计算特征并复用特征对象。
以下是一个简单的示例,也在CloudControl Pro内置示例"图片与图色处理 - 找图找色"文件夹中,可直接运行。
// 读取小图
let hellokitty = $images.read('./hellokitty.jpg');
// 计算小图特征
let objectFeatures = $images.detectAndComputeFeatures(hellokitty);
// 请求截图权限
requestScreenCapture();
// 打开HelloKitty图片
$app.openUrl('https://baike.baidu.com/item/Hello%20Kitty/984270')
let n = 3;
for (let i = 0; i < n; i++) {
sleep(3000);
let capture = captureScreen();
// 若要提高效率,可以在计算大图特征时调整scale参数,默认为0.5,
// 越小越快,但可以放缩过度导致匹配错误。若在特征匹配时无法搜索到正确结果,可以调整这里的参数,比如{scale: 1}
// 也可以在这里指定{region: [...]}参数只计算这个区域的特征提高效率
let sceneFeatures = $images.detectAndComputeFeatures(capture);
// 最后一次匹配时,我们将特征和匹配绘制出来,在调试时更容易看出匹配效果,但会增加耗时
let drawMatches = (i === n - 1 ? './matches.jpg' : undefined);
let result = $images.matchFeatures(sceneFeatures, objectFeatures, { drawMatches });
// 打印结果和中心点,可使用click(reuslt.centerX, result.centerY)点击
console.log(result, result ? result.center : null);
// 回收特征对象
sceneFeatures.recycle();
if (drawMatches) {
// 可以在当前目录查看matches.jpg图片,会绘制详细匹配详情
app.viewFile('./matches.jpg');
}
}
// 回收小图特征对象
objectFeatures.recycle();
hellokitty.recycle();
ImageFeatures
[v9.2新增]
存储特征信息的类,仅用于特征匹配。
ImageFeatures.recycle()
回收特征对象。必须显式在不使用该对象时调用,否则会导致内存泄露而程序崩溃。
ObjectFrame
[v9.2新增]
特征匹配返回的结果,表示一个四边形。
ObjectFrame.topLeft
- {Point}
四边形的左上角坐标。
ObjectFrame.topRight
- {Point}
四边形的右上角坐标。
ObjectFrame.bottomLeft
- {Point}
四边形的左下角坐标。
ObjectFrame.bottomRight
- {Point}
四边形的右下角坐标。
ObjectFrame.center
- {Point}
四边形的中心点坐标。
ObjectFrame.centerX
- {number}
四边形的中心点x坐标。
ObjectFrame.centerY
- {number}
四边形的中心点y坐标。
MatchingResult
[v4.1.0新增]
MatchingResult.matches
- {Array} 匹配结果的数组。
数组的元素是一个Match对象:
point
{Point} 匹配位置similarity
{number} 相似度
例如:
var result = images.matchTemplate(img, template, {
max: 100
});
result.matches.forEach(match => {
log("point = " + match.point + ", similarity = " + match.similarity);
});
MatchingResult.points
- {Array} 匹配位置的数组。
MatchingResult.first()
- 返回 {Match}
第一个匹配结果。如果没有任何匹配,则返回null
。
MatchingResult.last()
- 返回 {Match}
最后一个匹配结果。如果没有任何匹配,则返回null
。
MatchingResult.leftmost()
- 返回 {Match}
位于大图片最左边的匹配结果。如果没有任何匹配,则返回null
。
MatchingResult.topmost()
- 返回 {Match}
位于大图片最上边的匹配结果。如果没有任何匹配,则返回null
。
MatchingResult.rightmost()
- 返回 {Match}
位于大图片最右边的匹配结果。如果没有任何匹配,则返回null
。
MatchingResult.bottommost()
- 返回 {Match}
位于大图片最下边的匹配结果。如果没有任何匹配,则返回null
。
MatchingResult.best()
- 返回 {Match}
相似度最高的匹配结果。如果没有任何匹配,则返回null
。
MatchingResult.worst()
- 返回 {Match}
相似度最低的匹配结果。如果没有任何匹配,则返回null
。
MatchingResult.sortBy(cmp)
cmp
{Function} | {string} 比较函数,或者是一个字符串表示排序方向。例如"left"表示将匹配结果按匹配位置从左往右排序、"top"表示将匹配结果按匹配位置从上往下排序,"left-top"表示将匹配结果按匹配位置从左往右、从上往下排序。方向包括left
(左),top
(上),right
(右),bottom
(下)。- {MatchingResult}
对匹配结果进行排序,并返回排序后的结果。
var result = images.matchTemplate(img, template, {
max: 100
});
log(result.sortBy("top-right"));
Image
表示一张图片,可以是截图的图片,或者本地读取的图片,或者从网络获取的图片。
Image.getWidth()
返回以像素为单位图片宽度。
Image.getHeight()
返回以像素为单位的图片高度。
Image.saveTo(path)
path
{string} 路径
把图片保存到路径path。(如果文件存在则覆盖)
Image.pixel(x, y)
x
{number} 横坐标y
{number} 纵坐标
返回图片image在点(x, y)处的像素的ARGB值。
该值的格式为0xAARRGGBB,是一个"32位整数"(虽然JavaScript中并不区分整数类型和其他数值类型)。
坐标系以图片左上角为原点。以图片左侧边为y轴,上侧边为x轴。
Point
findColor, findImage返回的对象。表示一个点(坐标)。
Point.x
横坐标。
Point.y
纵坐标。
ColorMapping
通过颜色映射的实现一种找色方式,对于同一张图找多次色,每次找色相比images模块里的函数非常快,只是需要相比一般找色需要一个初始化过程。
注意!ColorMapping仅能使用截图的图片对象初始化颜色映射。
初始化方式:
// 申请截图权限
$images.requestScreenCapture();
// 初始化ColorMapping
let ColorMapping = $colors.mapping;
// 创建ColorMapping实例
let cm = new ColorMapping();
// 截屏
let img = $images.captureScreen();
// 初始化颜色映射
cm.reset(img);
// 使用完后及时回收
cm.recycle();
如果不想手动回收,可以用ColorMapping的单例,这个单例会自动在脚本结束时回收。
// 申请截图权限
$images.requestScreenCapture();
// 初始化ColorMapping
let ColorMapping = $colors.mapping;
// 创建ColorMapping实例
let cm = ColorMapping.singleton;
// 截屏
let img = $images.captureScreen();
// 初始化颜色映射
cm.reset(img);
// 找色
cm.findColor("#ffffff")
ColorMapping.singleton
- {ColorMapping}
ColorMapping的全局单例对象。
ColorMapping.reset(img)
img
{Image} 截图
此操作会重新初始化颜色映射的数据。
ColorMapping.recycle()
此操作会释放ColorMapping对象。
ColorMapping.findColor(color[, options])
color
{number} | {string} 要检测的颜色options
{Object} 选项包括:region
{Array} 找色区域。是一个两个或四个元素的数组。(region[0], region[1])表示找色区域的左上角;region[2]*region[3]表示找色区域的宽高。如果只有region只有两个元素,则找色区域为(region[0], region[1])到图片右下角。如果不指定region选项,则找色区域为整张图片。similarity
{number} 找色时颜色相似度,范围为0~1(越大越相似,1为颜色相等,0为任何颜色都能匹配)。threshold
{number} 找色时颜色相似度的临界值,范围为0 ~ 255(越小越相似,0为颜色相等,255为任何颜色都能匹配)。默认为4。threshold和浮点数相似度(0.0~1.0)的换算为 similarity = (255 - threshold) / 255 。相似度与阈值二选一,同时存在则以相似度为准。
- 返回 {Point}
在图片中寻找颜色color。找到时返回找到的点Point,找不到时返回null。
一个同一张图多次找色的例子如下:
// 申请截图权限
$images.requestScreenCapture();
// 初始化ColorMapping
let ColorMapping = $colors.mapping;
// 创建ColorMapping实例
let cm = new ColorMapping();
// 使用ColorMapping找色
while (true) {
// 截屏
let img = $images.captureScreen();
// 初始化颜色映射
cm.reset(img);
let p1 = cm.findColor("#ffffff");
if (p1) {
// ...
console.log("白色点坐标" + p1);
continue;
}
let p2 = cm.findColor("#000000");
if (p2) {
// ...
console.log("黑色点坐标" + p2);
continue;
}
}
// 释放ColorMapping
cm.recycle();
一个区域找色的例子如下:
// 申请截图权限
$images.requestScreenCapture();
// 初始化ColorMapping
let ColorMapping = $colors.mapping;
// 创建ColorMapping实例
let cm = new ColorMapping();
// 截屏
let img = $images.captureScreen();
// 初始化颜色映射
cm.reset(img);
// 使用ColorMapping找色,指定找色区域为在位置(400, 500)的宽为300长为200的区域,指定找色临界值为4
let point = cm.findColor("#00ff00", {
region: [400, 500, 300, 200],
threshold: 4
});
if(point){
toastLog("找到啦:" + point);
}else{
toastLog("没找到");
}
// 释放ColorMapping
cm.recycle();
ColorMapping.findMultiColors(firstColor, colors, options)
firstColor
{number} | {string} 第一个点的颜色colors
{Array} 表示剩下的点相对于第一个点的位置和颜色的数组,数组的每个元素为[x, y, color]options
{Object} 选项,包括:region
{Array} 找色区域。是一个两个或四个元素的数组。(region[0], region[1])表示找色区域的左上角;region[2]*region[3]表示找色区域的宽高。如果只有region只有两个元素,则找色区域为(region[0], region[1])到图片右下角。如果不指定region选项,则找色区域为整张图片。threshold
{number} 找色时颜色相似度的临界值,范围为0 ~ 255(越小越相似,0为颜色相等,255为任何颜色都能匹配)。默认为4。threshold和浮点数相似度(0.0~1.0)的换算为 similarity = (255 - threshold) / 255。
- 返回 {Point}
多点找色,与images.findMultiColors类似,但多次在同一张图片中找色速度极快。
一个同一张图片多次多点找色的例子:
// 申请截图权限
$images.requestScreenCapture();
// 初始化ColorMapping
let ColorMapping = $colors.mapping;
// 创建ColorMapping实例
let cm = new ColorMapping();
// 截屏
let img = $images.captureScreen();
// 初始化颜色映射
cm.reset(img);
// 使用ColorMapping多点找色
let p1 = cm.findMultiColors("#ff00ff", [[10, 20, "#ffffff"], [30, 40, "#000000"]]);
let p2 = cm.findMultiColors("#ff00ff", [[10, 20, "#ffffff"], [30, 40, "#000000"]]);
log("p1" + p1 + "p2" + p2);
// 释放ColorMapping
cm.recycle();
ColorMapping.findAllPointsForColor(color, options)
color
{number} | {string} 要检测的颜色options
{Object} 选项包括:region
{Array} 找色区域。是一个两个或四个元素的数组。(region[0], region[1])表示找色区域的左上角;region[2]*region[3]表示找色区域的宽高。如果只有region只有两个元素,则找色区域为(region[0], region[1])到图片右下角。如果不指定region选项,则找色区域为整张图片。similarity
{number} 找色时颜色相似度,范围为0~1(越大越相似,1为颜色相等,0为任何颜色都能匹配)。threshold
{number} 找色时颜色相似度的临界值,范围为0—255(越小越相似,0为颜色相等,255为任何颜色都能匹配)。默认为4。threshold和浮点数相似度(0.0~1.0)的换算为 similarity = (255 - threshold) / 255 。相似度与阈值二选一,同时存在则以相似度为准。
- 返回 {Array}
在图片中寻找所有颜色为color的点。找到时返回找到的点Point的数组,找不到时返回null。
找出所有白色点和所有黑色点的例子:
// 申请截图权限
$images.requestScreenCapture();
// 初始化ColorMapping
let ColorMapping = $colors.mapping;
// 创建ColorMapping实例
let cm = new ColorMapping();
// 截屏
let img = $images.captureScreen();
// 初始化颜色映射
cm.reset(img);
// 使用ColorMapping多点找色
let whitePoints = cm.findAllPointsForColor("#ffffff");
let blackPoints = cm.findAllPointsForColor("#000000");
if (whitePoints != null) {
log("白色点有" + whitePoints.length + "个");
} else {
log("未找到白色点");
}
if (blackPoints != null) {
log("黑色点有" + blackPoints.length + "个");
} else {
log("未找到黑色点");
}
// 释放ColorMapping
cm.recycle();