上一篇http://blog.csdn.net/xiaibiancheng/article/details/72853009讲解了在Android studio 下面如何编译开源libyuv库,这一篇主要讲解如何使用ARGBToI420和ConvertToARGB这两个接口。

ARGBToI420接口主要用于将argb数据转换为一帧yuv I420 数据,接口定义如下:

 

// Convert ARGB to I420.
LIBYUV_API int ARGBToI420(const uint8* src_argb, int src_stride_argb,
               uint8* dst_y, int dst_stride_y,
               uint8* dst_u, int dst_stride_u,
               uint8* dst_v, int dst_stride_v,
               int width, int height)


各个参数说明:

 

src_argb:用于待转换的argb数据。

src_stride_argb:argb数据每一行的大小,如果是argb_8888格式的话这个值为wX4,argb4444的话值为wX2。

dst_y:用于保存y分量数据。

dst_stride_y:值为w*h。

dst_u:用于保存u分量数据。

dst_stride_u:值为(w+1)/2。

dst_v:用于保存分量数据。

dst_stride_v:值为(w+1)/2。

width:位图宽度。

height:位图高度。

上面的w和h分别对应width和height。

 

ConvertToARGB 接口用于将一帧yuv数据转换为一张位图数据,接口定义如下 :

 

LIBYUV_API int ConvertToARGB(const uint8* sample, size_t sample_size,
                  uint8* crop_argb, int argb_stride,
                  int crop_x, int crop_y,
                  int src_width, int src_height,
                  int crop_width, int crop_height,
                  enum RotationMode rotation,
                  uint32 fourcc)


参数说明如下:

 

sample:yuv输入数据。

sample_size:输入数据大小,值为w*h*3/2。

crop_argb:用于保存转换后的argb数据。

argb_stride:职位w*4

crop_x:裁剪的起始x位置。

crop_y:裁剪的起始y位置。

src_width:yuv数据帧的宽度

src_height:yuv数据帧的高度

crop_width:裁剪后位图的宽度

crop_height:裁剪后位图的高度

rotation:旋转角度。

fourcc:yuv数据输入格式。

测试代码:

 

Bitmap image = null;
        AssetManager am = getResources().getAssets();
        try{
            //读取assert 的文图
            InputStream is = am.open("test.jpg");
            image = BitmapFactory.decodeStream(is);

            //将位图资源转为二进制数据,数据大小为w*h*4
            int bytes = image.getByteCount();
            ByteBuffer buf = ByteBuffer.allocate(bytes);
            image.copyPixelsToBuffer(buf);
            byte[] byteArray = buf.array();

            byte[]  ybuffer=new byte[w*h];//用于保存y分量数据
            byte[]  ubuffer=new byte[w*h*1/4];//用于保存u分量数据
            byte[]  vbuffer=new byte[w*h*1/4];//用于保存v分量数据
            //将位图数据argb转换为yuv I420 转换后的数据分别保存在 ybuffer、ubuffer和vbuffer里面
            Test.argbtoi420(byteArray,w*4,ybuffer,w,ubuffer,(w+1)/2,vbuffer,(w+1)/2,w,h);

            //将上面的yuv数据保存到一个数组里面组成一帧yuv I420 数据 分辨率为w*h
            byte[] frameBuffer=new byte[w*h*3/2];
            System.arraycopy(ybuffer,0,frameBuffer,0,w*h);
            System.arraycopy(ubuffer,0,frameBuffer,w*h,w*h*1/4);
            System.arraycopy(vbuffer,0,frameBuffer,w*h*5/4,w*h*1/4);

            //用于保存将yuv数据转成argb数据
            byte[] rgbbuffer=new byte[w*h*4];
            //将上面的yuv I420 还原成argb数据
            Test.convertToArgb(frameBuffer,w*h*3/2,rgbbuffer,w*4,0,0,w,h,w,h,0,0);

            //还原成位图
            Bitmap stitchBmp = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
            stitchBmp.copyPixelsFromBuffer(ByteBuffer.wrap(rgbbuffer));

            //显示还原的位图
            imgShow.setImageBitmap(stitchBmp);


        }catch (IOException e){

        }

 

jni代码:

 

