学习记录:各种YUV图像上画线的实现

Posted fanchenxinok

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了学习记录:各种YUV图像上画线的实现相关的知识,希望对你有一定的参考价值。

写本篇文章的目的不是为了在YUV图像上画出多么性感的直线,而是带大家认识YUV家族,学习YUV家族成员的数据是怎么排布的。

几种常用YUV格式图像内存分布 (以 4x4 共16个像素为例):

 (1)YUV444I (interleaved)

          每个Y分量都有一个UV分量

YUVYUVYUVYUV
YUVYUVYUVYUV
YUVYUVYUVYUV
YUVYUVYUVYUV

(2)YUV444P (planar)

          每个Y分量都有一个UV分量                                          

YYYY
YYYY
YYYY
YYYY
UUUU
UUUU
UUUU
UUUU
VVVV
VVVV
VVVV
VVVV

 (3)YUV422P

           每两个Y分量公用一个UV分量,0号两个Y对应0号的UV

Y(0)Y(1)Y(2)Y(3)
Y(0)Y(1)Y(2)Y(3)
Y(4)Y(5)Y(6)Y(7)
Y(4)Y(5)Y(6)Y(7)
U(0)U(1)U(2)U(3)
U(4)U(5)U(6)U(7)
V(0)V(1)V(2)V(3)
V(4)V(5)V(6)V(7)

(4)YUV422I_UYVY / YUYV / VYUY / YVYU

         每两个Y分量公用一个UV分量

UYVYUYVY
UYVYUYVY
UYVYUYVY
UYVYUYVY

(5)YUV420SP_NV12 / NV21

          每四个Y分量公用一个UV分量, 0号四个Y分量对应0号的两个UV

Y(0)Y(0)Y(1)Y(1)
Y(0)Y(0)Y(1)Y(1)
Y(2)Y(2)Y(3)Y(3)
Y(2)Y(2)Y(3)Y(3)
U(0)V(0)U(1)V(1)
U(2)V(2)U(3)V(3)

(6)YUV420I

每四个Y分量公用一个UV分量,UV不是交替排列

Y(0)Y(0)Y(1)Y(1)
Y(0)Y(0)Y(1)Y(1)
Y(2)Y(2)Y(3)Y(3)
Y(2)Y(2)Y(3)Y(3)
U(0)U(1)U(2)U(3)
V(0)V(1)V(2)V(3)

代码如下:

#include <stdio.h>
#define READ_MAX (1024)

typedef unsigned char  uInt8;
typedef unsigned short uInt16;
typedef unsigned int uInt32;
typedef char Int8;
typedef short Int16;
typedef int Int32;

typedef enum

	TYPE_YUV422I_UYVY,
	TYPE_YUV422I_YUYV,
	TYPE_YUV420SP_NV12,
	TYPE_YUV420SP_NV21,
	TYPE_YUV422P,
	TYPE_YUV444I,
	TYPE_YUV444P,
	TYPE_YUV420I,
enYuvType;

typedef enum

	YUV_GREEN,
	YUV_RED,
	YUV_BLUE,
	YUV_PURPLE,
	YUV_DARK_GREEN,
	YUV_YELLOW,
	YUV_LIGHT_BLUE,
	YUV_LIGHT_PURPLE,
	YUV_DARK_BLACK,
	YUV_GRAY,
	YUV_WHITE,
	YUV_COLOR_MAX,
enYuvColorIdx;

typedef struct

	uInt8 Y;
	uInt8 U;
	uInt8 V;
stYuvColor;

typedef struct

	uInt16 x;
	uInt16 y;
stPoint;

typedef struct

	stPoint startPoint;
	stPoint endPoint;
	uInt16 lineWidth;
	enYuvColorIdx clrIdx;
stDrawLineInfo;

typedef struct

	enYuvType yuvType;
	uInt8 *pYuvBuff;
	uInt16 width;
	uInt16 height;
stYuvBuffInfo;

#pragma pack (1)
typedef struct

	uInt16 x : 14;
	uInt16 y : 14;
	uInt8 color_idx : 4; // 2^4 可以指定16种颜色
stYuvPixMap;
#pragma pack ()

typedef struct

	uInt32 pixNums;
	stYuvPixMap *pPixMapBuff;
stPixMapInfo;

static stYuvColor s_color_table[YUV_COLOR_MAX] = 
	0x00, 0x00, 0x00, // green
	0x00, 0x00, 0xff, // red
	0x00, 0xff, 0x00,	// blue
	0x00, 0xff, 0xff,	// purple
	0xff, 0x00, 0x00, // dark green
	0xff, 0x00, 0xff, // yellow
	0xff, 0xff, 0x00, // light blue
	0xff, 0xff, 0xff, // light purple
	0x00, 0x80, 0x80, // dark black
	0x80, 0x80, 0x80, // gray
	0xff, 0x80, 0x80, // white
;

