• Stars
    star
    113
  • Rank 310,115 (Top 7 %)
  • Language
    C++
  • License
    MIT License
  • Created about 5 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

基于 libyuv 封装各种图像格式转换,用于处理摄像头yuv图像数据

LQRLibyuv

《Android 音视频——Libyuv 使用实战》。该库对 libyuv 进行封装,用于处理摄像头 yuv 图像数据。

该库已发布 jitpack ,最新版本号为 JitPack,可直接通过 gradle 依赖使用:

implementation 'com.github.GitLqr:LQRLibyuv:1.0.0'

注:因为 jitpack 只支持使用高版本 NDK 编译(22.1.7171670),无法编译出已经淘汰的 armeabi 与 mips 架构的 so 库,所以如果有需要,请 clone 该仓库,改用低版本的 NDK 自己本地编译吧,gradle 里都写好了。

一、编译

Rebuild Project后,提取 so 库与 YuvUtil.java,放到自己的工程项目中,如下图所示:

二、使用

1、使用 YuvUtil 完全手动处理 YUV 图像数据

/**
 * 使用YuvUtil完全手动处理YUV图像数据,要求理解byte[]的创建长度:
 * yuvNV21ToI420():nv21转i420
 * yuvMirrorI420():镜像
 * yuvScaleI420():缩放
 * yuvCropI420():裁剪
 * yuvRotateI420():旋转
 * yuvI420ToNV21():i420转nv21
 *
 * @param data 摄像头获取到的nv21数据
 */
private void yuvProcessAndDraw1(byte[] data) {
    int width = WIDTH;
    int height = HEIGHT;

    // nv21 --> i420
    byte[] nv21Data = data;
    byte[] i420Data = new byte[width * height * 3 / 2];
    YuvUtil.yuvNV21ToI420(nv21Data, width, height, i420Data);

    // 镜像
    byte[] i420MirrorData = new byte[width * height * 3 / 2];
    YuvUtil.yuvMirrorI420(i420Data, width, height, i420MirrorData);
    i420Data = i420MirrorData;

    // 缩放
    byte[] i420ScaleData = new byte[width * height * 3 / 2];
    int scaleWidth = 320;
    int scaleHeight = 240;
    YuvUtil.yuvScaleI420(i420Data, width, height, i420ScaleData, scaleWidth, scaleHeight, 0);
    i420Data = i420ScaleData;
    width = scaleWidth;
    height = scaleHeight;

    // 裁剪
    byte[] i420CropData = new byte[width * height * 3 / 2];
    int cropWidth = 240;
    int cropHeight = 240;
    YuvUtil.yuvCropI420(i420Data, width, height, i420CropData, cropWidth, cropHeight, 0, 0);
    i420Data = i420CropData;
    width = cropWidth;
    height = cropHeight;

    // 旋转
    byte[] i420RotateData = new byte[width * height * 3 / 2];
    int degree = 90;
    YuvUtil.yuvRotateI420(i420Data, width, height, i420RotateData, degree);
    i420Data = i420RotateData;
    if (degree == 90 || degree == 270) {
        int temp = width;
        width = height;
        height = temp;
    }

    // i420 --> nv21
    YuvUtil.yuvI420ToNV21(i420Data, width, height, nv21Data);

    // 绘制图像
    drawSurfaceView(data, width, height);
}

2、使用 YuvUtil 半自动处理 YUV 图像数据

/**
 * 使用YuvUtil半自动处理YUV图像数据:
 * yuvCompress():nv21转i420、镜像、缩放、旋转
 * yuvCropI420():裁剪
 * yuvI420ToNV21():i420转nv21
 *
 * @param data 摄像头获取到的nv21数据
 */
private void yuvProcessAndDraw2(byte[] data) {
    int width = WIDTH;
    int height = HEIGHT;
    int dstWidth = 320;
    int dstHeight = 240;

    // nv21 --> i420 --> 镜像 --> 缩放 --> 旋转
    byte[] nv21Data = data;
    byte[] i420Data = new byte[dstWidth * dstHeight * 3 / 2];
    int degree = 90;
    YuvUtil.yuvCompress(nv21Data, width, height, i420Data, dstWidth, dstHeight, 0, 90, true);
    // 旋转过后,需要手动校正宽高
    if (degree == 90 || degree == 270) {
        width = dstHeight;
        height = dstWidth;
    } else {
        width = dstWidth;
        height = dstHeight;
    }

    // 裁剪
    byte[] i420CropData = new byte[width * height * 3 / 2];
    int cropWidth = 240;
    int cropHeight = 240;
    YuvUtil.yuvCropI420(i420Data, width, height, i420CropData, cropWidth, cropHeight, 0, 0);
    i420Data = i420CropData;
    width = cropWidth;
    height = cropHeight;

    // i420 --> nv21
    YuvUtil.yuvI420ToNV21(i420Data, width, height, nv21Data);

    // 绘制图像
    drawSurfaceView(data, width, height);
}

