c 在文本终端中显示yuv图片

把yuv422 转为rgb32 ,利用framebuffer 显示

经实验,可以显示任意尺寸大小的yuv图片

再利用此基础,就可以在文本终端中显示yuyv

格式的视频。

特别要注意:1:YUYV  是4字节存储两个像素,UV 这两个字节共用

                      2:YUYV422   二字节中的低字节代表Y,高为U  或者V

                      3:RGB32  :是4字节,低字节为B,第2为G,第3为R,第4为空



#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include   //v4l2 头文件
#include 
#include 
#include 

#define  pic_width   640        //1280*720  640*480  960*540
#define  pic_heigth  480
#define  pic_path   "/home/wjs/Pictures/my.yuv"

#define WT  10    //如果图片是斜的,微调此值

static int color1=0; 
static int color2=0;
static	int sp[3000*2000];             //取摄像头最大尺寸
static struct fb_var_screeninfo var;

int main(void)
{
	FILE *f=fopen(pic_path,"r+b");
	if(f==NULL){
		puts("file error");
		exit(-1);
	}
	fseek(f,0,SEEK_END);
	int len=ftell(f);
	fseek(f,0,SEEK_SET);
	
	int fd=fileno(f);
	char *p1=mmap(NULL,len,PROT_READ,MAP_SHARED,fd,0);
	
	char (*p)[4]=(char (*)[4])p1;    //   p[][0]=Y   p[][1]=U  p[][2]=Y  p[][3]=V
	//R = Y + 1.4075 *(V-128)
	//G = Y – 0.3455 *(U –128) – 0.7169 *(V –128) 
	//	B = Y + 1.779 *(U – 128)
	
		
	int t=0;
	int u=0;
	while(1){
		if(4*t>=len){
			break;
		}
		int Y1=(unsigned char)p[t][0];
		if((4*t+1)>=len){
			break;
		}
		int U=(unsigned char)p[t][1];
		if((4*t+2)>=len){
			break;
		}
		int Y2=(unsigned char)p[t][2];
		if((4*t+3)>=len){
			break;
		}
		int V=(unsigned char)p[t][3];
		//-------------------------------------------------	
		int B0=Y1+1.779*(U-128);
		if(B0>255)  B0=255;
		if(B0<0)    B0=0;
		
		int G0=Y1-0.3455*(U-128)-0.7169*(V-128);
		if(G0>255)  G0=255;
		if(G0<0)    G0=0;
		
		int R0=Y1+1.4075*(V-128);
		if(R0>255)  R0=255;
		if(R0<0)    R0=0;
		
		int B1=Y2+1.779*(U-128);
		if(B1>255)  B1=255;
		if(B1<0)    B1=0;
		
		int G1=Y2-0.3455*(U-128)-0.7169*(V-128);
		if(G1>255)  G1=255;
		if(G1<0)    G1=0;
		
		int R1=Y2+1.4075*(V-128);
		if(R1>255)  R1=255;
		if(R1<0)    R1=0;
		
		color1=(R0<<16)|(G0<<8)|B0;
		color2=(R1<<16)|(G1<<8)|B1;
		
		sp[u]=color1;
		sp[u+1]=color2;
		
		t++;
		u=u+2;
		
	}
	munmap(p1,len);
	puts("yuyv over");
	
	//--------------------------------
	int fd_fb = open("/dev/fb0", O_RDWR);
	if (fd_fb < 0)
	{
		puts("/dev/fb0 error");
		return -1;
	}
	if (ioctl(fd_fb, FBIOGET_VSCREENINFO, &var))
	{
		puts("ioctl error");
		return -1;
	}
	
//	unsigned int  pixel_width = var.bits_per_pixel / 8;                  //deepin=32
	int screen_size = var.xres * var.yres * var.bits_per_pixel / 8;     //刚好等于图片的长乘宽
	
	unsigned char *fb_base = mmap(NULL, screen_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd_fb, 0);
	if (fb_base == NULL)
	{
		puts("mmap error");
		return -1;
	}
	memset(fb_base,0, screen_size);     //设底色为黑色
	
	int zz=0;
	var.xres=var.xres+WT;            //如果图片是斜的,微调WT的值
	for(int a=0;a

你可能感兴趣的:(c语言,开发语言)