Int32 read_file(const char* file, uInt8 *pOut)

	Int32 size = 0;
	uInt8 *p = pOut;
	FILE* fp = fopen(file, "rb");
	if(fp && pOut) 
		int n = 0;
		while((n = fread(p, 1, READ_MAX, fp)) > 0) 
			size += n;
			p += n;
			if(n < READ_MAX)
				break;
		
		fclose(fp);
		printf("	%s, size = %d\\n", file, size);
	
	else 
		printf("Open %s png file fail\\n", file);
	

	return size;



void yuv_setdata(
	uInt8* YBuff,
	uInt8* UVBuff,
	enYuvType yuvType,
	uInt16 width,
	uInt16 height,
	stPoint draw_point,
	enYuvColorIdx clrIdx)

	switch(yuvType)
	
		case TYPE_YUV422I_UYVY:
		case TYPE_YUV422I_YUYV:
		
			/*
				UYVY UYVY UYVY UYVY
			*/
			uInt32 tmp = draw_point.y * width * 2;
			uInt32 y_offset = 0, u_offset = 0, v_offset = 0;
			if(yuvType == TYPE_YUV422I_UYVY) 
				u_offset = tmp + draw_point.x / 2 * 4;
				v_offset = u_offset + 2;
				y_offset = u_offset + 1;
			
			else 
				y_offset = tmp + draw_point.x / 2 * 4;
				u_offset = y_offset + 1;
				v_offset = u_offset + 2;
			
			YBuff[y_offset] = s_color_table[clrIdx].Y;
			YBuff[y_offset + 2] = s_color_table[clrIdx].Y;
			YBuff[u_offset] = s_color_table[clrIdx].U;
			YBuff[v_offset] = s_color_table[clrIdx].V;
		break;
		case TYPE_YUV420SP_NV12:
		case TYPE_YUV420SP_NV21:
		
			/*
				YY YY
				YY YY
				UV UV
			*/
			uInt32 y_offset = draw_point.y * width + draw_point.x;
			uInt32 u_offset = 0, v_offset = 0;
			YBuff[y_offset] = s_color_table[clrIdx].Y;
			#if 0
			Int32 x_flag = 1, y_flag = 1;
			if(draw_point.y % 2 == 0) 
				YBuff[y_offset + width] = s_color_table[clrIdx].Y;
				y_flag = 1;
			
			else 
				YBuff[y_offset - width] = s_color_table[clrIdx].Y;
				y_flag = -1;
			

			if(draw_point.x % 2 == 0) 
				YBuff[y_offset + 1] = s_color_table[clrIdx].Y;
				x_flag = 1;
			
			else 
				YBuff[y_offset - 1] = s_color_table[clrIdx].Y;
				x_flag = -1;
			
			YBuff[y_offset + width * y_flag + 1 * x_flag] = s_color_table[clrIdx].Y;
			#endif
			
			if(yuvType == TYPE_YUV420SP_NV12) 
				u_offset = (draw_point.y / 2) * width + draw_point.x / 2 * 2;
				v_offset = u_offset + 1;
			
			else 
				v_offset = (draw_point.y / 2) * width + draw_point.x / 2 * 2;
				u_offset = v_offset + 1;
			
			UVBuff[u_offset] = s_color_table[clrIdx].U;
			UVBuff[v_offset] = s_color_table[clrIdx].V;
			//printf("[%d, %d]: y_offset = %d, u_offset = %d, v_offset = %d\\n",
			//	draw_point.x, draw_point.y, y_offset, u_offset, v_offset);
		break;
		case TYPE_YUV444P:
		
			/*
				YYYYYYYY
				UUUUUUUU
				VVVVVVVV
			*/
			uInt32 y_offset = 0, u_offset = 0, v_offset = 0;
			uInt32 plane_size = width * height;
			y_offset = draw_point.y * width + draw_point.x;
			u_offset = y_offset;
			v_offset = plane_size + u_offset;
			YBuff[y_offset] = s_color_table[clrIdx].Y;
			UVBuff[u_offset] = s_color_table[clrIdx].U;
			UVBuff[v_offset] = s_color_table[clrIdx].V;
		break;
		case TYPE_YUV444I:
		
			/*
				YUV YUV YUV YUV YUV YUV YUV YUV
			*/
			uInt32 y_offset = 0, u_offset = 0, v_offset = 0;
			y_offset = draw_point.y * width * 3 + draw_point.x * 3;
			u_offset = y_offset + 1;
			v_offset = u_offset + 1;
			YBuff[y_offset] = s_color_table[clrIdx].Y;
			YBuff[u_offset] = s_color_table[clrIdx].U;
			YBuff[v_offset] = s_color_table[clrIdx].V;
		break;
		case TYPE_YUV422P:
		
			/*
				YYYYYYYY
				UUUU
				VVVV
			*/
			uInt32 y_offset = 0, u_offset = 0, v_offset = 0;
			uInt32 plane_size = width * height / 2;
			y_offset = draw_point.y * width + draw_point.x;
			u_offset = y_offset / 2;
			v_offset = plane_size + y_offset / 2;
			YBuff[y_offset] = s_color_table[clrIdx].Y;
			UVBuff[u_offset] = s_color_table[clrIdx].U;
			UVBuff[v_offset] = s_color_table[clrIdx].V;
		break;
		case TYPE_YUV420I:
		
			/*
				YYYYYYYY
				UU
				VV
			*/
			uInt32 y_offset = 0, u_offset = 0, v_offset = 0;
			uInt32 plane_size = width * height / 4;
			y_offset = draw_point.y * width + draw_point.x;
			u_offset = draw_point.y / 2 * width / 2 + draw_point.x/2;
			v_offset = u_offset + plane_size;
			YBuff[y_offset] = s_color_table[clrIdx].Y;
			UVBuff[u_offset] = s_color_table[clrIdx].U;
			UVBuff[v_offset] = s_color_table[clrIdx].V;
		break;
	


