图片 - Images

# Images > Stability: 2 - Stable images模块提供了一些手机设备中常见的图片处理函数,包括截图、读写图片、图片剪裁、旋转、二值化、找色找图等。 该模块分为两个部分,找图找色部分和图片处理部分。 >i 需要注意的是,**image对象创建后尽量在不使用时进行回收**,同时避免循环创建大量图片。因为图片是一种占用内存比较大的资源,尽管Auto.js通过各种方式(比如图片缓存机制、垃圾回收时回收图片、脚本结束时回收所有图片)尽量降低图片资源的泄漏和内存占用,但是糟糕的代码仍然可以占用大量内存。 Image对象通过调用recycle()函数来回收。例如: ```js // 读取图片 var img = images.read("./1.png"); //对图片进行操作 ... // 回收图片 img.recycle(); ``` 例外的是,**caputerScreen()返回的图片不需要回收**。 ## 图片处理 ## 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} 图片格式,可选的值为: 1. png 2. jpeg/jpg 3. webp - quality {number} 图片质量,为0~100的整数值 **把图片image以PNG格式保存到path中**。如果文件不存在会被创建;文件存在会被覆盖。 ```js //把图片压缩为原来的一半质量并保存 var img = images.read("/sdcard/1.png"); images.save(img, "/sdcard/1.jpg", "jpg", 50); app.viewFile("/sdcard/1.jpg"); media.scanFile("/sdcard/1.jpg"); //刷新图库 ``` > 以下非官方例子 ```js //下载图片 let res =http.get("http://imgsrc.baidu.com/forum/w%3D580/sign=5339d407ab8b87d65042ab1737082860/ffef9a44ebf81a4cb12a8affdd2a6059242da6cd.jpg") if (res.statusCode == 200) { let img = images.fromBytes(res.body.bytes()); img = images.resize(img, [500, 600]); log(img); var s=images.save(img, "/sdcard/DCIM/Camera/IMG_20200121_99999.jpg", "jpg", 50); media.scanFile("/sdcard/DCIM/Camera/IMG_20200121_99999.jpg"); //刷新图片文件 log(s); toast("下载成功"); } ``` ## images.fromBase64(base64) - base64 {string} 图片的Base64数据 返回 {Image} **解码Base64数据**并返回解码后的图片Image对象。如果base64无法解码则返回null。 ## images.toBase64(img[, format = "png", quality = 100]) - image {image} 图片 - format {string} 图片格式,可选的值为: 1. png 2. jpeg/jpg 3. webp - quality {number} 图片质量,为0~100的整数值 返回 {string} **把图片编码为base64数据**并返回。 联众识别2.0接口调用示例: ```js let src = captureScreen(), clip; //截图 // 红米7a 滑块区域的两种图片 if (findNode("text", "请进行安全验证")) { clip = images.clip(src, 104, 538, 512, 256); } else if (findNode("text", "请拖动下方滑块完成拼图")) { clip = images.clip(src, 67, 482, 585, 329); } let result = getCode(clip); log(result) // { code: '-1', msg: '网络链接超时...', data: {} } // { code: 0, msg: '', data: { recognition: '1' } } // { code: 0, msg: '', data: { recognition: '354,205' } } 识别成功 // 联众接入技术 10:11:53 // 如果平台压缩了客户上传图像展示的话 返还结果是 是储存结果乘以压缩比例 // 平台后台上,识别结果显示的 是储存图像的坐标值 // 以程序返还坐标值为准 那个是以客户原图返回的坐标 function getCode(img) { http.__okhttp__.setTimeout(3e4); var imgData = images.toBase64(img, format = "png"), i = device.release, c = device.model, s = device.buildId; try { var json = http.postJson("https://v2-api.jsdama.com/upload", { softwareId: softwareId, softwareSecret: softwareSecret, username: username, password: password, captchaData: imgData, captchaType: captchaType, captchaMinLength: 1, captchaMaxLength: 1, workerTipsId: 0 }, { headers: { "User-Agent": "Mozilla/5.0 (Linux; Android " + i + "; " + c + " Build/" + s + "; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/66.0.3359.126 Mobile Safari/537.36", } }); } catch (e) { return { code: "-1", msg: "网络链接超时...", data: {} }; } var html = json.body.json(), code = html.code, message = html.message; if (code == "0") { // log(html.data.recognition) // { data: { recognition: '296,192', captchaId: '20190903:000000000033308132201' }, message: '', code: 0 } return { code: code, msg: message, data: { recognition: html.data.recognition } }; } else if (code == "10079009" || code == "10142006" || code == "10142004" || code == "10142005" || code == "10079006") { return { code: code, msg: message, data: {} }; } else { log("其他识别结果", code) }; return html; } ``` ## images.fromBytes(bytes) - bytes {byte[]} 字节数组 解码字节数组bytes并返回解码后的图片Image对象。如果bytes无法解码则返回null。 ## images.toBytes(img[, format = "png", quality = 100]) - image {image} 图片 - format {string} 图片格式,可选的值为: 1. png 2. jpeg/jpg 3. webp - quality {number} 图片质量,为0~100的整数值 返回 {byte[]} **把图片编码为字节数组**并返回。 ## images.clip(img, x, y, w, h) - img {Image} 图片 - x {number} 剪切区域的左上角横坐标 - y {number} 剪切区域的左上角纵坐标 - w {number} 剪切区域的宽度 - h {number} 剪切区域的高度 返回 {Image} **从图片img的位置(x, y)处剪切大小为w * h的区域**,并返回该剪切区域的新图片。 ```js 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"(线性插值),可选的值有: 1. NEAREST 最近邻插值 2. LINEAR 线性插值(默认) 3. AREA 区域插值 4. CUBIC 三次样条插值 5. LANCZOS4 Lanczos插值 参见InterpolationFlags 返回 {Image} **调整图片大小**,并返回调整后的图片。例如把图片放缩为200*300:images.resize(img, [200, 300])。 参见Imgproc.resize。 ## images.scale(img, fx, fy[, interpolation]) [v4.1.0新增] - img {Image} 图片 - fx {number} 宽度放缩倍数 - fy {number} 高度放缩倍数 - interpolation {string} 插值方法,可选,默认为"LINEAR"(线性插值),可选的值有: 1. NEAREST 最近邻插值 2. LINEAR 线性插值(默认) 3. AREA 区域插值 4. CUBIC 三次样条插值 5. LANCZOS4 Lanczos插值 参见InterpolationFlags 返回 {Image} **放缩图片**,并返回放缩后的图片。例如把图片变成原来的一半: ```js images.scale(img, 0.5, 0.5)。 ``` 参见Imgproc.resize。 ## images.rotate(img, degress[, x, y]) [v4.1.0新增] - img {Image} 图片 - degress {number} 旋转角度。 - x {number} 旋转中心x坐标,默认为图片中点 - y {number} 旋转中心y坐标,默认为图片中点 返回 {Image} **将图片逆时针旋转**degress度,返回旋转后的图片对象。 例如逆时针旋转90度为 ```js images.rotate(img, 90) ``` ## images.concat(img1, image2[, direction]) [v4.1.0新增] - img1 {Image} 图片1 - img2 {Image} 图片2 - direction {string} 连接方向,默认为"RIGHT",可选的值有: 1. LEFT 将图片2接到图片1左边 2. RIGHT 将图片2接到图片1右边 3. TOP 将图片2接到图片1上边 4. BOTTOM 将图片2接到图片1下边 返回 {Image} **连接两张图片**,并返回连接后的图像。如果两张图片大小不一致,小的那张将适当居中。 ## images.grayscale(img) [v4.1.0新增] - img {Image} 图片 返回 {Image} **灰度化图片**,并返回灰度化后的图片。 ## image.threshold(img, threshold, maxVal[, type]) [v4.1.0新增] - img {Image} 图片 - threshold {number} 阈值 - maxVal {number} 最大值 - type {string} 阈值化类型,默认为"BINARY",参见ThresholdTypes, 可选的值: 1. BINARY 2. BINARY_INV 3. TRUNC 4. TOZERO 5. TOZERO_INV 6. OTSU 7. 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} 在一个邻域内计算阈值所采用的算法,可选的值有: 1. MEAN_C 计算出领域的平均值再减去参数C的值 2. GAUSSIAN_C 计算出领域的高斯均值再减去参数C的值 - thresholdType {string} 阈值化类型,可选的值有: 1. BINARY 2. 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),这里只列出几个: 1. BGR2GRAY BGR转换为灰度 2. 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",可选的值有: 1. CONSTANT iiiiii|abcdefgh|iiiiiii with some specified i 2. REPLICATE aaaaaa|abcdefgh|hhhhhhh 3. REFLECT fedcba|abcdefgh|hgfedcb 4. WRAP cdefgh|abcdefgh|abcdefg 5. REFLECT_101 gfedcb|abcdefgh|gfedcba 6. TRANSPARENT uvwxyz|abcdefgh|ijklmno 7. REFLECT101 same as BORDER_REFLECT_101 8. DEFAULT same as BORDER_REFLECT_101 9. ISOLATED 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.matToImage(mat) [v4.1.0新增] - mat {Mat} OpenCV的Mat对象 返回 {Image} **把Mat对象转换为Image对象**。