autojs图片回收时img, bitmap和mat三者的关系

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 牙叔教程 简单易懂

牙叔教程 简单易懂


autojs图片的数据表现形式, 一共有三种

  • img: com.stardust.autojs.core.image.ImageWrapper
  • bitmap
  • mat


三种图片数据格式互相转换

img转bitmap和mat

img.bitmap
img.mat


bitmap转img

com.stardust.autojs.core.image.ImageWrapper.ofMat(bitmap)


mat转img

com.stardust.autojs.core.image.ImageWrapper.ofMat(mat)


bitmap转mat

org.opencv.android.Utils.bitmapToMat(bitmap, mat);


mat转bitmap

org.opencv.android.Utils.matToBitmap(mat, bitmap);


img回收时, 会影响bitmap和mat吗

公共函数

// 打印图片信息
function printInfo(tag, img, bitmap, mat) {
  let arr = ["\n"];
  arr.push("tag = " + tag);
  try {
    arr.push(java.lang.String.format("%1$-9s: width = %2$s, height = %3$s", "img", img.width, img.height));
  } catch (e) {
    arr.push(java.lang.String.format("%1$-9s: %2$ss", "img", e));
  }
  arr.push(
    java.lang.String.format(
      "%1$-9s: width = %2$s, height = %3$s, allocationByteCount = %4$s",
      "bitmap",
      bitmap.width,
      bitmap.height,
      bitmap.allocationByteCount
    )
  );
  arr.push(java.lang.String.format("%1$-9s: width = %2$s, height = %3$s", "mat", mat.width(), mat.height()));
  log(arr.join("\n"));
}
// 查看img
function viewImg(img) {
  images.save(img, "/sdcard/1.jpg", "jpg", 50);
  app.viewFile("/sdcard/1.jpg");
}
// 查看mat
function viewMat(mat) {
  let mat2 = mat.clone();
  Imgproc.cvtColor(mat, mat2, Imgproc.COLOR_BGRA2RGBA);
  let tempFilePath = files.join(files.getSdcardPath(), "脚本", "mat.png");
  Imgcodecs.imwrite(tempFilePath, mat2);
  mat2.release();
  app.viewFile(tempFilePath);
}


测试代码

let imgPath = files.path("./牙叔正方形.png");
let img = images.read(imgPath);
let bitmap = img.bitmap;
let mat = img.mat;
printInfo("原始图片信息", img, bitmap, mat);
img.recycle();
printInfo("释放了img后的图片信息", img, bitmap, mat);


日志

