牙叔教程 简单易懂
效果展示
斯嘉丽约翰逊
美国国旗
图片融合
环境
Android版本: 11
Autojs版本: 9.0.8
思路
- 要做到透明渐变, 那么图片就需要png格式
- 图片处理一般都会用opencv
- 图片的数据格式一般是mat, 在mat中修改透明度对应的通道的值
- 图片融合使用canvas直接画
你将学到以下知识点
- 获取图片类型
- 转换图片类型
- mat转图片
- mat转bitmap
- canvas画图
- 图片归一化, 即让两幅图片大小相同
- 打印mat属性
- 修改图片透明通道的值
- byte数组转换成16进制字符串
代码讲解
1. 两张图片的路径
let imgPath = files.path("./美国国旗.png"); let imgPath2 = files.path("./斯嘉丽约翰逊.jpg");
2. 初始化opencv
runtime.images.initOpenCvIfNeeded();
3. 导入类
importClass(org.opencv.core.MatOfByte); importClass(org.opencv.core.Scalar); importClass(org.opencv.core.Point); importClass(org.opencv.core.CvType); importClass(java.util.List); importClass(java.util.ArrayList); importClass(java.util.LinkedList); importClass(org.opencv.imgproc.Imgproc); importClass(org.opencv.imgcodecs.Imgcodecs); importClass(org.opencv.core.Core); importClass(org.opencv.core.Mat); importClass(org.opencv.core.MatOfDMatch); importClass(org.opencv.core.MatOfKeyPoint); importClass(org.opencv.core.MatOfRect); importClass(org.opencv.core.Size); importClass(org.opencv.features2d.DescriptorMatcher); importClass(org.opencv.features2d.Features2d); importClass(org.opencv.core.MatOfPoint2f); importClass(org.opencv.android.Utils); importClass(android.graphics.Bitmap); importClass(java.lang.StringBuilder); importClass(java.io.FileInputStream); importClass(java.io.File);
4. 获取图片类型
function getPicType(fis) { //读取文件的前几个字节来判断图片格式 // let b = new byte[4](); let b = util.java.array("byte", 4); try { fis.read(b, 0, b.length); let type = bytesToHexString(b).toUpperCase(); type = new java.lang.String(type); if (type.contains("FFD8FF")) { return TYPE_JPG; } else if (type.contains("89504E47")) { return TYPE_PNG; } else if (type.contains("47494638")) { return TYPE_GIF; } else if (type.contains("424D")) { return TYPE_BMP; } else { return TYPE_UNKNOWN; } } catch (e) { log(e); } finally { if (fis != null) { try { fis.close(); } catch (e) { log(e); } } } return null; }
5. 归一化图片, 令其宽高一致, 虽然这里处理了, 但最好提前处理图片, 以免变形
function normalize(img, img2) { let imgWidth = img.getWidth(); // 200 let imgHeight = img.getHeight(); // 200 return images.resize(img2, [imgWidth, imgHeight]); }
6. 修改png图片的透明通道, 这里令背景显示的宽度为三分之二且透明渐变
function transparentGradient(mat) { let width = mat.width(); let height = mat.height(); let unit = 256 / ((width / 3) * 2); let wLimit = (width / 3) * 2; for (var i = 0; i < height; i++) { for (var j = 0; j < width; j++) { let item = mat.get(i, j); if (j > wLimit) { item[3] = 0; } else { item[3] = 255 - unit * j; } mat.put(i, j, item); } } return mat; }
7. 色彩空间转换, 因为aj显示的是rgb颜色才正常, bgr显示颜色就不正常了
Imgproc.cvtColor(mat, mat, Imgproc.COLOR_BGRA2RGBA);
8. 使用canvas将两幅图片融合成一幅, 也可以直接计算图片融合后的正确颜色, 然后创建新mat, 图片合并不止一种方法
function merge(mat, mat3) { let tempFilePath = saveMat(mat); let w = mat.width(); let h = mat.height(); let bitmap3 = mat2bitmap(mat3); let bitmap = android.graphics.Bitmap.createBitmap(w, h, android.graphics.Bitmap.Config.ARGB_8888); var tempImg = images.read(tempFilePath); bitmap2 = tempImg.getBitmap(); let canvas = new Canvas(bitmap); let paint = new Paint(); canvas.drawBitmap(bitmap3, 0, 0, paint); canvas.drawBitmap(bitmap2, 0, 0, paint); var image = canvas.toImage(); tempImg.recycle(); return image; }
9. 查看融合后的图片
let tempDir = files.join("/sdcard/Pictures/img"); let tempFilePath2 = files.join(tempDir, files.getName(oImgPath2)); files.createWithDirs(tempFilePath2); images.save(img4, tempFilePath2); app.viewFile(tempFilePath2);
10. 释放资源
img.recycle(); img2.recycle(); img3.recycle(); img4.recycle(); mat.release(); mat3.release();
参考
名人名言
思路是最重要的, 其他的百度, bing, stackoverflow, 安卓文档, autojs文档, 最后才是群里问问
--- 牙叔教程
声明
部分内容来自网络
本教程仅用于学习, 禁止用于其他用途