void yuv_drawline(stYuvBuffInfo *pYuvBuffInfo, stDrawLineInfo *pDrawLineInfo)

	if(!pYuvBuffInfo || !pYuvBuffInfo->pYuvBuff) return;

	uInt8 *YBuff = NULL, *UVBuff = NULL;
	if(pDrawLineInfo->lineWidth == 0) pDrawLineInfo->lineWidth = 1;
	
	uInt16 i = 0;
	for(i = 0; i < pDrawLineInfo->lineWidth; i++) 
		uInt16 x0 = pDrawLineInfo->startPoint.x, y0 = pDrawLineInfo->startPoint.y;
		uInt16 x1 = pDrawLineInfo->endPoint.x, y1 = pDrawLineInfo->endPoint.y;
		x0 = (x0 >= pYuvBuffInfo->width) ? (x0 - pDrawLineInfo->lineWidth) : x0;
		x1 = (x1 >= pYuvBuffInfo->width) ? (x1 - pDrawLineInfo->lineWidth) : x1;
		y0 = (y0 >= pYuvBuffInfo->height) ? (y0 - pDrawLineInfo->lineWidth) : y0;
		y1 = (y1 >= pYuvBuffInfo->height) ? (y1 - pDrawLineInfo->lineWidth) : y1;
		
		uInt16 dx = (x0 > x1) ? (x0 - x1) : (x1 - x0);
		uInt16 dy = (y0 > y1) ? (y0 - y1) : (y1 - y0);

		if(dx <= dy) 
			x0 += i;
			x1 += i;
		
		else 
			y0 += i;
			y1 += i;
		

		Int16 xstep = (x0 < x1) ? 1 : -1;
		Int16 ystep = (y0 < y1) ? 1 : -1;
		Int16 nstep = 0, eps = 0;

		stPoint draw_point;
		draw_point.x = x0;
		draw_point.y = y0;

		switch(pYuvBuffInfo->yuvType)
		
			case TYPE_YUV422I_UYVY:
			case TYPE_YUV422I_YUYV:
			case TYPE_YUV444I:
			
				YBuff = pYuvBuffInfo->pYuvBuff;
				UVBuff = NULL;
			break;
			case TYPE_YUV420SP_NV12:
			case TYPE_YUV420SP_NV21:
			case TYPE_YUV444P:
			case TYPE_YUV422P:
			case TYPE_YUV420I:
			
				YBuff = pYuvBuffInfo->pYuvBuff;
				UVBuff = pYuvBuffInfo->pYuvBuff + pYuvBuffInfo->width * pYuvBuffInfo->height;
			break;
			default:
				return;
		

		// 布雷森汉姆算法画线
		if(dx > dy)
			while(nstep <= dx) 
				yuv_setdata(YBuff, UVBuff, pYuvBuffInfo->yuvType, pYuvBuffInfo->width, pYuvBuffInfo->height, draw_point, pDrawLineInfo->clrIdx);
				eps += dy;
				if( (eps << 1) >= dx ) 
					draw_point.y += ystep;
					eps -= dx;
				
				draw_point.x += xstep;
				nstep++;
			
		else 
			while(nstep <= dy)	
				yuv_setdata(YBuff, UVBuff, pYuvBuffInfo->yuvType, pYuvBuffInfo->width, pYuvBuffInfo->height, draw_point, pDrawLineInfo->clrIdx);
				eps += dx;
				if( (eps << 1) >= dy ) 
					draw_point.x += xstep;
					eps -= dy;
				
				draw_point.y += ystep;
				nstep++;
			
		
	


