利用布雷森汉姆算法绘制在YUV图像上画直线

最近,因工作需要,在YUV图像上画直线;

算法1步骤:
1.已知直线的起点和终点;

2. 利用布雷森汉姆算法在两点间画直线;

3. 将该直线上的点的颜色在YUV图像上画出。

布雷森汉姆算法原理参考wiki: http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm

yuv图像转换原理参考:http://en.wikipedia.org/wiki/Yuv


参考代码:

unsigned char breshenham(unsigned char* imgdata, int width, int height, nPoint startPoint, nPoint endPoint, nColor color)
{
	if (!imgdata)
	{
		return -1;
	}
	if (width < 0 || height < 0 )
	{
		return -1;
	}
	if (startPoint.x<0 || startPoint.x > width || startPoint.y < 0 || startPoint.y > height || endPoint.x < 0 || endPoint.x > width || endPoint.y < 0 || endPoint.y > height)
	{
		return -1;
	}

	int imgSize = width*height;

	int x0 = startPoint.x, x1 = endPoint.x;
	int y0 = startPoint.y, y1 = endPoint.y;
	int dy = abs(y1 - y0);
	int dx = abs(x1 - x0);
	bool steep = dy>dx ?true:false;

	if (steep)
	{
		swap(x0, y0);
		swap(x1, y1);
	}
	if (x0 > x1)
	{
		swap(x0, x1);
		swap(y0, y1);
	}

	int deltax = x1 - x0;
	int deltay = abs(y1 - y0);

	int error = deltax/2;
	int ystep;
	int y = y0;

	if (y0 < y1)
	ystep = 1;
	else
		ystep = -1;

	for (int x = x0; x < x1; x++)
	{
		if (steep)
		{
			imgdata[x*width + y] = color.r;
			imgdata[imgSize + x/2*width/2 + y/2] = color.g;
			imgdata[imgSize + imgSize/4 + x/2*width/2 + y/2] = color.b;
		}
		else
		{
			imgdata[y*width + x] = color.r;
			imgdata[imgSize + y/2*width/2 + x/2] = color.g;
			imgdata[imgSize + imgSize/4 + y/2*width/2 + x/2] = color.b;
		}

		error -= deltay;
		if (error < 0) 
		{
			y += ystep;
			error += deltax;
		}
	}
	return 1;
}

算法2步骤:
1.已知直线的起点和终点;

2. 利用super vector bresenham算法在两点间画直线;

3. 将该直线上的点的颜色在YUV图像上画出。

super vector bresenham 算法原理参考wiki: http://lifc.univ-fcomte.fr/home/~ededu/projects/bresenham/

yuv图像转换原理参考:http://en.wikipedia.org/wiki/Yuv

void superVectorBresenham(unsigned char* imgData, int width, int height, nPoint startPoint, nPoint endPoint, nColor color)
{
	if (!imgData)
	{
		return ;
	}
	if (width<0 || height<0)
	{
		return;
	}
	if (startPoint.x < 0 || startPoint.x > width || startPoint.y < 0 || startPoint.y > height ||
		 endPoint.x < 0 || endPoint.x >width || endPoint.y < 0 || endPoint.y > height)
	{
		return;
	}

	int imgSize = width*height;
	
	int yStep, xStep;
	int error, errorPrev;
	int y = startPoint.y, x = startPoint.x;
	int ddy, ddx;
	int dx = endPoint.x - startPoint.x;
	int dy = endPoint.y - startPoint.y;

	//StartPoint()
	imgData[y*width + x] = color.r;
	imgData[imgSize + y/2*width/2 + x/2] = uData;
	imgData[imgSize + imgSize/4 + y/2*width/2 + x/2] = vData;

	if (dy < 0)
	{
		yStep = -1;
		dy = -dy;
	}
	else
		yStep = 1;

	if (dx < 0)
	{
		xStep = -1;
		dx = -dx;
	}
	else
		xStep = 1;

	ddx = 2*dx;
	ddy = 2*dy;

	if (ddx >= ddy)
	{
		errorPrev = error = dx;
		for (int i=0; i<dx; i++)
		{
			x += xStep;
			error += ddy;
			if (error > ddx)
			{
				y += yStep;
				error -= ddx;
				if (error + errorPrev < ddx)
				{//POINT(y-ystep, x)
					int tmpY = y - yStep;
					imgData[tmpY*width + x] = color.r;
					imgData[imgSize + tmpY/2*width/2 + x/2] = color.g;
					imgData[imgSize + imgSize/4 + tmpY/2*width/2 + x/2] = color.b;
				}
				else if (error + errorPrev > ddx)
				{
					//POINT(y, x-xstep)
					int tmpX = x - xStep;
					imgData[y*width + tmpX] = color.r;
					imgData[imgSize + y/2*width/2 + tmpX/2] = color.g;
					imgData[imgSize + imgSize/4 + y/2*width/2 + tmpX/2] = color.b;
				}
				else
				{
					//POINT(y-ystep, x)
					int tmpY = y - yStep;
					imgData[tmpY*width + x] = color.r;
					imgData[imgSize + tmpY/2*width/2 + x/2] = color.g;
					imgData[imgSize + imgSize/4 + tmpY/2*width/2 + x/2] = color.b;

					//POINT(y, x-xstep)
					int tmpX = x - xStep;
					imgData[y*width + tmpX] = color.r;
					imgData[imgSize + y/2*width/2 + tmpX/2] = color.g;
					imgData[imgSize + imgSize/4 + y/2*width/2 + tmpX/2] = color.b;
				}
			}
			
			//POINT(y,x)
				imgData[y*width + x] = color.r;
				imgData[imgSize + y/2*width/2 + x/2] = color.g;
				imgData[imgSize + imgSize/4 + y/2*width/2 + x/2] = color.b;
				errorPrev = error;
		}
	}

	else
	{
		errorPrev = error = dy;
	
		for (int i=0; i<dy; i++)
		{
			y += yStep;
			error += ddx;
			if (error > ddy)
			{
				x += xStep;
				error -= ddy;
				if (error + errorPrev < ddy)
				{
					//POINT(y, x-xstep)
					int tmpX = x - xStep;
					imgData[y*width + tmpX] = color.r;
					imgData[imgSize + y/2*width/2 + tmpX/2] = color.g;
					imgData[imgSize + imgSize/4 + y/2*width/2 + tmpX/2] = color.b;
				}
				else if (error + errorPrev > ddy)
				{
					//POINT(y-ystep, x)
					int tmpY = y - yStep;
					imgData[tmpY*width + x] = color.r;
					imgData[imgSize + tmpY/2*width/2 + x/2] = color.g;
					imgData[imgSize + imgSize/4 + tmpY/2*width/2 + x/2] = color.b;
				}
				else
				{
					//POINT(y, x-xstep)
					int tmpX = x - xStep;
					imgData[y*width + tmpX] = color.r;
					imgData[imgSize + y/2*width/2 + tmpX/2] = color.g;
					imgData[imgSize + imgSize/4 + y/2*width/2 + tmpX/2] = color.b;

					//POINT(y-ystep, x)
					int tmpY = y - yStep;
					imgData[tmpY*width + x] = color.r;
					imgData[imgSize + tmpY/2*width/2 + x/2] = color.g;
					imgData[imgSize + imgSize/4 + tmpY/2*width/2 + x/2] = color.b;
				}
			}

			//POINT(y, x)
			imgData[y*width + x] = color.r;
			imgData[imgSize + y/2*width/2 + x/2] = color.g;
			imgData[imgSize + imgSize/4 + y/2*width/2 + x/2] = color.b;
			errorPrev = error;
		}
	}
}






  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值