最近,因工作需要,在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;
}
}
}