3、Yuv 转 Bitmap

/**
 * 使用SurfaceView绘制Bitmap图像
 * @param data nv21数据
 * @param width 图像宽
 * @param height 图像高
 */
private void drawSurfaceView(byte[] data, int width, int height) {
    YuvImage yuvImage = new YuvImage(data, ImageFormat.NV21, width, height, null);
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    yuvImage.compressToJpeg(new Rect(0, 0, width, height), 100, out);
    byte[] bytes = out.toByteArray();
    Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
    mCameraViewR.drawBitmap(bitmap);
}

三、声明

文章:《Android 音视频——Libyuv 使用实战》
感谢:该库基于LibyuvDemo,修复了 bug,并添加了一些新 api,感谢原作者的开源。

四、更新

2019-11-06 扩展 yuv 图像转换 API:

  • YuvUtil#yuvNV21ToI420AndRotate(byte[] nv21Src, int width, int height, byte[] i420Dst, int degree);
  • YuvUtil#yuvI420ToRGB24(byte[] i420Src, int width, int height, byte[] rgb24Dst);
  • YuvUtil#yuvI420ToARGB(byte[] i420Src, int width, int height, int dst_stride, byte[] argbDst);
  • YuvUtil#yuvI420ToRGBAMac(byte[] i420Src, int width, int height, int dst_stride, byte[] rgbaMacDst);
  • YuvUtil#yuvI420ToARGB4444(byte[] i420Src, int width, int height, int dst_stride, byte[] argb4444Dst);
  • YuvUtil#yuvI420ToRGB565(byte[] i420Src, int width, int height, byte[] rgb565Dst);
  • YuvUtil#yuvI420ToRGB565Android(byte[] i420Src, int width, int height, byte[] rgb565Dst);
  • YuvUtil#yuvI420ToARGB1555(byte[] i420Src, int width, int height, int dst_stride, byte[] argb1555Dst);
  • YuvUtil#yuvI420ToYUY2(byte[] i420Src, int width, int height, int dst_stride, byte[] yuy2Dst);
  • YuvUtil#yuvI420ToUYVY(byte[] i420Src, int width, int height, int dst_stride, byte[] uyvyDst);
  • YuvUtil#yuvI420ToYV12(byte[] i420Src, int width, int height, int dst_stride, byte[] yv12Dst);
  • YuvUtil#yuvYV12ToI420(byte[] yv12Src, int width, int height, byte[] i420Dst);
  • YuvUtil#yuvNV12ToI420(byte[] nv12Src, int width, int height, byte[] i420Dst);
  • YuvUtil#yuvI420ToNv12(byte[] i420Src, int width, int height, byte[] nv12Dst);
  • YuvUtil#yuvNV12ToI420AndRotate(byte[] nv12Src, int width, int height, byte[] i420Dst, int degree);
  • YuvUtil#yuvNV12ToRGB565(byte[] nv12Src, int width, int height, byte[] rgb565Dst);
  • YuvUtil#yuvI420ToRGBAIPhone(byte[] i420Src, int width, int height, int dst_stride, byte[] rgbaDst);
  • YuvUtil#yuvI420Copy(byte[] i420Src, int width, int height, int dst_stride, byte[] i420Dst);
  • YuvUtil#yuvUYVYToI420(byte[] uyvySrc, int width, int height, byte[] i420Dst);
  • YuvUtil#yuvYUY2ToI420(byte[] yuy2Src, int width, int height, byte[] i420Dst);
  • YuvUtil#yuvRGB24ToARGB(byte[] rgb24Src, int width, int height, int dst_stride, byte[] argbDst);
  • YuvUtil#yuvRGB24ToI420(byte[] rgb24Src, int width, int height, byte[] i420Dst);
  • YuvUtil#yuvI420ToARGBMac(byte[] i420Src, int width, int height, int dst_stride, byte[] argbMacDst);
  • YuvUtil#yuvARGBMacToI420(byte[] argbMacSrc, int width, int height, byte[] i420Dst);
  • YuvUtil#yuvMirrorI420LeftRight(byte[] i420Src, int width, int height, byte[] i420Dst);
  • YuvUtil#yuvMirrorI420UpDown(byte[] i420Src, int width, int height, byte[] i420Dst);

