FFmpeg之yuv裁剪(二十一)

本文详细介绍了如何在Android中针对YUV420sp、YUV420p和YUYV格式的数据进行裁剪,重点讲解了不同格式下Y、U、V之间的共用关系以及对应的内存操作。同时提到了Android开发中的一些高级架构和资源学习资源。
摘要由CSDN通过智能技术生成

需要注意YUV三者的共用关系,Y的裁剪比较直接;但是对于UV而言,UV的大小各只有Y的大小的1/4(U的宽高和V的宽高都是Y的宽高的一半),因此在横纵向都要进行跳行,在横向由于UV是交叉排序,width / 2 的V和 width / 2 的U加起来刚好就是Y的大小,可以直接按偏移量裁剪。

void cropYuv420sp(char *yuv420sp, char *cropYuv420sp, int width, int height, int left, int top,

int right, int bottom) {

int halfWidth = width / 2;

int cropImageWidth = right - left;

int cropImageHeight = bottom - top;

//复制Y

int originalYLineStart = top * width;

int targetYIndex = 0;

//复制UV

int originalUVLineStart = width * height + top * halfWidth;

int targetUVIndex = cropImageWidth * cropImageHeight;

for (int i = top; i < bottom; i++) {

memcpy(cropYuv420sp + targetYIndex, yuv420sp + originalYLineStart + left, cropImageWidth);

originalYLineStart += width;

targetYIndex += cropImageWidth;

if ((i & 1) == 0) {

memcpy(cropYuv420sp + targetUVIndex, yuv420sp + originalUVLineStart + left,

cropImageWidth);

originalUVLineStart += width;

targetUVIndex += cropImageWidth;

}

}

}

2. 裁剪YV12I420

和裁剪NV21类似,Y的裁剪比较直接;但是对于UV而言,UV的大小各只有Y的大小的1/4,且是各自连续排序(U的宽高和V的宽高都是Y的宽高的一半),因此在横纵向都要进行跳行。

void cropYuv420p(char *yuv420p, char *cropYuv420p, int width, int height, int left, int top,

int right, int bottom) {

int halfWidth = width / 2;

int cropImageWidth = right - left;

int cropImageHeight = bottom - top;

//复制Y

int originalYLineStart = top * width;

int targetYIndex = 0;

//复制UV

int originalULineStart = width * height + top * halfWidth / 2;

int originalVLineStart = width * height + width * height / 4 + top * halfWidth / 2;

int targetUIndex = cropImageWidth * cropImageHeight;

int targetVIndex = cropImageWidth * cropImageHeight * 5 / 4;

int halfImageWidth = halfWidth;

int halfLeft = left / 2;

int halfCropImageWidth = cropImageWidth / 2;

for (int i = top; i < bottom; i++) {

memcpy(cropYuv420p + targetYIndex, yuv420p + originalYLineStart + left, cropImageWidth);

originalYLineStart += width;

targetYIndex += cropImageWidth;

if ((i & 1) == 0) {

memcpy(cropYuv420p + targetUIndex, yuv420p + originalULineStart + halfLeft,

halfCropImageWidth);

memcpy(cropYuv420p + targetVIndex, yuv420p + originalVLineStart + halfLeft,

halfCropImageWidth);

originalULineStart += halfImageWidth;

originalVLineStart += halfImageWidth;

targetUIndex += halfCropImageWidth;

targetVIndex += halfCropImageWidth;

}

}

}

3. 裁剪YUYV

**和NV21I420之类的数据不同,YUYV的排列方式是YUYV YUYV....,每行的连续4个byte会有共用关系,这4个byte相当于2个像素),每行的数据宽度是 width * 2。

注意:该函数对入参有限制,需要裁剪的边界都需要是偶数。**

void cropYuyv(char *yuyv, char *cropYuyv, int width, int height, int left, int top, int right,

int bottom) {

int cropImageWidth = right - left;

int cropImageHeight = bottom - top;

【延伸Android必备知识点】

【Android部分高级架构视频学习资源】

**Android精讲视频学习后更加是如虎添翼!**进军BATJ大厂等(备战)!现在都说互联网寒冬,其实无非就是你上错了车,且穿的少(技能),要是你上对车,自身技术能力够强,公司换掉的代价大,怎么可能会被裁掉,都是淘汰末端的业务Curd而已!现如今市场上初级程序员泛滥,这套教程针对Android开发工程师1-6年的人员、正处于瓶颈期,想要年后突破自己涨薪的,进阶Android中高级、架构师对你更是如鱼得水!

**任何市场都是优胜略汰适者生存,只要你技术过硬,到哪里都不存在饱和不饱和的问题,所以重要的还是提升自己。懂得多是自己的加分项 而不是必须项。门槛高了只能证明这个市场在不断成熟化!**另外一千个读者就有一千个哈姆雷特,所以以上只是自己的关键,不喜勿喷!

如果你是卡在缺少学习资源的瓶颈上,那么刚刚好我能帮到你。欢迎关注会持续更新和分享的。
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可获取!
不断成熟化!**另外一千个读者就有一千个哈姆雷特,所以以上只是自己的关键,不喜勿喷!

如果你是卡在缺少学习资源的瓶颈上,那么刚刚好我能帮到你。欢迎关注会持续更新和分享的。
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可获取!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值