void draw_rect(stYuvBuffInfo* yuvBuffInfo)

	stDrawLineInfo drawLineInfo;
	drawLineInfo.clrIdx = YUV_RED;
	drawLineInfo.lineWidth = 3;
	drawLineInfo.startPoint.x = 160;
	drawLineInfo.startPoint.y = 140;
	drawLineInfo.endPoint.x = 560;
	drawLineInfo.endPoint.y = 340;
	yuv_drawline(yuvBuffInfo, &drawLineInfo);

	drawLineInfo.clrIdx = YUV_PURPLE;
	drawLineInfo.lineWidth = 3;
	drawLineInfo.startPoint.x = 560;
	drawLineInfo.startPoint.y = 140;
	drawLineInfo.endPoint.x = 160;
	drawLineInfo.endPoint.y = 340;
	yuv_drawline(yuvBuffInfo, &drawLineInfo);

	drawLineInfo.clrIdx = YUV_YELLOW;
	drawLineInfo.lineWidth = 3;
	drawLineInfo.startPoint.x = 160;
	drawLineInfo.startPoint.y = 140;
	drawLineInfo.endPoint.x = 560;
	drawLineInfo.endPoint.y = 140;
	yuv_drawline(yuvBuffInfo, &drawLineInfo);

	drawLineInfo.clrIdx = YUV_GREEN;
	drawLineInfo.lineWidth = 3;
	drawLineInfo.startPoint.x = 160;
	drawLineInfo.startPoint.y = 140;
	drawLineInfo.endPoint.x = 160;
	drawLineInfo.endPoint.y = 340;
	yuv_drawline(yuvBuffInfo, &drawLineInfo);

	drawLineInfo.clrIdx = YUV_BLUE;
	drawLineInfo.lineWidth = 3;
	drawLineInfo.startPoint.x = 160;
	drawLineInfo.startPoint.y = 340;
	drawLineInfo.endPoint.x = 560;
	drawLineInfo.endPoint.y = 340;
	yuv_drawline(yuvBuffInfo, &drawLineInfo);

	drawLineInfo.clrIdx = YUV_WHITE;
	drawLineInfo.lineWidth = 3;
	drawLineInfo.startPoint.x = 560;
	drawLineInfo.startPoint.y = 140;
	drawLineInfo.endPoint.x = 560;
	drawLineInfo.endPoint.y = 340;
	yuv_drawline(yuvBuffInfo, &drawLineInfo);


void get_yuv_pixmap(stPixMapInfo *pPixmapInfo, stDrawLineInfo *pDrawLineInfo, uInt32 width, uInt32 height)

	if(!pPixmapInfo || !pPixmapInfo->pPixMapBuff) return;
	if(pDrawLineInfo->lineWidth == 0) pDrawLineInfo->lineWidth = 1;

	uInt16 i = 0;
	for(i = 0; i < pDrawLineInfo->lineWidth; i++) 
		uInt16 x0 = pDrawLineInfo->startPoint.x, y0 = pDrawLineInfo->startPoint.y;
		uInt16 x1 = pDrawLineInfo->endPoint.x, y1 = pDrawLineInfo->endPoint.y;
		x0 = (x0 >= width) ? (x0 - pDrawLineInfo->lineWidth) : x0;
		x1 = (x1 >= width) ? (x1 - pDrawLineInfo->lineWidth) : x1;
		y0 = (y0 >= height) ? (y0 - pDrawLineInfo->lineWidth) : y0;
		y1 = (y1 >= height) ? (y1 - pDrawLineInfo->lineWidth) : y1;

		uInt16 dx = (x0 > x1) ? (x0 - x1) : (x1 - x0);
		uInt16 dy = (y0 > y1) ? (y0 - y1) : (y1 - y0);

		if(dx <= dy) 
			x0 += i;
			x1 += i;
		
		else 
			y0 += i;
			y1 += i;
		
		//printf("(x0,y0)->(x1, y1) = (%d,%d)->(%d,%d)\\n", x0, y0, x1, y1);

		Int16 xstep = (x0 < x1) ? 1 : -1;
		Int16 ystep = (y0 < y1) ? 1 : -1;
		Int16 nstep = 0, eps = 0;

		stPoint draw_point;
		draw_point.x = x0;
		draw_point.y = y0;

		// 布雷森汉姆算法画线
		if(dx > dy)
			while(nstep <= dx) 
				pPixmapInfo->pPixMapBuff[pPixmapInfo->pixNums].x = draw_point.x;
				pPixmapInfo->pPixMapBuff[pPixmapInfo->pixNums].y = draw_point.y;
				pPixmapInfo->pPixMapBuff[pPixmapInfo->pixNums].color_idx = pDrawLineInfo->clrIdx;
				//printf("[%d](x, y) -> (%d, %d)\\n", pPixmapInfo->pixNums, 
				//	pPixmapInfo->pPixMapBuff[pPixmapInfo->pixNums].x,
				//	pPixmapInfo->pPixMapBuff[pPixmapInfo->pixNums].y);
				pPixmapInfo->pixNums++;
				
				eps += dy;
				if( (eps << 1) >= dx ) 
					draw_point.y += ystep;
					eps -= dx;
				
				draw_point.x += xstep;
				nstep++;
			
		else 
			while(nstep <= dy)	
				pPixmapInfo->pPixMapBuff[pPixmapInfo->pixNums].x = draw_point.x;
				pPixmapInfo->pPixMapBuff[pPixmapInfo->pixNums].y = draw_point.y;
				pPixmapInfo->pPixMapBuff[pPixmapInfo->pixNums].color_idx = pDrawLineInfo->clrIdx;
				//printf("[%d](x, y) -> (%d, %d)\\n", pPixmapInfo->pixNums, 
				//	pPixmapInfo->pPixMapBuff[pPixmapInfo->pixNums].x,
				//	pPixmapInfo->pPixMapBuff[pPixmapInfo->pixNums].y);
				pPixmapInfo->pixNums++;
				
				eps += dx;
				if( (eps << 1) >= dy ) 
					draw_point.x += xstep;
					eps -= dy;
				
				draw_point.y += ystep;
				nstep++;
			
		
	



