YUV420图像的裁剪

小白一个,开始研究YUV,记录一下心得,如果有什么说得不对的地方,请及时纠正吐舌头


最近实现了一个yuv裁剪的功能,现在做一些整理:

宽和高分别为w和h的yuv420图像的大小为w*h*3/2,对于NV21和NV12来说,前w*h Byte存储Y分量,后w*h/2 Byte存储UV分量,NV12和NV21不同就是UV分量的位置不同,具体自行百度。

具体实现如下:

void cutYuv(int yuvType, unsigned char *tarYuv, unsigned char *srcYuv, int startW,
            int startH, int cutW, int cutH, int srcW, int srcH) 
{
  int i;
  int j = 0;
  int k = 0;
  //分配一段内存,用于存储裁剪后的Y分量 
  unsigned char *tmpY = (unsigned char *)malloc(cutW*cutH);
  //分配一段内存,用于存储裁剪后的UV分量 
	unsigned char *tmpUV = (unsigned char *)malloc(cutW*cutH/2);
  switch (yuvType) {
    case NV21OR21:
         for(i=startH; i<cutH+startH; i++) {
           // 逐行拷贝Y分量,共拷贝cutW*cutH
           memcpy(tmpY+j*cutW, srcYuv+startW+i*srcW, cutW);
           j++;
         }
         for(i=startH/2; i<(cutH+startH)/2; i++) {
           //逐行拷贝UV分量,共拷贝cutW*cutH/2
           memcpy(tmpUV+k*cutW, srcYuv+startW+srcW*srcH+i*srcW, cutW);
           k++;
         }
         //将拷贝好的Y,UV分量拷贝到目标内存中
         memcpy(tarYuv, tmpY, cutW*cutH);
         memcpy(tarYuv+cutW*cutH, tmpUV, cutW*cutH/2);
         free(tmpY);
         free(tmpUV);
         break;
    case YUV420SP:
    //Not FInished
         break;
   }
}


参数的含义:yuvType  --------------------------   yuv类型,目前只支持NV12和NV21

                        tarYuv     --------------------------   存储裁剪结果的内存

                        srcYuv    --------------------------   原始YUV数据,通过fread获取

                        startW,startH  --------------------------  开始裁剪的坐标位置

                        cutW,cutH  --------------------------  裁剪过后的分辨率

                        srcW,srcH  --------------------------  原始YUV数据的分辨率


从代码看出,分别拷贝Y分量和UV分量即可。具体测试结果如下:


裁剪前,分辨率1144*789(不要问为什么这么奇葩,QQ截图随便截的)


在裁剪坐标20,50  裁剪大小500,500之后,结果如下


评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值