jpg图片在开发板上显示
文件IO项目:
	在开发板屏幕上循环显示目录里的图片
	a.按照一定的间隔循环显示目录里的bmp图片
	b.实现手指滑动来显示目录里的图片(bmp,jpg)上一张,下一张
	
	
	d1:
		1.能操控屏幕(查询开发板屏幕分辨率,以及每个像素点占几个字节)
			 命令:FBIOGET_VSCREENINFO
			 查询结果保存在些结构中:
			 struct fb_var_screeninfo fbinfo;
				__u32 xres;       屏幕分辨率
				__u32 yres;
				__u32 bits_per_pixel; 每个像素点占多少位      /* guess what           */
			 ioctl(fd,FBIOGET_VSCREENINFO,&fbinfo);
			1.control device
			控制设备
			int ioctl(int fd, int request, ...);
			fd:文件描述符,表示要操作的设备
			request:一般表示一个命令号,该命令由驱动开发者提供
			...:其它参数,不同的命令参数是不一样的,也由驱动程序员提供
			
			返回值:返回0
					失败-1
	------------------------------------------------				
			2.功能:映射一个文件或设备到内存,实现像操作普通内存一样去操作文件或设备
			void *mmap(
				void *addr, 把文件内容映射到内存哪个地址,给NULL,让操作系统自动分配
				size_t length,要映射的文件内容的长度
				int prot, 映射的内存区域的权限
							PROT_EXEC  可执行
							PROT_READ  可读
							PROT_WRITE 可写
				int flags,映射标志,决定对映射部分的操作是否对其它进程可见
						MAP_SHARED:共享的,对其它进程可见,内存操作直接应用到文件中去
						MAP_PRIVATE:私有的,对其它进程不可见,内存操作不应用到文件中去
					
				int fd,文件描述符,要映射的文件
				off_t offset 偏移量,表示文件从哪个位置开始映射
			);
				
			返回值:成功返回映射内存区域的首地址
					失败返回 MAP_FAILED(-1),同时errno被设置
		  
				  
			int munmap(void *addr, size_t length);
				功能:解除映射
				addr:mmap的返回值
				length:映射内存的长度
				
				返回值:成功返回0
						失败返回-1
				
					
			
		
	void *memset(void *s, int c, size_t n);
		s:要设置的内存首地址
		c:要设置的内容
		n:长度
		
		//struct student s;
		//memset(&s,0,sizeof(s));
		 //void *memcpy(void *dest, const void *src, size_t n);
		 
		memcpy(addr,gImage_cat2,800*480*4);
		
	
		2.显示图片
		
		
	
-----------------------------------------
Linux Frame Buffer:
	帧缓冲设备:
		是对具体图像硬件的一个抽像,它让上层图像应用程序不必关心具体的硬件实现细节。
		在内存(显存)中开辟一段空间,用来保存在屏幕上像素点的颜色值,然后操作屏幕就直接操作这段内存就可以了,这就是说的帧缓冲。
		
		LCD显示原理:
			屏幕是由y行且每行x个像素点的矩阵组成
			在屏幕上显示图像就是给每个像素点显示一个颜色。
		
		帧缓冲设备操作流程:
			1.open打开设备
			2.ioctl获取屏幕信息
			3.mmap映射设备到内存
			4.操作显存
			5.munmap解除映射
			6.close关闭文件
			
1.显示jpg图片
	libjpeg移植:
		1.解压
			tar xvf jpegsrc.v8a.tar.gz 
		2.cd jpeg-8a/
		3.配置参数(生成Makefile)
			./configure --host=arm-linux --target=arm-linux --prefix=/usr/local/libjpeg-8a CC=arm-linux-gcc
			(
				注:
				如果没有建立交叉编译工具软链接的同学请用这个
				CC=arm-none-linux-gnueabi-gcc
			)
			
		4.make  
		5.sudo make install
			注:
				sudo make install时可能出现以下错误
				./libtool: line 950: arm-linux-ranlib: command not found
				解决方法:
					sudo -s
					export PATH=$PATH:/usr/local/arm/arm-2009q3/bin
					重新执行以下命令
					make install
		6.把生成库文件打包下载到开发板
			cd /usr/local/libjpeg-8a
			tar zcvf libjpeg-8a.tar.gz lib/
			
		7.在开发板上解压刚下载的包
			tar xvf libjpeg-8a.tar.gz
			cd lib/
			cp libjpeg.* /lib/
			
			
	arm-linux-gcc test_jpeg.c -o test_jpeg2 
	-ljpeg //指定链接的库名  
	-I /usr/local/libjpeg-8a/include/ //指定头文件存放路径
	-L /usr/local/libjpeg-8a/lib/		//指定库文件存放路径
		
	
	
	