//
// Created by Administrator on 2017/6/4.
//
#include "include/libyuv.h"
#include <jni.h>

void Java_com_example_libyuv_Test_argbtoi420(JNIEnv* env, jobject thiz,
                                             jbyteArray src_argb, int src_stride_argb,
                                             jbyteArray dst_y, int dst_stride_y,
                                             jbyteArray dst_u, int dst_stride_u,
                                             jbyteArray dst_v, int dst_stride_v,
                                             int width, int height){
    uint8_t* rgbBuffer = (uint8_t*) (*env)->GetByteArrayElements(env, src_argb, 0);
    uint8_t* yBuffer=(uint8_t*) (*env)->GetByteArrayElements(env, dst_y, 0);
    uint8_t* uBuffer=(uint8_t*) (*env)->GetByteArrayElements(env, dst_u, 0);
    uint8_t* vBuffer=(uint8_t*) (*env)->GetByteArrayElements(env, dst_v, 0);

    ARGBToI420(rgbBuffer,src_stride_argb,yBuffer,dst_stride_y,uBuffer,dst_stride_u,vBuffer,dst_stride_v,width,height);

    (*env)->ReleaseByteArrayElements(env, src_argb, rgbBuffer, 0);
    (*env)->ReleaseByteArrayElements(env, dst_y, yBuffer, 0);
    (*env)->ReleaseByteArrayElements(env, dst_u, uBuffer, 0);
    (*env)->ReleaseByteArrayElements(env, dst_v, vBuffer, 0);
}

void Java_com_example_libyuv_Test_convertToI420(JNIEnv* env, jobject thiz,
                                                jbyteArray src_frame, int src_size,
                                                jbyteArray dst_y, int dst_stride_y,
                                                jbyteArray dst_u, int dst_stride_u,
                                                jbyteArray dst_v, int dst_stride_v,
                                                int crop_x, int crop_y,
                                                int src_width, int src_height,
                                                int crop_width, int crop_height,
                                                int rotation,
                                                int format){
    uint8_t* yuvFrame = (uint8_t*) (*env)->GetByteArrayElements(env, src_frame, 0);
    uint8_t* yBuffer=(uint8_t*) (*env)->GetByteArrayElements(env, dst_y, 0);
    uint8_t* uBuffer=(uint8_t*) (*env)->GetByteArrayElements(env, dst_u, 0);
    uint8_t* vBuffer=(uint8_t*) (*env)->GetByteArrayElements(env, dst_v, 0);

    ConvertToI420(yuvFrame,src_size,yBuffer,dst_stride_y,uBuffer,dst_stride_u,vBuffer,dst_stride_v,crop_x,crop_y,src_width,src_height,crop_width,crop_height,kRotate0,FOURCC_IYUV);

    (*env)->ReleaseByteArrayElements(env, src_frame, yuvFrame, 0);
    (*env)->ReleaseByteArrayElements(env, dst_y, yBuffer, 0);
    (*env)->ReleaseByteArrayElements(env, dst_u, uBuffer, 0);
    (*env)->ReleaseByteArrayElements(env, dst_v, vBuffer, 0);

}

void Java_com_example_libyuv_Test_convertToArgb(JNIEnv* env, jobject thiz,
                                                jbyteArray src_frame, int src_size,
                                                jbyteArray dst_argb, int dst_stride_argb,
                                                int crop_x, int crop_y,
                                                int src_width, int src_height,
                                                int crop_width, int crop_height,
                                                int rotation,
                                                int format){

    uint8_t* yuvFrame = (uint8_t*) (*env)->GetByteArrayElements(env, src_frame, 0);
    uint8_t* rgbBuffer= (uint8_t*) (*env)->GetByteArrayElements(env, dst_argb, 0);

    ConvertToARGB(yuvFrame,src_size,rgbBuffer,dst_stride_argb,crop_x,crop_y,src_width,src_height,crop_width,crop_height,kRotate0,FOURCC_IYUV);
    (*env)->ReleaseByteArrayElements(env, src_frame, yuvFrame, 0);
    (*env)->ReleaseByteArrayElements(env, dst_argb, rgbBuffer, 0);
}

 

 

 

demo地址:

 

 

 

https://github.com/XIAIBIANCHENG/android-libyuv

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