void get_rect_pixmap(stPixMapInfo *pPixmapInfo, uInt32 width, uInt32 height, uInt16 lineWidth)

	stDrawLineInfo drawLineInfo;
	drawLineInfo.clrIdx = YUV_RED;
	drawLineInfo.lineWidth = lineWidth;
	drawLineInfo.startPoint.x = 160;
	drawLineInfo.startPoint.y = 140;
	drawLineInfo.endPoint.x = 560;
	drawLineInfo.endPoint.y = 340;
	get_yuv_pixmap(pPixmapInfo, &drawLineInfo, width, height);

	drawLineInfo.clrIdx = YUV_PURPLE;
	drawLineInfo.lineWidth = lineWidth;
	drawLineInfo.startPoint.x = 560;
	drawLineInfo.startPoint.y = 140;
	drawLineInfo.endPoint.x = 160;
	drawLineInfo.endPoint.y = 340;
	get_yuv_pixmap(pPixmapInfo, &drawLineInfo, width, height);

	drawLineInfo.clrIdx = YUV_YELLOW;
	drawLineInfo.lineWidth = lineWidth;
	drawLineInfo.startPoint.x = 160;
	drawLineInfo.startPoint.y = 140;
	drawLineInfo.endPoint.x = 560;
	drawLineInfo.endPoint.y = 140;
	get_yuv_pixmap(pPixmapInfo, &drawLineInfo, width, height);

	drawLineInfo.clrIdx = YUV_GREEN;
	drawLineInfo.lineWidth = lineWidth;
	drawLineInfo.startPoint.x = 160;
	drawLineInfo.startPoint.y = 140;
	drawLineInfo.endPoint.x = 160;
	drawLineInfo.endPoint.y = 340;
	get_yuv_pixmap(pPixmapInfo, &drawLineInfo, width, height);

	drawLineInfo.clrIdx = YUV_BLUE;
	drawLineInfo.lineWidth = lineWidth;
	drawLineInfo.startPoint.x = 160;
	drawLineInfo.startPoint.y = 340;
	drawLineInfo.endPoint.x = 560;
	drawLineInfo.endPoint.y = 340;
	get_yuv_pixmap(pPixmapInfo, &drawLineInfo, width, height);

	drawLineInfo.clrIdx = YUV_WHITE;
	drawLineInfo.lineWidth = lineWidth;
	drawLineInfo.startPoint.x = 560;
	drawLineInfo.startPoint.y = 140;
	drawLineInfo.endPoint.x = 560;
	drawLineInfo.endPoint.y = 340;
	get_yuv_pixmap(pPixmapInfo, &drawLineInfo, width, height);