More Repositories

1

LQRWeChat

本项目仿最新版微信6.5.7(除图片选择器外),基于融云SDK,使用目前较火的 Rxjava+Retrofit+MVP+Glide 技术开发。相比上个版本,加入发送位置消息,红包消息等功能。
Java
3,370
star
2

LQREmojiLibrary

一个超级牛逼的表情库,可使用表情及贴图功能,方便好用,抽离图片加载接口,图片加载工具可让开发者自己选择。
Java
484
star
3

LQRAudioRecord

集成录音与播音功能,使用简单方便
Java
382
star
4

MaterialDesignDemo

Material Design 兼容性控件学习
Java
226
star
5

HotFixDemo

热修复Demo(附文章讲解)
Java
162
star
6

TopsalesSellControlTableDemo

仿房产销冠APP的销控表界面
Java
147
star
7

LQRImagePicker

完全仿微信的图片选择,并且提供了多种图片加载接口,选择图片后可以旋转,可以裁剪成矩形或圆形,可以配置各种其他的参数
Java
139
star
8

LQRNineGridImageView

仿微信群头像九宫格控件
Java
132
star
9

LQRRecyclerViewLibrary

对RecyclerView的封装,让其使用更加简单,得心应手
Java
128
star
10

LQRBiliBlili

高仿bilibili安卓客户端
Java
116
star
11

LQRDropdownLayoutLibrary

下拉导航菜单,使用非常简单
Java
71
star
12

LQRAdapterLibrary

万能适配器(RecyclerView、ListView、GridView)
Java
57
star
13

LQRViedoRecordView

安卓视频录制控件,可以用来仿微信小视频
Java
57
star
14

LQRNativePicSelect

为使用系统原生选择图片需求做了一个工具类封装,并适配了Android 7.0
Java
44
star
15

RePluginX

🔥 Supports AndroidX and Android-Support
Java
43
star
16

LQROptionItemView

项目中常用选项条目布局控件
Java
21
star
17

AndroidAopDemo

Android面向切面编程Demo(AOP)
Java
20
star
18

AspectLogDemo

Spring Boot使用自定义注解+AOP处理日志
Java
16
star
19

LQRArticlePatch

解析下载今日头条视频及图片
Java
14
star
20

SimpleDbFrame

手撸一个简单的面向对象数据框架(工厂模式+泛型+注解+反射)
Java
13
star
21

LQRRecordProgress

仿微信小视频进度条
Java
8
star
22

DropdownLayoutDemo

下拉导航菜单,使用非常简单
Java
6
star
23

LiteARouter

精简版ARouter,与 RePluginX 更配哦~
Java
5
star
24

OpenGLDemo

Android中OpenGL编程Demo
Java
3
star
25

meiduo_project

django美多商城
HTML
3
star
26

UniappIseXfyun

Uniapp小程序版 科大讯飞语音评测Demo
TypeScript
3
star
27

LQROpenCV

基于OpenCV3.4.1,实现人脸识别,手部识别。
C++
3
star
28

IocDemo

使用注解打造自己的IOC框架
Java
2
star
29

vue-legacy-project

兼容低版本浏览器的vue工程示例
Vue
2
star
30

LQRCustomerView

自定义View练习
Java
2
star
31

OpenGLStudy

study opengl and camera
Java
1
star
32

pagehelper

Mybatis逆向工程分页助手fix
Java
1
star
33

www---api-6-17-

Python
1
star
34

LQRCameraDemo

Android相机使用Demo
Java
1
star
35

WeiXinEmotion

模仿微信表情
Java
1
star
36

game-tank

Kotlin坦克大战
Kotlin
1
star
37

LQRLibrtmp

基于librtmp搭建的RTMP推流器
C
1
star
38

uniapp-tensorflowjs-mp

uniapp 集成 tensorflowjs(微信小程序)
SCSS
1
star
39

vite-plugin-variant

vite-plugin-variant is a vite plugin for managing multi-channel differentiated source code
TypeScript
1
star