bitmap和mat三者的关系

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 − 9 s : w i d t h = -9s: width = %2 9s:width=s, height = %3KaTeX parse error: Expected 'EOF', got '}' at position 39: …mg.height)); }̲ catch (e) { …-9s: %2KaTeX parse error: Expected 'EOF', got '}' at position 20: … "img", e)); }̲ arr.push( …-9s: width = %2 s , h e i g h t = s, height = %3 s,height=s, allocationByteCount = %4 s " , " b i t m a p " , b i t m a p . w i d t h , b i t m a p . h e i g h t , b i t m a p . a l l o c a t i o n B y t e C o u n t ) ) ; a r r . p u s h ( j a v a . l a n g . S t r i n g . f o r m a t ( " s", "bitmap", bitmap.width, bitmap.height, bitmap.allocationByteCount ) ); arr.push(java.lang.String.format("%1 s","bitmap",bitmap.width,bitmap.height,bitmap.allocationByteCount));arr.push(java.lang.String.format("-9s: width = %2 s , h e i g h t = s, height = %3 s,height=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

从日志可以看出, img回收之后, bitmap虽然宽高还是原来的, 但是大小已经变成了0, mat的宽高是0,

也就是说, img回收以后, bitmap和mat必然也回收了

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

测试代码

let imgPath = files.path("./牙叔正方形.png");
let img = images.read(imgPath);
let bitmap = img.bitmap;
let mat = img.mat;
printInfo(“原始图片信息”, img, bitmap, mat);
bitmap.recycle();
// mat.release();
printInfo(“释放了bitmap后的图片信息”, 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:00:35.347 Script-58 Main [remote://789216b9dbb2c184ad7efa6ee6d2c830/main.js]/D:

tag = 释放了bitmap后的图片信息
img : width = 564.0, height = 564.0
bitmap : width = 564.0, height = 564.0, allocationByteCount = 0.0
mat : width = 564.0, height = 564.0

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

比如获取某个点的颜色

images.pixel(img, 100, 200)

代码报错

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

img不能正常使用了,

那么此时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 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

颜色正常获取, 说明这个取色方法能用, 至于其他方法能不能用, 要看有没有用到mat,

如果用到了mat, mat已经回收, 自然就会报错.

猜你喜欢

转载自blog.csdn.net/weixin_39664733/article/details/121462296
今日推荐