您的位置:首页 > 其它

YUV420(YV12,I420)裁剪,画中画算法实现(笔记)

2018-01-05 10:07 120 查看
关于RGB和YUV的数据排列不再累述,百度很多。

YV12,I420同属YUV420P,加了一个P的意思,我理解为把Y,U,V分量按块排列,即YYYYYYYY  UU  VV这样。YV12,I420的区别在于U和V的位置颠倒而已。

直接贴代码吧:

1、裁剪算法:

static void Cut_YV12(BYTE* Src,int x,int y,int srcWidth,int srcHeight,BYTE* Dst,int desWidth,int desHeight)//图片按位置裁剪
{
//得到B图像所在A的坐标
int nIndex=0;
int BPosX=x ;//列
int BPosY=y;//行
for(int i=0;i<desHeight;i++)//
{
memcpy(Dst+desWidth*i,Src+(srcWidth*BPosY)+BPosX+nIndex,desWidth);
nIndex+=(srcWidth);
}

nIndex=0;
BYTE *pUSour=Src+srcWidth*srcHeight;
BYTE *pUDest=Dst+desWidth*desHeight;
for(int i=0;i<desHeight/2;i++)//
{
memcpy(pUDest+desWidth/2*i,pUSour+(srcWidth/2*BPosY/2)+BPosX/2+nIndex,desWidth/2);
nIndex+=(srcWidth/2);
}

nIndex=0;
BYTE *pVSour=Src+srcWidth*srcHeight*5/4;
BYTE *pVDest=Dst+desWidth*desHeight*5/4;
for(int i=0;i<desHeight/2;i++)//
{
memcpy(pVDest+desWidth/2*i,pVSour+(srcWidth/2*BPosY/2)+BPosX/2+nIndex,desWidth/2);
nIndex+=(srcWidth/2);
}

}上面是YV12的算法,如果是I420,直接把U和V分量交换下即可。
2、画中画算法:

static void PicIn_YV12(BYTE* Src,int x,int y,int srcWidth,int srcHeight,BYTE* Dst,int desWidth,int desHeight)//图片按位置合并
{
if(x+srcWidth>desWidth)//越界
return;
if(y+srcHeight>desHeight)//越界
return;

//得到B图像所在A的坐标
int nIndex=0;
int BPosX=x ;//列
int BPosY=y;//行
for(int i=0;i<srcHeight;i++)//
{
memcpy(Dst+(desWidth*BPosY)+BPosX+nIndex,Src+(srcWidth*i),srcWidth);
nIndex+=(desWidth);
}

nIndex=0;
BYTE *pUSour=Src+srcWidth*srcHeight;
BYTE *pUDest=Dst+desWidth*desHeight;
for(int i=0;i<srcHeight/2;i++)//
{
memcpy(pUDest+(desWidth/2*BPosY/2)+BPosX/2+nIndex,pUSour+(srcWidth/2*i),srcWidth/2);
nIndex+=(desWidth/2);
}

nIndex=0;
BYTE *pVSour=Src+srcWidth*srcHeight*5/4;
BYTE *pVDest=Dst+desWidth*desHeight*5/4;
for(int i=0;i<srcHeight/2;i++)//
{
memcpy(pVDest+(desWidth/2*BPosY/2)+BPosX/2+nIndex,pVSour+(srcWidth/2*i),srcWidth/2);
nIndex+=(desWidth/2);
}

}上面是YV12的算法,如果是I420,直接把U和V分量交换下即可。
上面2个算法均未考虑奇数宽高的情况,所以,输入的值应该均为偶数,保证完全正确应该考虑补位的情况,先不管这些了。记录下这2个算法,以备后用,也希望能帮助到您!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: