美文网首页
图像融合效果-透明渐变

图像融合效果-透明渐变

作者: 牙叔教程 | 来源:发表于2021-10-01 20:08 被阅读0次

    牙叔教程 简单易懂

    效果展示

    斯嘉丽约翰逊


    斯嘉丽约翰逊.jpg

    美国国旗


    美国国旗原图.png

    图片融合


    效果.jpg

    环境

    Android版本: 11

    Autojs版本: 9.0.8

    思路

    1. 要做到透明渐变, 那么图片就需要png格式
    2. 图片处理一般都会用opencv
    3. 图片的数据格式一般是mat, 在mat中修改透明度对应的通道的值
    4. 图片融合使用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();
    

    参考

    java代码判断图片文件格式, 不是根据文件后缀来判断。

    名人名言

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

    声明

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

    相关文章

      网友评论

          本文标题:图像融合效果-透明渐变

          本文链接:https://www.haomeiwen.com/subject/uebunltx.html