-------------------------			
	tftp用法:
		1.乌班图下启动服务
			
		sudo service tftpd-hpa restart 
			[sudo] password for csgec: 
			tftpd-hpa stop/waiting
			tftpd-hpa start/running, process 15716
			
		2.tftp -g -r filename 主机IP
			(timeout)
				如果超时,请检查网络是否畅通
				从主机ping开发板
				从开发板ping主机
				检查开发板和主机是否在同一网段
				如果是笔记本,把无线网卡先断开
				
--------------------------------------
输入事件:
	鼠标事件
	键盘事件
	触屏事件
	...
	#include <linux/input.h>
		一般触屏分为是否按下,用压力值来区分,当压力值为0时表示没按下
		触屏事件使用的是绝对坐标(包括x和y)
	struct input_event {
       struct timeval time;//该事件发生的时间
		__u16 type;//事件类型
				EV_KEY          0x01 键盘事件
				EV_REL          0x02 鼠标事件	
				EV_ABS          0x03 触摸事件
		__u16 code;//根据事件类型同,含义不同
				if type == EV_KEY
					code 为键盘的键值
				if type = EV_REL
					code 为坐标轴 REL_X REL_Y
				if type = EV_ABS
					code 为坐标轴 ABS_X ABS_Y ABS_PRESSURE(压力)
		__s32 value;//根据事件类型同,含义不同
				if type == EV_KEY
					value 1 / 0 表示按键up/down
				if type = EV_REL
					value表示相应的坐标轴的偏移
				if type = EV_ABS
					value表示相应的坐标轴的绝对坐标
					X:(1-800)
					Y:(1-480)
					压力值:200 或 0(表示没按下)
						
   }; 	   
		
	#define ABS_PRESSURE        0x18//表示压力值
	
	获取起点和终点
	起点:按下去就可获取
	终点:当压力值为0时,也就是松开时的那个坐标值
		终点-起点 > 50
	
#include<stdio.h>
#include<linux/input.h>
#include<fcntl.h>
int main(int argc,char **argv)
{
	int fd = open("/dev/event0",O_RDONLY);
	if(fd < 0)
	{
		perror("open");
		return -1;
	}
	struct input_event ev;
	int r;
	while(1)
	{
		r = read(fd,&ev,sizeof(ev));
		if(r == sizeof(ev))
		{
			printf("type = %x,code = %x,value = %x\n",ev.type,ev.code,ev.value);
		}
		/*
		if(ev.type == EV_ABS && ev.code == ABS_PRESSURE)
		{
			printf("value = %d\n",ev.value);
		}
		
		if(ev.type == EV_ABS && ev.code == ABS_X)
		{
		
			printf("value = %d\n",ev.value);
		
		}
		*/
	}
	return 0;
}
/*************************************************************************
	> File Name: test_jpeg.c
	> Author: csgec
	> Mail: longer.zhou@gmail.com 
	> Created Time: Thu 04 Aug 2016 10:57:30 AM CST
 ************************************************************************/
