android 相机预览编译 libyuv 处理 YUV 数据

下载源码(需翻墙),Android Studio 新建一个 NDK 项目,源码拷贝到 cpp 目录下。

include 下面是头文件, source 下面是源码,其它文件基本用不到不用管。CMakeLists.txt 是 cmake 编译脚本, 现在android ndk 默认都是用 cmake 编译。

// 格式转换(NV21、NV12、I420等格式互转)
libyuv\include\libyuv\convert.h
libyuv\include\libyuv\convert_from.h
// 图像处理(镜像、旋转、缩放、裁剪)
libyuv\include\libyuv\planar_functions.h
libyuv\include\libyuv\rotate.h
libyuv\include\libyuv\scale.h

 下面编写我们自己的 CMakeLists , libyuv 作为一个子项目单独编译,按下面修改


cmake_minimum_required(VERSION 3.4.1)

include_directories(libyuv/include) #add


add_subdirectory(libyuv ./build) #add



add_library( # Sets the name of the library.
             native-lib

             # Sets the library as a shared library.
             SHARED

             # Provides a relative path to your source file(s).
             native-lib.cpp )



find_library( # Sets the name of the path variable.
              log-lib

              # Specifies the name of the NDK library that
              # you want CMake to locate.
              log )



target_link_libraries( # Specifies the target library.
                       native-lib

                       # Links the target library to the log library
                       # included in the NDK.
                       ${log-lib}
                       yuv)  #add

这个时候点击Make Project,应该就可以得到.so文件了。

 

YuvJni.cpp 是JNI源码,包装一下 libyuv 的代码。需要对各种 YUV 格式比较熟悉,否则也包装不出来。

#include <jni.h>
#include "libyuv.h"

/**
 * NV21 -> I420
 */
extern "C"
JNIEXPORT void JNICALL
Java_com_libyuv_util_YuvUtil_NV21ToI420(JNIEnv *env, jclass clazz, jbyteArray src_nv21_array,
jint width, jint height, jbyteArray dst_i420_array) {
jbyte *src_nv21_data = env->GetByteArrayElements(src_nv21_array, JNI_FALSE);
jbyte *dst_i420_data = env->GetByteArrayElements(dst_i420_array, JNI_FALSE);

jint src_y_size = width * height;
jint src_u_size = (width >> 1) * (height >> 1);

jbyte *src_nv21_y_data = src_nv21_data;
jbyte *src_nv21_vu_data = src_nv21_data + src_y_size;

jbyte *dst_i420_y_data = dst_i420_data;
jbyte *dst_i420_u_data = dst_i420_data + src_y_size;
jbyte *dst_i420_v_data = dst_i420_data + src_y_size + src_u_size;

libyuv::NV21ToI420((const uint8_t *) src_nv21_y_data, width,
(const uint8_t *) src_nv21_vu_data, width,
(uint8_t *) dst_i420_y_data, width,
(uint8_t *) dst_i420_u_data, width >> 1,
(uint8_t *) dst_i420_v_data, width >> 1,
width, height);

env->ReleaseByteArrayElements(src_nv21_array, src_nv21_data, 0);
env->ReleaseByteArrayElements(dst_i420_array, dst_i420_data, 0);
}

YUVUtil.java 定义了 native 方法

package com.example.YuvLib;

public class YuvUtil {

    static {
        System.loadLibrary("yuvutil");
    }

    /**
     * NV21 -> I420
     *
     * @param src_nv21_data 原始NV21数据
     * @param width         原始宽
     * @param height        原始高
     * @param dst_i420_data 目前I420数据
     */
    public static native void NV21ToI420(byte[] src_nv21_data, int width, int height, byte[] dst_i420_data);

    /**
     * I420 -> NV21
     *
     * @param src_i420_data
     * @param width
     * @param height
     * @param dst_nv21_data
     */
    public static native void I420ToNV21(byte[] src_i420_data, int width, int height, byte[] dst_nv21_data);
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值