封装一个 JNI 方法来调用 libyuv 的 I420Scale 函数
-
创建 JNI 接口
external fun yuvScale(yuv: ByteArray, srcWidth: Int, srcHeight: Int,dstWith:Int,dstHeight:Int): ByteArray
-
编写一个 C++ 文件,使用 libyuv 的 I420Scale 方法
extern "C" JNIEXPORT jbyteArray JNICALL Java_com_libyuv_YuvUtil_yuvScale(JNIEnv *env, jobject thiz, jbyteArray inputYUV, jint src_width, jint src_height, jint dst_with, jint dst_height) { // 获取输入数据 jbyte* inputPtr = env->GetByteArrayElements(inputYUV, nullptr); if (inputPtr == nullptr) { return nullptr; // Out of memory } // 创建输出数据 int outputSize = dst_with * dst_height * 3 / 2; jbyteArray outputYUV = env->NewByteArray(outputSize); jbyte* outputPtr = env->GetByteArrayElements(outputYUV, nullptr); if (outputPtr == nullptr) { env->ReleaseByteArrayElements(inputYUV, inputPtr, JNI_ABORT); return nullptr; // Out of memory } // 进行 YUV420 缩放 const uint8_t* src_y = reinterpret_cast<const uint8_t*>(inputPtr); const uint8_t* src_u = src_y + src_width * src_height; const uint8_t* src_v = src_u + (src_width * src_height) / 4; libyuv::I420Scale(src_y, src_width, src_u, src_width / 2, src_v, src_width / 2, src_width, src_height, reinterpret_cast<uint8_t*>(outputPtr), dst_with, reinterpret_cast<uint8_t*>(outputPtr) + dst_with * dst_height, dst_with / 2, reinterpret_cast<uint8_t*>(outputPtr) + dst_with * dst_height + (dst_with * dst_height) / 4, dst_with / 2, dst_with, dst_height, libyuv::kFilterBilinear); // 释放输入数据 env->ReleaseByteArrayElements(inputYUV, inputPtr, JNI_ABORT); // 释放输出数据 env->ReleaseByteArrayElements(outputYUV, outputPtr, 0); return outputYUV; // 返回输出数据 }
-
在 Java 中调用 scaleI420 方法,传入原始 YUV 数据和目标宽高
var outImage = yuvUtil.yuvScale(it,1920,1080,960,540)