#include<stdio.h>
#include<jpeglib.h>
#include<fcntl.h>
#include<sys/mman.h>
#include<stdlib.h>
void lcdDraw_point(int *p,int x,int y,int color)
{
	*(p + 800*y + x) = color;
}
int main(int argc,char ** argv)
{
	//1
		int fb = open("/dev/fb0",O_RDWR);
		if(fb < 0)
		{
			perror("open");
			return -1;
		}
	//2
		void *addr = mmap(0,800*480*4,PROT_READ|PROT_WRITE,MAP_SHARED,fb,0);
		if(addr == MAP_FAILED)
		{
			perror("mmap");
			return -1;
		}
//-----------利用libjpeg解压jpeg文件的步骤--------------------------------
	//1.分配并初始化一个jpeg解压对象
	printf("start jpeg\n");
	struct jpeg_decompress_struct cinfo;
	struct jpeg_error_mgr jerr;
	cinfo.err = jpeg_std_error(&jerr);
	jpeg_create_decompress(&cinfo);
	//2.指定要解压的文件
	FILE *infile;
	infile = fopen(argv[1],"r");
	if(infile == NULL)
	{
		fprintf(stderr, "can't open %s\n", argv[1]);
		return -1;
	}
	jpeg_stdio_src(&cinfo, infile);
	//3.获取图片信息
	jpeg_read_header(&cinfo, TRUE);
	//4.启动解压过程,cinfo中下面几个成员会比较有用
	//cinfo.output_width  宽_
	//cinfo.output_height	高
	//cinfo.output_components	像素分量(一个像素点占几个字节)
	//cinfo.
	jpeg_start_decompress(&cinfo);
	
	//5.读取一行扫描线数据并处理,通常的代码是这样的
	//成功后buffer里保存的就是解压后的行像素点的数据
	//R G B 从上到下,从左到右
	unsigned char *buffer = malloc(cinfo.output_width * cinfo.output_components);
	printf("start scanline\n");
	while(cinfo.output_scanline < cinfo.output_height)
	{
		jpeg_read_scanlines(&cinfo,
				&buffer,//保存解压后的数据的二级指针
				1//扫描的行数
				);
	int x,color;
	unsigned char r,g,b;
	unsigned char *p  = buffer;
	for(x = 0; x < 800; x++)
	{
		r = *p++;
		g = *p++;
		b = *p++;
		color = (r << 16) | (g << 8) | b;
		lcdDraw_point(addr,x,cinfo.output_scanline-1,color);
//	int y = cinfo.output_scanline-1;	
//	int *pf = (int*)addr;
//	*(pf + 800*y + x) = color;
	}
	
	}
	printf("finish decompress\n");
	//6.完成解压过程
	jpeg_finish_decompress(&cinfo);
	//7.释放资源
	jpeg_destroy_decompress(&cinfo);
	fclose(infile);
	close(fb);
return 0;
}
/*************************************************************************
  > File Name: test_jpeg.c
  > Author: csgec
  > Mail: longer.zhou@gmail.com 
  > Created Time: Thu 04 Aug 2016 10:57:30 AM CST
 ************************************************************************/
#include<stdio.h>
#include<jpeglib.h>
#include<fcntl.h>
#include<sys/mman.h>
#include<stdlib.h>
void draw_point(int *p,int x,int y,int color)
{
		int *pf = p + (800*y + x);
			*pf = color;
}
int main(int argc,char ** argv)
{
	//1
	int fb = open("/dev/fb0",O_RDWR);
	if(fb < 0)
	{
		perror("open");
		return -1;
	}
	//2
	void *addr = mmap(0,800*480*4,PROT_READ|PROT_WRITE,MAP_SHARED,fb,0);
	if(addr == MAP_FAILED)
	{
		perror("mmap");
		return -1;
	}
	//-----------利用libjpeg解压jpeg文件的步骤--------------------------------
	//1.分配并初始化一个jpeg解压对象
	printf("start jpeg\n");
	struct jpeg_decompress_struct cinfo;
	struct jpeg_error_mgr jerr;
	cinfo.err = jpeg_std_error(&jerr);
	jpeg_create_decompress(&cinfo);
	//2.指定要解压的文件
	FILE *infile;
	infile = fopen(argv[1],"r");
	if(infile == NULL)
	{
		fprintf(stderr, "can't open %s\n", argv[1]);
		return -1;
	}
	jpeg_stdio_src(&cinfo, infile);
	//3.获取图片信息
	jpeg_read_header(&cinfo, TRUE);
	//4.启动解压过程,cinfo中下面几个成员会比较有用
	//cinfo.output_width  宽_
	//cinfo.output_height	高
	//cinfo.output_components	像素分量(一个像素点占几个字节)
	//cinfo.
	jpeg_start_decompress(&cinfo);
	//5.读取一行扫描线数据并处理,通常的代码是这样的
	//成功后buffer里保存的就是解压后的行像素点的数据
	//R G B 从上到下,从左到右
	unsigned char *buffer = malloc(cinfo.output_width * cinfo.output_components);
	printf("start scanline\n");
	while(cinfo.output_scanline < cinfo.output_height)
	{
		jpeg_read_scanlines(&cinfo,
				&buffer,//保存解压后的数据的二级指针
				1//扫描的行数
				);
		int x,color;
		unsigned char r,g,b;
		unsigned char *p  = buffer;
		for(x = 0; x < 800; x++)
		{
			r = *p++;
			g = *p++;
			b = *p++;
			color = (r << 16) | (g << 8) | b;
				draw_point(addr,x,cinfo.output_scanline-1,color);
			/*
			int y = cinfo.output_scanline-1;	
			int *pf = (int*)addr;
			*(pf + 800*y + x) = color;
			*/
		}
	}
	printf("finish decompress\n");
	//6.完成解压过程
	jpeg_finish_decompress(&cinfo);
	//7.释放资源
	jpeg_destroy_decompress(&cinfo);
	fclose(infile);
	close(fb);
return 0;
}
 
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号