如何裁剪YUV420图像,抓取指定区域,制作方形视频,模仿Instagram

I420格式介绍

在webrtc中android和ios系统采集摄像头获取到原始数据后,
一帧原始图像会被转化为标准的YUV420P格式,也就是I420格式,
转换的函数使用的是libyuv中的ConvertToI420()函数

YUV格式详细讲解

进行裁剪操作需要对I420格式的内存分布有深入的了解,推荐大家看这篇文章:
http://blog.csdn.net/jefry_xdz/article/details/7931018 
其中I420就是YUV420P格式

裁剪图像的含义

裁剪就是去掉某些区域,剩下指定的区域,
本文所讲的裁剪就是抠图,抠去出原图像的某个内部区域

裁剪的用途

我们可以将裁剪后的视频传递给h264编码器,然后将输出保存成MP4文件(还需要加上声音),即可模仿Instagram软件中拍摄方形视频的功能。

代码如下:

代码中假设视频宽度和“Image Stride”相同
什么是stride? 参考这篇文章:
https://msdn.microsoft.com/en-us/library/windows/desktop/aa473780(v=vs.85).aspx

这里使用到了webrtc中的部分代码其中I420VideoFrame格式定义为
https://code.google.com/p/webrtc/source/browse/trunk/webrtc/video_frame.h?r=8434
所以dst_frame是这样生成的:
  dst_frame->CreateEmptyFrame(dst_width_, dst_height_,
                              dst_width_, (dst_width_ + 1) / 2,
                              (dst_width_ + 1) / 2);
int zp_getImageBlock(const I420VideoFrame& src_frame, I420VideoFrame& dst_frame,int start_w,int start_h)
    {

        //I420格式说明参考的这个博客 http://blog.csdn.net/jefry_xdz/article/details/7931018
        
        assert(start_w >= 0 && start_h >= 0);
        //start_w 开始点距离左边的距离
        //start_h 开始点距离上边的距离
        //起始点可以决定裁剪视频的哪个区域,不一定是中心区域
        
        int src_width = src_frame.width();
        int src_height = src_frame.height();
        int dst_width = dst_frame.width();
        int dst_height = dst_frame.height();
        
        if (start_w + dst_width > src_width ||
            start_h + dst_height > src_height) {
            //区域设置不合理,已经超出原始视频范围
            return -1;
        }
        if(dst_height > src_height || dst_width > src_width)
        {
            //只能缩小,不能扩大,扩大使用libyuv的scale函数
            return -1;
        }
        
        int w_cut = start_w;
        int h_cut = start_h;
        
        //切除的部分必须是偶数,因为每四个像素对应一个u,v
        assert(w_cut%2==0);
        assert(h_cut%2==0);
        
        const uint8* src_y = src_frame.buffer(kYPlane);
        uint8* dst_y = dst_frame.buffer(kYPlane);
        const uint8* src_u = src_frame.buffer(kUPlane);
        uint8* dst_u = dst_frame.buffer(kUPlane);
        const uint8* src_v = src_frame.buffer(kVPlane);
        uint8* dst_v = dst_frame.buffer(kVPlane);
        
        //取Y
        for (int row = 0; row < dst_height; ++row) {
            for (int col = 0; col < dst_width; ++col) {
                //计算目标区域的下标对应于源数据的哪个下标
                //目标区域的下表row*dst_width+col
                //(h_cut+row)*src_width+(w_cut+col)
                dst_y[row*dst_width+col] = src_y[(h_cut+row)*src_width+(w_cut+col)];
            }
        }
        
        //取U,V
        int k = 0;
        for (int row = 0; row < dst_height; row+=2) {
            for (int col = 0; col < dst_width; col+=2) {
                int old_index = (h_cut+row)*src_width/4+(w_cut+col)/2;
                dst_u[k] = src_u[old_index];
                dst_v[k] = src_v[old_index];
                k++;
            }
        }
        return 0;
    }
    
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,634评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,951评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,427评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,770评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,835评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,799评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,768评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,544评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,979评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,271评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,427评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,121评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,756评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,375评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,579评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,410评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,315评论 2 352

推荐阅读更多精彩内容