FFmpeg之yuv裁剪(二十一)
1. 裁剪NV21
或NV12
需要注意Y
、U
、V
三者的共用关系,Y
的裁剪比较直接;但是对于U
和V
而言,U
和V
的大小各只有Y
的大小的1/4(U
的宽高和V
的宽高都是Y
的宽高的一半),因此在横纵向都要进行跳行,在横向由于U
和V
是交叉排序,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;//复制Yint originalYLineStart = top * width;int targetYIndex = 0;//复制UVint 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. 裁剪YV12
或I420
和裁剪NV21
类似,Y的裁剪比较直接;但是对于U
和V
而言,U
和V
的大小各只有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;//复制Yint originalYLineStart = top * width;int targetYIndex = 0;//复制UVint 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
和NV21
、I420
之类的数据不同,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;int lineDataSize = width * 2;int cropLineDataSize = cropImageWidth * 2;int originalLineStart = top * width * 2;int targetIndex = 0;int lineOffsetDataSize = left * 2;for (int i = top; i < bottom; i++) {memcpy(cropYuyv + targetIndex, yuyv + originalLineStart + lineOffsetDataSize, cropLineDataSize);originalLineStart += lineDataSize;targetIndex += cropLineDataSize;}
}
4. 裁剪BGR24
无论是BGR24
、RGB24
,在裁剪时,都是以3个byte为一个整体进行裁剪,因此以下代码兼容24bpp的RGB数据的裁剪。
void cropRgb24(char *rgb24, char *cropRgb24, int width, int height, int left, int top, int right,int bottom) {int cropImageWidth = right - left;int cropImageHeight = bottom - top;int lineDataSize = width * 3;int cropLineDataSize = cropImageWidth * 3;int originalLineStart = top * lineDataSize;int targetIndex = 0;int lineOffsetDataSize = left * 3;for (int i = top; i < bottom; i++) {memcpy(cropRgb24 + targetIndex, rgb24 + originalLineStart + lineOffsetDataSize, cropLineDataSize);originalLineStart += lineDataSize;targetIndex += cropLineDataSize;}
}
FFmpeg之yuv裁剪(二十一)相关推荐
- ffmpeg实战教程(二)用SDL播放YUV,并结合ffmpeg实现简易播放器
ffmpeg实战教程(二)用SDL播放YUV,并结合ffmpeg实现简易播放器 https://blog.csdn.net/King1425/article/details/71171142 我们先实 ...
- VTK学习笔记(二十一)vtk裁剪求截面面积
VTK学习笔记(二十一)vtk裁剪求界面面积 1.代码 2.CMakeLists.txt 3.运行输出 4.面积正确性验证 4.1.代码 4.2.执行结果 1.代码 #pragma once#incl ...
- 中介者模式 调停者 Mediator 行为型 设计模式(二十一)
中介者模式(Mediator) 调度.调停 意图 用一个中介对象(中介者)来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散 而且可以独立地改变它们之间的交互. 中介者模式又 ...
- 二十一世纪贫穷人的2008条语录
流失的是岁月,留不走的是语言的录音-- 二十一世纪贫穷人的2006条语录 随便一条就能记住的:随便一条就能深思的:随便一条就能看下去的:随便一条就是哲理的:随便一条链接起来就是文章的:随便一条就能告诉 ...
- 二十一. Python基础(21)--Python基础(21)
二十一. Python基础(21)--Python基础(21) 1 ● 类的命名空间 #对于类的静态属性: #类.属性: 调用的就是类中的属性 #对象.属性: 先从自己的内存空间里找名 ...
- 某云数据中心网络解决方案(分享二十一)
某云数据中心网络解决方案(分享二十一) 参考文章: (1)某云数据中心网络解决方案(分享二十一) (2)https://www.cnblogs.com/zywu-king/p/8284189.html ...
- iOS 11开发教程(二十一)iOS11应用视图美化按钮之实现按钮的响应(1)
iOS 11开发教程(二十一)iOS11应用视图美化按钮之实现按钮的响应(1) 按钮主要是实现用户交互的,即实现响应.按钮实现响应的方式可以根据添加按钮的不同分为两种:一种是编辑界面添加按钮实现的响应 ...
- 运动控制器编程_快速入门 | 篇二十一:运动控制器ZHMI组态编程简介一
点击上方"正运动小助手",随时关注新动态! 运动控制器ZHMI组态编程简介一 今天我们来学习一下,运动控制器的ZHMI组态编程简介.本文主要从产品概述.控制器连接触摸屏使用.HM ...
- SQL Server数据库开发的二十一条军规
如果你正在负责一个基于SQL Server的项目,或者你刚刚接触SQL Server,你都有可能要面临一些数据库性能的问题,这篇文章会为你提供一些有用的指导(其中大多数也可以用于其它的DBMS). 在 ...
最新文章
- NanoPi NEO Air使用十五:使用V4L2驱动USB摄像头
- python 美颜人脸
- 欣赏多彩的计算机作品教案,五年级上信息技术教案-欣赏多彩的计算机作品长春版(三起).docx...
- springboot 控制台程序读取配置文件(原创)
- SAP License:2021年最新FICO面试答案
- Android开发笔记(一百七十七)借助FileProvider安装应用
- linux分析目录内存,在 Linux x86-64 模式下分析内存映射流程
- MySql 存储大量长字节 Text报错处理办法
- 第2节 网站点击流项目(下):5、访客分析
- 吉他录音混音教程|连这些录音知识都不懂,以后还怎么“混”?| MZD Studios
- 药物研发企业用哪个项目管理软件好?
- 电信云服务器装系统,天翼云主机重装系统的详细操作步骤
- 模拟题 czy的后宫
- Java使用JavaMail收发Email电子邮件
- 怎么让浏览器一直前置_上海居住证积分没有前置学历怎么解决?
- syntactic sugar - 语法糖 - 糖衣语法
- Cadence Orcad Capture元件位号自动编号的2种方法图文教程及视频演示
- Thinkpad E470重装WIN7系统后,重启进入boot menu的问题
- 关于:File.separator ( 详解 )
- 「数据库选型」抛弃MongoDB,拥抱PostgreSQL,工作更轻松
热门文章
- 关于maven modules开发时候,eclipse的dubug模式不能找到源代码
- 判定是否支持XHTML
- 利用光盘恢复grub引导器
- C#程序员66个编码好习惯
- Qt 发布 Android 自动驾驶技术预览
- 逆向工程平台 Radare2
- android pod 组件化_Flutter组件化导入至iOS现有工程中(CocoaPods篇)
- android http 图片上传,Android okHttp上传图片
- 模拟鱼群的matlab算法,IFSA人工鱼群算法
- apache 版本_Apache官宣!ShardingSphere首个Apache版本发布