android yuv数据处理_使用libyuv对YUV数据进行缩放,旋转,镜像,裁剪等操作

本文介绍了如何利用Google的libyuv库在Android上高效处理YUV数据,包括缩放、旋转、镜像和裁剪操作。通过CMake在Android Studio中编译并使用libyuv,实现对Camera捕获的YUV帧的快速处理,以满足直播推流等场景的需求。
摘要由CSDN通过智能技术生成

1.背景

在Android做过自定义Camera的朋友应该都知道,我们可以通过public void onPreviewFrame(byte[] data, Camera camera)回调中获取摄像头采集到的每一帧的数据,但是这个byte[] data的数据格式YUV的,并不能直接给我们进行使用,那么该通过什么样的方法对这个YUV数据进行处理呢?

2.YUV数据格式介绍

首先我们来了解什么是YUV数据,当然这方面的文章有很多,在这里我就不详细的介绍了,大家可以看下这篇文章 : 图文详解YUV420数据格式

,在这里我们主要用到的是YUV数据格式是NV21(yuv420sp)和I420(yuv420p),它们都是 4:2:0的格式,唯一的区别就是它们的YUV数据排列不一样,NV21的排列是YYYYYYYY VUVU =>YUV420SP,而I420的排列是YYYYYYYY UU VV =>YUV420P。

其实我们知道的NV21和I420的数据格式和数据的排列,我们就可以根据排列方式对其进行一些操作,比如在之前的文章分享几个Android摄像头采集的YUV数据旋转与镜像翻转的方法介绍的旋转镜像的操作。但是它的效率并不是很高,如果只是简单的操作单一的YUV数据,那么倒没有太大影响。但是如果要运用于直播推流的话,要保证推流视频的帧率,那么对YUV数据处理的耗时就相当的重要。

2.Libyuv库的介绍

其实对于YUV数据的处理,Google已经开源了一个叫做libyuv的库专门用于YUV数据的处理。

2.1 什么是libyuv

libyuv是Google开源的实现各种YUV与RGB之间相互转换、旋转、缩放的库。它是跨平台的,可在Windows、Linux、Mac、Android等操作系统,x86、x64、arm架构上进行编译运行,支持SSE、AVX、NEON等SIMD指令加速。

2.2 Android上如何使用Libyuv

libyuv并不能直接为Android开发直接进行使用,需要对它进行编译的操作。在这里介绍的是使用Android Studio的Cmake的方式进行libyuv的编译操作,首先从官方网站Libyuv上下载libyuv库,下载的目录结构如下

libyuv.png

如果无法下载的话,也可以从我文章最后的demo中去进行拷贝。新键Android项目,并且创建的时候勾选项include C++ Support,也就是改android项目支持C,C++的编译,如果对于Android Stuido如何支持C,C++编译不清楚的,请自行百度谷歌,这里就不多细说。项目创建之后将下载的libyuv库直接拷贝到src/main/cpp目录下

libyuv.png

修改CMakeLists.txt文件,并在src/main/cpp下创建YuvJni.cpp文件,CMakeLists.txt修改如下

cmake_minimum_required(VERSION 3.4.1)

include_directories(src/main/cpp/libyuv/include)

add_subdirectory(src/main/cpp/libyuv ./build)

aux_source_directory(src/main/cpp SRC_FILE)

add_library(yuvutil SHARED ${SRC_FILE})

find_library(log-lib log)

target_link_libraries(yuvutil ${log-lib} yuv)

创建文件YuvUtil.java,在这里我添加了三个方法进行yuv数据的操作

public class YuvUtil {

static {

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android中,使用libyuv库对视频数据YUV格式)进行裁剪操作,首先要确保已包含libyuv库,并将其添加到项目中。libyuv是一个高效的跨平台库,用于处理各种图像格式,包括YUV。 假设你有一个2560x1440分辨率的YUV帧,想要将其裁剪为四个1280x720的部分,你可以按照以下步骤操作: 1. **加载和解析YUV数据**: 首先,你需要从原始YUV缓冲区中读取数据,并创建一个`libyuv::SubsampledImage`对象来表示原始图像,这样可以方便地进行后续的操作。 2. **确定裁剪区域**: 定义四个裁剪区域,每个区域都是1280x720大小,坐标分别为(0,0)、(1280,0)、(0,720)和(1280,720)。这些坐标应根据你的应用场景进行调整。 3. **创建裁剪后的子图像**: 对于每一个裁剪区域,调用`libyuv::PlanarYUVSource`或`libyuv::I420Buffer`方法,传入对应部分的YUV数据,然后使用`libyuv::CopyArea`函数复制源数据到新分配的目标缓冲区中,生成新的1280x720 YUV图像。 4. **释放原始数据**: 在完成所有裁剪后,记得释放原始的大尺寸YUV数据,以节省内存。 5. **存储裁剪后的图像**: 最后,保存裁剪后的子图像到各自独立的缓冲区或文件中。 下面是伪代码示例: ```cpp // 假设yuv_data是原始YUV数据yuv_width和yuv_height是原始尺寸 SubsampledImage src_image(yuv_data, yuv_width, yuv_height, ...); // 创建四个裁剪区域 int crop = { {0, 0}, {1280, 0}, {0, 720}, {1280, 720} }; int output_count = sizeof(crop) / sizeof(crop[0]); for (int i = 0; i < output_count; ++i) { int x = crop[i]; int y = crop[i]; int width = 1280; int height = 720; // 创建新图像 PlanarYUVSource dst_subimage(width, height); // 裁剪并复制数据 libyuv::Status status = libyuv::CopyArea(src_image, dst_subimage, x, y, width, height); if (status != libyuv::kSuccess) { // 处理错误 } // 存储裁剪后的子图像 std::vector<uint8_t> cropped_data = dst_subimage.data(); // 写入文件或进一步处理 } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值