ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

YUV切割

2019-06-02 13:52:44  阅读:288  来源: 互联网

标签:src 切割 int h1 YUV char w1 memcpy


YUV分割原理是对Y、U、V三个分量分别处理。以下使用I420做例子列举出左右、上下、切块三种方式,原理都一样。

不画图直接上代码。

 

左右切割:

void CutLR(const char* src1, int w, int h)
{
	int w1 = w / 2, w2 = w - w1;
	int h1 = h, h2 = h;
	char* cut_L = new char[w1 * h1 * 3 / 2];    // Left planer
	char* cut_R = new char[w2 * h2 * 3 / 2];    // Right planer
	    
	char* src_y = (char*)src1;
	char* src_u = src_y + w * h;
	char* src_v = src_u + w / 2 * h / 2;

	char* y1 = cut_L;
	char* u1 = cut_L + w1 * h1;
	char* v1 = u1 + w1 / 2 * h1 / 2;
	char* y2 = cut_R;
	char* u2 = cut_R + w2 * h2;
	char* v2 = u2 + w2 / 2 * h2 / 2;

	for (int i = 0; i < h; i++)
	{
		// Left y
		memcpy(y1 + i*w1, src_y + i * w, w1);	
		// Right y
		memcpy(y2 + i*w2, src_y + i*w + w1, w2);
	}

	for (int i = 0; i < h / 2; i++)
	{
		// Left uv
		memcpy(u1 + i*w1 / 2, src_u + i*w / 2, w1 / 2);
		memcpy(v1 + i*w1 / 2, src_v + i*w / 2, w1 / 2);

		// Right uv
		memcpy(u2 + i*w1 / 2, src_u + i*w / 2 + w1/2, w1 / 2);
		memcpy(v2 + i*w1 / 2, src_v + i*w / 2 + w1/2, w1 / 2);
	}
}

上下切割:

void CutUD(const char* src1, int w, int h)
{
	int w1 = w, w2 = w;
	int h1 = h / 2, h2 = h - h1;

	char* cut_U = new char[w1 * h1 * 3 / 2];	// Up planer
	char* cut_D = new char[w2 * h2 * 3 / 2];	// Down planer

	char* src_y = (char*)src1;
	char* src_u = src_y + w * h;
	char* src_v = src_u + w / 2 * h / 2;

	char* y1 = cut_U;
	char* u1 = cut_U + w1 * h1;
	char* v1 = u1 + w1 / 2 * h1 / 2;
	char* y2 = cut_D;
	char* u2 = cut_D + w2 * h2;
	char* v2 = u2 + w2 / 2 * h2 / 2;

	// Up y
	for (int i = 0; i < h1; i++)
	{
		memcpy(y1 + i*w1, src_y + i*w, w1);
	}
	// Up uv
	for (int i = 0; i < h1 / 2; i++)
	{
		memcpy(u1 + i*w1 / 2, src_u + i * w / 2, w1 / 2);
		memcpy(v1 + i*w1 / 2, src_v + i * w / 2, w1 / 2);
	}

	// Down y
	for (int i = 0; i < h2; i++)
	{
		memcpy(y2 + i*w2, src_y + (i + h1)*w, w2);
	}
	// Down uv
	for (int i = 0; i < h2 / 2; i++)
	{
		memcpy(u2 + i*w1 / 2, src_u + (i+h1/2) * w / 2, w1 / 2);
		memcpy(v2 + i*w1 / 2, src_v + (i+h1/2) * w / 2, w1 / 2);
	}
}

切割块:

/*
* src1: source i420
* w: source width
* h: source height
* x,y: cut postion
* dw: destination width
* dh: destination height
*/
void CutBlock(const char* src1, int w, int h, int x, int y, int dw, int dh)
{
	if (x + dw > w || y + dh > h) return;

	char* dst = new char[dw*dh * 3 / 2];    // dst YUV
	char* dst_y = dst;
	char* dst_u = dst + dw * dh;
	char* dst_v = dst_u + dw / 2 * dh / 2;

	char* src_y = (char*)src1;
	char* src_u = src_y + w * h;
	char* src_v = src_u + w / 2 * h / 2;

	for (int i = 0; i < dh; i++)
	{
		memcpy(dst_y + i * dw, src_y + (i + y) * w + x, dw);
	}
	for (int i = 0; i < dh / 2; i++)
	{
		memcpy(dst_u + i * dw / 2, src_u + (i + y / 2) * w / 2 + x/2, dw / 2);
		memcpy(dst_v + i * dw / 2, src_v + (i + y / 2) * w / 2 + x/2, dw / 2);
	}
}

 

标签:src,切割,int,h1,YUV,char,w1,memcpy
来源: https://blog.csdn.net/andrew57/article/details/90738080

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有