tag = 原始图片信息
img      : width = 564.0, height = 564.0
bitmap   : width = 564.0, height = 564.0, allocationByteCount = 1272384.0
mat      : width = 564.0, height = 564.0
11-19 17:56:54.150 Script-56 Main [remote://789216b9dbb2c184ad7efa6ee6d2c830/main.js]/D:
tag = 释放了img后的图片信息
img      : JavaException: java.lang.IllegalStateException: image has been recycleds
bitmap   : width = 564.0, height = 564.0, allocationByteCount = 0.0
mat      : width = 0.0, height = 0.0


从日志可以看出, bitmap的大小归零了, 那么img还能用吗? 我们用图色命令来测试一下

比如获取某个点的颜色

images.pixel(img, 100, 200)


代码报错

Wrapped java.lang.IllegalStateException: Can't call getPixel() on a recycled bitmap


mg不能正常使用了,

那么此时img算回收了吗?

至少mat还是存在的, mat可以正常使用, 所以img也不算回收,


我们用代码来判断一下图片是否回收

log(img.isRecycled()); // false


代码说图片并没有回收, 那么此时把mat也释放掉, img算不算回收了呢?

mat.release();
log(img.isRecycled()); // false

还是false, img并没有被标记为已回收


autojs的img回收方法具体代码

public synchronized void recycle() {
    Bitmap bitmap = this.mBitmap;
    if (bitmap != null) {
        bitmap.recycle();
    }
    this.mBitmap = null;
    Mat mat = this.mMat;
    if (mat != null) {
        OpenCVHelper.release(mat);
    }
    this.mMat = null;
    Image image = this.mediaImage;
    if (image != null) {
        image.close();
    }
    this.mediaImage = null;
    Debug.INSTANCE.noMemoryLeak(this.id);
    d<b> dVar = this.ref;
    if (dVar != null) {
        dVar.b = 0;
    }
    this.isRecycled = true;
}


看着还是有点复杂, mediaImage是个啥? 我都没用过, 也不管用管它了, 知道有这么个东西就行


mat回收时, 会影响img和bitmap吗

测试代码

let imgPath = files.path("./牙叔正方形.png");
let img = images.read(imgPath);
let bitmap = img.bitmap;
let mat = img.mat;
printInfo("原始图片信息", img, bitmap, mat);
mat.release();
printInfo("释放了mat后的图片信息", img, bitmap, mat);


日志

tag = 原始图片信息
img      : width = 564.0, height = 564.0
bitmap   : width = 564.0, height = 564.0, allocationByteCount = 1272384.0
mat      : width = 564.0, height = 564.0
11-19 18:24:44.707 Script-81 Main [remote://789216b9dbb2c184ad7efa6ee6d2c830/main.js]/D:
tag = 释放了mat后的图片信息
img      : width = 564.0, height = 564.0
bitmap   : width = 564.0, height = 564.0, allocationByteCount = 1272384.0
mat      : width = 0.0, height = 0.0


从日志可以看出, mat已经归零了, bitmap没有变化, img此时能用吗? 我们用代码测一下
比如获取某个点的颜色

images.pixel(img, 100, 200); // -16777212


总结

图片回收一律用img, 只要img回收了, 那么bitmap和mat也就回收了;

除非你用了bitmap.copy或者mat.clone, 来复制图片数据,

此时你就要自己去回收你复制的图片数据了


以上代码的测试环境

手机: Mi 11 Pro

Android版本: 11

Autojs版本: 9.0.11

名人名言


思路是最重要的, 其他的百度, bing, stackoverflow, github, 安卓文档, autojs文档, 最后才是群里问问
--- 牙叔教程


声明


部分内容来自网络
本教程仅用于学习, 禁止用于其他用途



相关实践学习
通过日志服务实现云资源OSS的安全审计
本实验介绍如何通过日志服务实现云资源OSS的安全审计。
相关文章
|
Android开发
autojs无Root访问data目录实现
牙叔教程 简单易懂
2839 0
|
Android开发
autojs之保活
autojs打包的app经常在后台被杀,请做到以下几点来保活: autojs版本号
2457 0
autojs之保活
|
XML 分布式计算 监控
Oozie工作流管理系统设计与实践:面试经验与必备知识点解析
【4月更文挑战第9天】本文详述了Oozie工作流管理系统的核心概念,包括安装配置、Workflow XML、Action、Coordinator和Bundle XML定义。此外,讨论了工作流设计实践,如监控调试、自动化运维,并对比了Oozie与其他工作流工具的差异。文中还分享了面试经验及解决实际项目挑战的方法,同时展望了Oozie的未来发展趋势。通过学习,读者能提升Oozie技术能力,为面试做好充分准备。
261 0
AutoJs Pro 7.0.4-1 实战教程 ---火热持续更新中
AutoJs Pro 7.0.4-1 实战教程 ---火热持续更新中
575 0
|
存储 Kubernetes C++
Kubernetes VS Docker Swarm:哪个容器编排工具更适合你?
当今,容器化技术已成为IT领域的热门话题,而容器编排工具是实现容器自动化部署和管理的关键。本文将比较两种主流的容器编排工具Kubernetes和Docker Swarm,并探讨它们的优缺点,以帮助你选择最适合自己的工具。
|
11月前
|
编译器 Linux C++
《C++跨平台编译:打破系统边界,释放代码潜能》
C++作为一门强大的编程语言,在多元化软件开发环境中面临跨平台编译的挑战。本文探讨了跨平台编译的重要性,包括拓宽用户群体和资源利用,以及面临的操作系统差异、编译器差异和依赖库问题。通过使用跨平台构建系统、抽象平台相关代码和管理依赖库等策略,可以有效应对这些挑战,提升软件的市场竞争力和资源利用效率。
225 0
|
Python Windows
在 Windows 平台下打包 Python 多进程代码为 exe 文件的问题及解决方案
在使用 Python 进行多进程编程时,在 Windows 平台下可能会出现将代码打包为 exe 文件后无法正常运行的问题。这个问题主要是由于在 Windows 下创建新的进程需要复制父进程的内存空间,而 Python 多进程机制需要先完成父进程的初始化阶段后才能启动子进程,所以在这个过程中可能会出现错误。此外,由于没有显式导入 Python 解释器,也会导致 Python 解释器无法正常工作。为了解决这个问题,我们可以使用函数。
425 5
|
人工智能 搜索推荐 机器人
AI发展已经一段时间了,当前社会身边哪些功能已经在运用了AI技术?未来AI技术还将有哪些地方会运用?
AI技术现已被广泛应用在智能家居(如自动化控制与安全)、个性化教育(定制化学习与辅助教学)、精准医疗(疾病诊断与药物研发)、智能服务(如智能客服)和金融服务(风险评估)等领域。未来,预计AI将在AI PC、人机协创、超级视野、机器人和零搜索等领域发挥更大作用,实现信息主动推送、无缝沟通和创新服务。随着技术进步,AI将持续影响并改变我们的生活。【6月更文挑战第2天】
782 0
|
人工智能 编解码
图片无损放大-AI为图片开光
图片无损放大的, 免费的, AI加持, 全平台的开源软件, 放大后的图片是 1352X1352, 如果觉得不够大, 还可以选择第二个步骤中的 dobule 放大, 那样生成的图片就是 2704X2704
900 0
|
文字识别
autojs之浩然ocr-不安装插件就能用ocr
使用场景 不想安装浩然ocr插件
1976 0

热门文章

最新文章