autojs图片的数据表现形式, 一共有三种
三种图片数据格式互相转换
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
从日志可以看出, 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<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
颜色正常获取, 说明这个取色方法能用, 至于其他方法能不能用, 要看有没有用到mat,
如果用到了mat, mat已经回收, 自然就会报错.
总结
图片回收一律用img, 只要img回收了, 那么bitmap和mat也就回收了;
除非你用了bitmap.copy或者mat.clone, 来复制图片数据,
此时你就要自己去回收你复制的图片数据了
chatGPT1.1.8更新了, 加了一个换头功能, 比如传说中的 狗头蛇
先选择一张蛇的图片网址:yii666.com
涂抹蛇头
AI 就会生成 狗头蛇
文章来源地址:https://www.yii666.com/blog/313800.html
这里面使用的就是canvas功能
<canvas id="imageEditCanvas" />
canvasView.on("draw", (canvas) => {})
技巧, 在编写draw事件的时候, 可能会用到canvasView的宽高, 我们可以延迟一下再添加draw事件, 也就是先让界面生成完毕, 再执行我们的操作
const { delay } = require("lang"); delay(1).then(() => { let canvasWidth = canvasView.getWidth(); let canvasHeight = canvasView.getHeight(); canvasView.on("draw", (canvas) => {}) })
画哪张图片是由用户决定的, 因此要让用户选择图片, 增加一个按钮, 让用户选择图片
let intent = new Intent(); intent.setType("image/*"); intent.setAction(Intent.ACTION_GET_CONTENT); context.startActivityForResult(Intent.createChooser(intent, "选择图片"), requestCode);
用户选好图片以后, 我们绘制图片文章来源地址https://www.yii666.com/blog/313800.html文章地址https://www.yii666.com/blog/313800.html
canvas.drawBitmap(maskBitmap512, matrix, null);
这里使用了matrix让图片居中, 在之前的教程已经讲过了
autojs怎么把长宽不定的图片, 放到正方形图片的中间
这个随意, 不管画点, 画圆, 画Path, 都可以, 我选择的是Path
canvas.drawPath(path, paint);
res = await axios.post(url, form, { headers: { "Content-Type": "multipart/form-data", Authorization: key, }, });
AI 返回的是url, 直接给imgView设置src即可
<img id='content' w='*' h='*' scaleType='fitCenter'></img> this.content.attr("src", url);