Android 使用libyuv-格式转换

  1. 添加JNI方法

    class YuvUtil {
        companion object {
            // Used to load the 'libyuv' library on application startup.
            init {
                System.loadLibrary("libyuv")
            }
        }
        external fun yuv2rgb(y: ByteArray, u:ByteArray,v:ByteArray,width: Int, height: Int): ByteArray
    }
    
  2. C++实现调用libyuv的I420ToRGB24方法

    #include <jni.h>
    #include <string>
    #include "logcat.h"
    #include "libyuv.h"
    #include "libyuv/convert_argb.h"
    
    extern "C"
    JNIEXPORT jbyteArray JNICALL
    Java_com_test_libyuv_YuvUtil_yuv2rgb(JNIEnv *env, jobject thiz, jbyteArray y, jbyteArray u, jbyteArray v,
                                                    jint width, jint height) {
        // 获取源数据
        jsize yLength = env->GetArrayLength(y);
        jsize uLength = env->GetArrayLength(u);
        jsize vLength = env->GetArrayLength(v);
        LogUtil::info("yuv2rgb", ("yuv length: " + std::to_string(yLength) + " " + std::to_string(uLength) + " " + std::to_string(vLength)).c_str());
        jbyte* yData = env->GetByteArrayElements(y, nullptr);
        jbyte* uData = env->GetByteArrayElements(u, nullptr);
        jbyte* vData = env->GetByteArrayElements(v, nullptr);
    
        // 创建输出数组
        jbyteArray rgbaArray = env->NewByteArray(width * height * 3);
        jbyte* rgbaData = env->GetByteArrayElements(rgbaArray, nullptr);
    
        // 调用 I420ToRGBA
        libyuv::I420ToRGB24(reinterpret_cast<const uint8_t*>(yData), width,
                   reinterpret_cast<const uint8_t*>(uData), width/2,
                   reinterpret_cast<const uint8_t*>(vData), width/2,
                   reinterpret_cast<uint8_t*>(rgbaData), width * 3,
                   width, height);
    
        // 释放资源
        env->ReleaseByteArrayElements(y, yData, JNI_ABORT);
        env->ReleaseByteArrayElements(u, uData, JNI_ABORT);
        env->ReleaseByteArrayElements(v, vData, JNI_ABORT);
        env->ReleaseByteArrayElements(rgbaArray, rgbaData, 0); // 0表示将修改后的数据写回
    
        return rgbaArray;
    }
    
  3. 测试代码

      //读取一张YUV420的图片
      var image = readFileToByteArray((path?.path ?: "") +"/image")
      var yuvUtil = YuvUtil()
      image?.let {
          Log.i(TAG,"image = ${it.size}")
          var y = ByteArray(1920*1080)
          var u = ByteArray(1920*1080/4)
          var v = ByteArray(1920*1080/4)
          System.arraycopy(it,0,y,0,y.size)
          System.arraycopy(it,y.size,u,0,u.size)
          System.arraycopy(it,y.size+u.size,v,0,v.size)
          //转换成RGB图片
          var outImage = yuvUtil.yuv2rgb(y,u,v,1920,1080)
      }
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值