android使用libyuv

本文介绍了如何在Android项目中使用libyuv库进行RGB到YUV的转换以及YUV的旋转操作。通过gitlab镜像获取libyuv源码,集成到Android Studio工程,然后创建C++类实现转换方法。注意在转换NV21到I420并旋转时,直接调用某些函数会导致画面异常,需要采用组合调用的方式解决。此外,还提供了一个YUVConverter类,用于将camera预览数据转换为适合MediaCodec H264编码器的YUV格式。
摘要由CSDN通过智能技术生成

libyuv可以帮我们将rgb转换成yuv,也可以用来旋转yuv,转换成其他yuv格式
libyuv git地址是https://chromium.googlesource.com/libyuv/libyuv,由于众所周知的原因,无法直接访问,我们可以用gitlab来中转一下
首先创建一个project,选择Import project,点击Repo by URL,在url里填入这个网址,勾选Mirror repository,然后创建工程,等待同步完成就可以下载代码了

这个是我创建的一个镜像 https://gitlab.com/cc_linco/libyuv1.git

接下来创建AS工程,勾选C++支持,一路next就可以了
将libyuv源码解压到src/main/cpp目录下,修改一下libyuv/CMakeLists.txt,去掉一些编译生成的文件,也可以不改,按自己需要编辑,下面是我注释掉一些编译目标后的文件

# CMakeLists for libyuv
# Originally created for "roxlu build system" to compile libyuv on windows
# Run with -DTEST=ON to build unit tests

PROJECT ( YUV C CXX )   # "C" is required even for C++ projects
CMAKE_MINIMUM_REQUIRED( VERSION 2.8 )
OPTION( TEST "Built unit tests" OFF )

SET ( ly_base_dir   ${PROJECT_SOURCE_DIR} )
SET ( ly_src_dir    ${ly_base_dir}/source )
SET ( ly_inc_dir    ${ly_base_dir}/include )
SET ( ly_tst_dir    ${ly_base_dir}/unit_test )
SET ( ly_lib_name   yuv )
SET ( ly_lib_static ${ly_lib_name} )
SET ( ly_lib_shared ${ly_lib_name}_shared )

FILE ( GLOB_RECURSE ly_source_files ${ly_src_dir}/*.cc )
LIST ( SORT         ly_source_files )

FILE ( GLOB_RECURSE ly_unittest_sources ${ly_tst_dir}/*.cc )
LIST ( SORT         ly_unittest_sources )

INCLUDE_DIRECTORIES( BEFORE ${ly_inc_dir} )

# this creates the static library (.a)
ADD_LIBRARY             ( ${ly_lib_static} STATIC ${ly_source_files} )

# this creates the shared library (.so)
ADD_LIBRARY             ( ${ly_lib_shared} SHARED ${ly_source_files} )
SET_TARGET_PROPERTIES   ( ${ly_lib_shared} PROPERTIES OUTPUT_NAME "${ly_lib_name}" )
SET_TARGET_PROPERTIES   ( ${ly_lib_shared} PROPERTIES PREFIX "lib" )

# this creates the conversion tool
#ADD_EXECUTABLE         ( yuvconvert ${ly_base_dir}/util/yuvconvert.cc )
#TARGET_LINK_LIBRARIES  ( yuvconvert ${ly_lib_static} )


INCLUDE ( FindJPEG )
if (JPEG_FOUND)
  include_directories( ${JPEG_INCLUDE_DIR} )
  target_link_libraries( yuvconvert ${JPEG_LIBRARY} )
  add_definitions( -DHAVE_JPEG )
endif()

if(TEST)
  find_library(GTEST_LIBRARY gtest)
  if(GTEST_LIBRARY STREQUAL "GTEST_LIBRARY-NOTFOUND")
    set(GTEST_SRC_DIR /usr/src/gtest CACHE STRING "Location of gtest sources")
    if(EXISTS ${GTEST_SRC_DIR}/src/gtest-all.cc)
      message(STATUS "building gtest from sources in ${GTEST_SRC_DIR}")
      set(gtest_sources ${GTEST_SRC_DIR}/src/gtest-all.cc)
      add_library(gtest STATIC ${gtest_sources})
      include_directories(${GTEST_SRC_DIR})
      include_directories(${GTEST_SRC_DIR}/include)
      set(GTEST_LIBRARY gtest)
    else()
      message(FATAL_ERROR "TEST is set but unable to find gtest library")
    endif()
  endif()

  add_executable(libyuv_unittest ${ly_unittest_sources})
  target_link_libraries(libyuv_unittest ${ly_lib_name} ${GTEST_LIBRARY})
  find_library(PTHREAD_LIBRARY pthread)
  if(NOT PTHREAD_LIBRARY STREQUAL "PTHREAD_LIBRARY-NOTFOUND")
    target_link_libraries(libyuv_unittest pthread)
  endif()
  if (JPEG_FOUND)
    target_link_libraries(libyuv_unittest ${JPEG_LIBRARY})
  endif()

  if(NACL AND NACL_LIBC STREQUAL "newlib")
    target_link_libraries(libyuv_unittest glibc-compat)
  endif()

  find_library(GFLAGS_LIBRARY gflags)
  if(NOT GFLAGS_LIBRARY STREQUAL "GFLAGS_LIBRARY-NOTFOUND")
    target_link_libraries(libyuv_unittest gflags)
    add_definitions(-DLIBYUV_USE_GFLAGS)
  endif()
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(); // 写入文件或进一步处理 } ```
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值