您的位置:首页 > 其它

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

2013-06-19 18:01 267 查看
最近,因工作需要,在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;
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: