知道了YUV切割和合并的原理,叠加其实就是覆盖相应位置的数据,如果用或运算符就是混合,前面合并一篇有提及。
下面还是使用I420数据,直接上代码。
/*
* src1: background yuv
* src2: source yuv
* w1: src1 width
* h1: src1 height
* w2: src2 width
* h2: src2 height
* x,y: src2 cover postion
*/
void Overlay(const char* src1, const char* src2, int w1, int h1, int w2, int h2, int x, int y)
{
if (w1 < w2 || h1 < h2) return;
if (x + w2 > w1 || y + h2 > h1) {
printf("pos out of range");
return;
}
int nW = w1, nH = h1;
char *dst = new char[nW * nH * 3 / 2];
char* dst_y = dst;
char* dst_u = dst + nW * nH;
char* dst_v = dst_u + nW / 2 * nH / 2;
char* src_y = (char*)src2;
char* src_u = src_y + w2 * h2;
char* src_v = src_u + w2 / 2 * h2 / 2;
// background
memcpy(dst, src1, w1 * h1 * 3 / 2);
for (int i = 0; i < h2; i++)
{
for (int j = 0; j < w2; j++)
{
// y
*(dst_y + (i+y) * w1 + (j+x)) = *(src_y + i * w2 + j);
}
}
for (int i = 0; i < h2/2; i++)
{
for (int j = 0; j < w2/2; j++)
{
// u
*(dst_u + (i + y/2) * w1 / 2 + (j + x/2)) = *(src_u + i * w2 / 2 + j);
// v
*(dst_v + (i + y/2) * w1 / 2 + (j + x/2)) = *(src_v + i * w2 / 2 + j);
}
}
}