void get_guideline_pixmap(stPixMapInfo *pPixmapInfo, uInt32 width, uInt32 height, uInt16 lineWidth)

	stDrawLineInfo drawLineInfo;
	// 绿线左斜线
	drawLineInfo.clrIdx = YUV_DARK_GREEN;
	drawLineInfo.lineWidth = lineWidth;
	drawLineInfo.startPoint.x = 200;
	drawLineInfo.startPoint.y = 100;
	drawLineInfo.endPoint.x = 170;
	drawLineInfo.endPoint.y = 150;
	get_yuv_pixmap(pPixmapInfo, &drawLineInfo, width, height);

	// 绿线右斜线
	drawLineInfo.clrIdx = YUV_DARK_GREEN;
	drawLineInfo.lineWidth = lineWidth;
	drawLineInfo.startPoint.x = 520;
	drawLineInfo.startPoint.y = 100;
	drawLineInfo.endPoint.x = 550;
	drawLineInfo.endPoint.y = 150;
	get_yuv_pixmap(pPixmapInfo, &drawLineInfo, width, height);

	// 绿线左横线
	drawLineInfo.clrIdx = YUV_DARK_GREEN;
	drawLineInfo.lineWidth = lineWidth;
	drawLineInfo.startPoint.x = 195;
	drawLineInfo.startPoint.y = 115;
	drawLineInfo.endPoint.x = 220;
	drawLineInfo.endPoint.y = 115;
	get_yuv_pixmap(pPixmapInfo, &drawLineInfo, width, height);

	// 绿线右横线
	drawLineInfo.clrIdx = YUV_DARK_GREEN;
	drawLineInfo.lineWidth = lineWidth;
	drawLineInfo.startPoint.x = 510;
	drawLineInfo.startPoint.y = 115;
	drawLineInfo.endPoint.x = 535;
	drawLineInfo.endPoint.y = 115;
	get_yuv_pixmap(pPixmapInfo, &drawLineInfo, width, height);

	// 黄线左斜线
	drawLineInfo.clrIdx = YUV_YELLOW;
	drawLineInfo.lineWidth = lineWidth;
	drawLineInfo.startPoint.x = 165;
	drawLineInfo.startPoint.y = 160;
	drawLineInfo.endPoint.x = 115;
	drawLineInfo.endPoint.y = 240;
	get_yuv_pixmap(pPixmapInfo, &drawLineInfo, width, height);

	// 黄线右斜线
	drawLineInfo.clrIdx = YUV_YELLOW;
	drawLineInfo.lineWidth = lineWidth;
	drawLineInfo.startPoint.x = 555;
	drawLineInfo.startPoint.y = 160;
	drawLineInfo.endPoint.x = 605;
	drawLineInfo.endPoint.y = 240;
	get_yuv_pixmap(pPixmapInfo, &drawLineInfo, width, height);

	// 黄线左横线
	drawLineInfo.clrIdx = YUV_YELLOW;
	drawLineInfo.lineWidth = lineWidth;
	drawLineInfo.startPoint.x = 155;
	drawLineInfo.startPoint.y = 180;
	drawLineInfo.endPoint.x = 205;
	drawLineInfo.endPoint.y = 180;
	get_yuv_pixmap(pPixmapInfo, &drawLineInfo, width, height);

	// 黄线右横线
	drawLineInfo.clrIdx = YUV_YELLOW;
	drawLineInfo.lineWidth = lineWidth;
	drawLineInfo.startPoint.x = 525;
	drawLineInfo.startPoint.y = 180;
	drawLineInfo.endPoint.x = 575;
	drawLineInfo.endPoint.y = 180;
	get_yuv_pixmap(pPixmapInfo, &drawLineInfo, width, height);

	// 红线左斜线
	drawLineInfo.clrIdx = YUV_RED;
	drawLineInfo.lineWidth = lineWidth;
	drawLineInfo.startPoint.x = 110;
	drawLineInfo.startPoint.y = 250;
	drawLineInfo.endPoint.x = 30;
	drawLineInfo.endPoint.y = 380;
	get_yuv_pixmap(pPixmapInfo, &drawLineInfo, width, height);

	// 红线右斜线
	drawLineInfo.clrIdx = YUV_RED;
	drawLineInfo.lineWidth = lineWidth;
	drawLineInfo.startPoint.x = 610;
	drawLineInfo.startPoint.y = 250;
	drawLineInfo.endPoint.x = 690;
	drawLineInfo.endPoint.y = 380;
	get_yuv_pixmap(pPixmapInfo, &drawLineInfo, width, height);

	// 红线左横线
	drawLineInfo.clrIdx = YUV_RED;
	drawLineInfo.lineWidth = lineWidth;
	drawLineInfo.startPoint.x = 85;
	drawLineInfo.startPoint.y = 300;
	drawLineInfo.endPoint.x = 165;
	drawLineInfo.endPoint.y = 300;
	get_yuv_pixmap(pPixmapInfo, &drawLineInfo, width, height);

	// 红线右横线
	drawLineInfo.clrIdx = YUV_RED;
	drawLineInfo.lineWidth = lineWidth;
	drawLineInfo.startPoint.x = 565;
	drawLineInfo.startPoint.y = 300;
	drawLineInfo.endPoint.x = 645;
	drawLineInfo.endPoint.y = 300;
	get_yuv_pixmap(pPixmapInfo, &drawLineInfo, width, height);



void draw_pixmap_data(stYuvBuffInfo *pYuvBuffInfo, stPixMapInfo *pPixmapInfo)

	uInt8 *YBuff = NULL, *UVBuff = NULL;
	switch(pYuvBuffInfo->yuvType)
	
		case TYPE_YUV422I_UYVY:
		case TYPE_YUV422I_YUYV:
		case TYPE_YUV444I:
		
			YBuff = pYuvBuffInfo->pYuvBuff;
			UVBuff = NULL;
		break;
		case TYPE_YUV420SP_NV12:
		case TYPE_YUV420SP_NV21:
		case TYPE_YUV444P:
		case TYPE_YUV422P:
		
			YBuff = pYuvBuffInfo->pYuvBuff;
			UVBuff = pYuvBuffInfo->pYuvBuff + pYuvBuffInfo->width * pYuvBuffInfo->height;
		break;
		default:
			return;
	

	uInt32 i = 0;
	for(i = 0; i < pPixmapInfo->pixNums; i++) 
		stPoint draw_point;
		draw_point.x = pPixmapInfo->pPixMapBuff[i].x;
		draw_point.y = pPixmapInfo->pPixMapBuff[i].y;
		yuv_setdata(YBuff, UVBuff, pYuvBuffInfo->yuvType, pYuvBuffInfo->width, pYuvBuffInfo->height, draw_point, pPixmapInfo->pPixMapBuff[i].color_idx);
	


void main(int argc, char** argv)

	stYuvBuffInfo yuvBuffInfo;
	uInt8 *pBuff = (uInt8*)malloc(sizeof(uInt8) * 10 * 0x100000); // 10M
	// 测试 NV12 格式
	Int32 size = read_file("yuv_data.nv12", pBuff);
	yuvBuffInfo.pYuvBuff = pBuff;
	yuvBuffInfo.width = 720;
	yuvBuffInfo.height = 480;
	yuvBuffInfo.yuvType = TYPE_YUV420SP_NV12;
	draw_rect(&yuvBuffInfo);
	FILE* fp_save = fopen("./yuv_data_line.nv12", "wb+");
	fwrite(pBuff, size, 1, fp_save);
	fclose(fp_save);

	// 测试UYVY 格式
	memset(pBuff, 0, sizeof(uInt8) * 10 * 0x100000);
	size = read_file("yuv_data.uyvy", pBuff);
	yuvBuffInfo.pYuvBuff = pBuff;
	yuvBuffInfo.width = 720;
	yuvBuffInfo.height = 480;
	yuvBuffInfo.yuvType = TYPE_YUV422I_UYVY;
	draw_rect(&yuvBuffInfo);
	fp_save = fopen("./yuv_data_line.uyvy", "wb+");
	fwrite(pBuff, size, 1, fp_save);

	// 测试 NV21 格式
	size = read_file("yuv_data.nv21", pBuff);
	yuvBuffInfo.pYuvBuff = pBuff;
	yuvBuffInfo.width = 720;
	yuvBuffInfo.height = 480;
	yuvBuffInfo.yuvType = TYPE_YUV420SP_NV21;
	draw_rect(&yuvBuffInfo);
	fp_save = fopen("./yuv_data_line.nv21", "wb+");
	fwrite(pBuff, size, 1, fp_save);
	fclose(fp_save);

	// 测试YUYV 格式
	memset(pBuff, 0, sizeof(uInt8) * 10 * 0x100000);
	size = read_file("yuv_data.yuyv", pBuff);
	yuvBuffInfo.pYuvBuff = pBuff;
	yuvBuffInfo.width = 720;
	yuvBuffInfo.height = 480;
	yuvBuffInfo.yuvType = TYPE_YUV422I_YUYV;
	draw_rect(&yuvBuffInfo);
	fp_save = fopen("./yuv_data_line.yuyv", "wb+");
	fwrite(pBuff, size, 1, fp_save);

	// 测试YUV444P 格式
	memset(pBuff, 0, sizeof(uInt8) * 10 * 0x100000);
	size = read_file("yuv_data.yuv444p", pBuff);
	yuvBuffInfo.pYuvBuff = pBuff;
	yuvBuffInfo.width = 720;
	yuvBuffInfo.height = 480;
	yuvBuffInfo.yuvType = TYPE_YUV444P;
	draw_rect(&yuvBuffInfo);
	fp_save = fopen("./yuv_data_line.yuv444p", "wb+");
	fwrite(pBuff, size, 1, fp_save);

	// 测试YUV444I 格式
	memset(pBuff, 0, sizeof(uInt8) * 10 * 0x100000);
	size = read_file("yuv_data.yuv444i", pBuff);
	yuvBuffInfo.pYuvBuff = pBuff;
	yuvBuffInfo.width = 720;
	yuvBuffInfo.height = 480;
	yuvBuffInfo.yuvType = TYPE_YUV444I;
	draw_rect(&yuvBuffInfo);
	fp_save = fopen("./yuv_data_line.yuv444i", "wb+");
	fwrite(pBuff, size, 1, fp_save);

	// 测试YUV422P 格式
	memset(pBuff, 0, sizeof(uInt8) * 10 * 0x100000);
	size = read_file("yuv_data.yuv422p", pBuff);
	yuvBuffInfo.pYuvBuff = pBuff;
	yuvBuffInfo.width = 720;
	yuvBuffInfo.height = 480;
	yuvBuffInfo.yuvType = TYPE_YUV422P;
	draw_rect(&yuvBuffInfo);
	fp_save = fopen("./yuv_data_line.yuv422p", "wb+");
	fwrite(pBuff, size, 1, fp_save);

	// 测试YUV420I 格式
	memset(pBuff, 0, sizeof(uInt8) * 10 * 0x100000);
	size = read_file("yuv_data.yuv420i", pBuff);
	yuvBuffInfo.pYuvBuff = pBuff;
	yuvBuffInfo.width = 720;
	yuvBuffInfo.height = 480;
	yuvBuffInfo.yuvType = TYPE_YUV420I;
	draw_rect(&yuvBuffInfo);
	fp_save = fopen("./yuv_data_line.yuv420i", "wb+");
	fwrite(pBuff, size, 1, fp_save);

	// 测试 YUV pixmap 结构
	stPixMapInfo pixMapInfo;
	pixMapInfo.pixNums = 0;
	pixMapInfo.pPixMapBuff = (stYuvPixMap*)malloc(sizeof(stYuvPixMap) * 720 * 480 * 4);
	get_rect_pixmap(&pixMapInfo, 720, 480, 10);
	printf("get pix num = %d\\n", pixMapInfo.pixNums);

	memset(pBuff, 0, sizeof(uInt8) * 10 * 0x100000);
	size = read_file("yuv_data.yuyv", pBuff);
	yuvBuffInfo.pYuvBuff = pBuff;
	yuvBuffInfo.width = 720;
	yuvBuffInfo.height = 480;
	yuvBuffInfo.yuvType = TYPE_YUV422I_YUYV;
	draw_pixmap_data(&yuvBuffInfo, &pixMapInfo);
	fp_save = fopen("./yuv_data_pixmap.yuyv", "wb+");
	fwrite(pBuff, size, 1, fp_save);

	// 测试 倒车辅助线 YUYV
	pixMapInfo.pixNums = 0;
	get_guideline_pixmap(&pixMapInfo, 720, 480, 10);
	printf("get pix num = %d\\n", pixMapInfo.pixNums);

	memset(pBuff, 0, sizeof(uInt8) * 10 * 0x100000);
	size = read_file("yuv_data.yuyv", pBuff);
	yuvBuffInfo.pYuvBuff = pBuff;
	yuvBuffInfo.width = 720;
	yuvBuffInfo.height = 480;
	yuvBuffInfo.yuvType = TYPE_YUV422I_YUYV;
	draw_pixmap_data(&yuvBuffInfo, &pixMapInfo);
	fp_save = fopen("./yuv_data_guideline.yuyv", "wb+");
	fwrite(pBuff, size, 1, fp_save);

	// 测试 倒车辅助线 NV12
	pixMapInfo.pixNums = 0;
	get_guideline_pixmap(&pixMapInfo, 720, 480, 10);
	printf("get pix num = %d\\n", pixMapInfo.pixNums);

	memset(pBuff, 0, sizeof(uInt8) * 10 * 0x100000);
	size = read_file("yuv_data.nv12", pBuff);
	yuvBuffInfo.pYuvBuff = pBuff;
	yuvBuffInfo.width = 720;
	yuvBuffInfo.height = 480;
	yuvBuffInfo.yuvType = TYPE_YUV420SP_NV12;
	draw_pixmap_data(&yuvBuffInfo, &pixMapInfo);
	fp_save = fopen("./yuv_data_guideline.nv12", "wb+");
	fwrite(pBuff, size, 1, fp_save);

	// 测试 倒车辅助线 YUV444P
	pixMapInfo.pixNums = 0;
	get_guideline_pixmap(&pixMapInfo, 720, 480, 10);
	printf("get pix num = %d\\n", pixMapInfo.pixNums);

	memset(pBuff, 0, sizeof(uInt8) * 10 * 0x100000);
	size = read_file("yuv_data.yuv444p", pBuff);
	yuvBuffInfo.pYuvBuff = pBuff;
	yuvBuffInfo.width = 720;
	yuvBuffInfo.height = 480;
	yuvBuffInfo.yuvType = TYPE_YUV444P;
	draw_pixmap_data(&yuvBuffInfo, &pixMapInfo);
	fp_save = fopen("./yuv_data_guideline.yuv444p", "wb+");
	fwrite(pBuff, size, 1, fp_save);

	// 测试 倒车辅助线 YUV422P
	pixMapInfo.pixNums = 0;
	get_guideline_pixmap(&pixMapInfo, 720, 480, 10);
	printf("get pix num = %d\\n", pixMapInfo.pixNums);

	memset(pBuff, 0, sizeof(uInt8) * 10 * 0x100000);
	size = read_file("yuv_data.yuv422p", pBuff);
	yuvBuffInfo.pYuvBuff = pBuff;
	yuvBuffInfo.width = 720;
	yuvBuffInfo.height = 480;
	yuvBuffInfo.yuvType = TYPE_YUV422P;
	draw_pixmap_data(&yuvBuffInfo, &pixMapInfo);
	fp_save = fopen("./yuv_data_guideline.yuv422p", "wb+");
	fwrite(pBuff, size, 1, fp_save);
	
	fclose(fp_save);
	free(pBuff);
	free(pixMapInfo.pPixMapBuff);

	system("sync");
	return;

划线效果:

 

线宽为3个像素 NV12格式的效果:

倒车辅助线 NV12格式:

 

以上是关于学习记录:各种YUV图像上画线的实现的主要内容,如果未能解决你的问题,请参考以下文章

怎么在ARCGIS中国地图上画线

怎么在ARCGIS中国地图上画线

如何在谷歌地图上画线

JQuery在画布图像上画线并重置线而不影响图像

MFC,如何在图片控件上边画线

MFC画线功能总结