一、要显示JPEG 图片就必须要把jpeg个解码成bmp,那么我们就需要用到官方的jpeg解码库:
http://www.ijg.org/ 下载地址
1.移植jpeg源码变成arm版本的解码库
把源码拷贝到家目录,因为共享目录不支持链接文件!!
cp jpegsrc.v8a.tar.gz /home/honghai
解压源码
tar -xvf jpegsrc.v8a.tar.gz
2.交叉编译jpeg源码
新建文件夹libjpeg用来装库
//进入到源码目录:cd jpeg-8a
//配置编译脚本
./configure --host=arm-linux --target=arm-linux --prefix=/home/honghai/libjpeg CC=arm-linux-gcc
//参数说明:
–host 运行的平台
–target 目标文件的平台
–prefix 生成的库文件路径
CC= 编译工具的名称
3.编译工具的名称
make
4.安装
make install
5. 把编译生成的库移植到开发板中:
libjpeg.so
libjpeg.so.8
libjpeg.so.8.0.1
下载到开发板的lib目录
编译命令:
arm-linux-gcc jpeg_show.c -o jpeg_show -I/home/gec/jpeg_arm_lib/include -L/home/gec/jpeg_arm_lib/lib -ljpeg(arm-linux-gcc c文件 -o 目标文件 -ljpeg)
二、配置freetype字库需要freetyp文件压缩包(和jpeg步骤一致)
1.移植freetype源码变成arm版本的解码库
把源码拷贝到家目录,因为共享目录不支持链接文件!!
cp freetype-2.4.10.tar.bz2 /home/honghai
解压源码
tar -xvf freetype-2.4.10.tar.bz2
2.交叉编译jpeg源码
新建文件夹libjpeg用来装库
//进入到源码目录:cd freetype-2.4.10/
//配置编译脚本
./configure --host=arm-linux --target=arm-linux --prefix=/home/honghai/libfreetype CC=arm-linux-gcc
//参数说明:
–host 运行的平台
–target 目标文件的平台
–prefix 生成的库文件路径
CC= 编译工具的名称
3.安装
make install
4. 把编译生成的库移植到开发板中:
把libfreetype/lib压缩打包都开发板根目录
a.下载lib_zi.tar.bz 到开发板的根目录 /
cd /
tar -xjvf lib_zi.tar.bz
b.下载 宋体GKB码 字体集到根目录 /
simsun.ttc
下载到开发板的lib目录
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#include <string.h>
#include <stdio.h>
#include "kernel_list.h"
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <linux/input.h> //输入模型的定义
#include "lcd_app.h"
int *lcd=NULL;
//定义大结构体
struct big_list
{
char name[1024];
struct list_head list;
};
//把头结点定义为全局变量
struct list_head *head=NULL;
//插入新节点
void my_inser(char *picname)
{
//指向头节点
struct list_head *h=head;
struct big_list *new = ( struct big_list*)malloc(sizeof( struct big_list));
//new->name = picname;
strcpy(new->name,picname); //把路径赋值到数据域
//插入新节点
list_add_tail(&new->list,h);
}
//判断文件后缀
void get_type(char *path,char *dirpath)
{
//判断传递过来的图片格式什么格式
char name[1024]={0};
sprintf(name,"%s/%s",dirpath,path);
int len = strlen(name);
//判断.jpg
if(name[len-1] == 'g' && \
name[len-2] == 'p' && \
name[len-3] == 'j' && \
name[len-4] == '.' )
{
// printf("path=%s\n",name);
my_inser(name); //插入数据到链表中
}
//判断.bmp
if(name[len-1] == 'p' && \
name[len-2] == 'm' && \
name[len-3] == 'b' && \
name[len-4] == '.' )
{
// printf("path=%s\n",name);
my_inser(name);
}
}
//显示24位 bmp图片
int showbmp(const char *pic)
{
//打开图片文件
int bmpfd = open(pic,O_RDWR);
if(bmpfd < 0)
{
perror("");
return -1;
}
//读取图片的头信息
unsigned char head[54]={0};
read(bmpfd,head,54);
//解析宽高
int kuan = *((int *)&head[18]);
int gao = *((int *)&head[22]);
printf("kuan = %d\n",kuan);
printf("gao = %d\n",gao);
//变长数组
int buf[gao][kuan];//32位图的buf
char tmp_buf[gao*kuan*3]; //24位图的buf
//读取文件的数据到 buf中
read(bmpfd,tmp_buf,sizeof(tmp_buf));
unsigned char r=0;
unsigned char g=0;
unsigned char b=0;
unsigned char a=0;
unsigned char *p = tmp_buf;
unsigned int color = 0;
unsigned int x=0,y=0;
for(y=0;y<gao;y++)
for(x=0;x<kuan;x++)
{
b = *p++;
g = *p++;
r = *p++;
a = 0;
color = a << 24 | r << 16 | g << 8 | b;
buf[y][x] = color;//保存颜色值
//把图片的像素点赋值到lcd设备中
//边界判断
int tmpy = gao-1-y;
if(tmpy < 480 && x < 800) //越界了
{
*(lcd+tmpy*800+x) = buf[y][x]; //显示颜色值
}
}
//关闭所有设备
close(bmpfd);
}
int slide()
{
//打开触摸屏设备
int tsfd = open("/dev/input/event0",O_RDWR);
if(tsfd < 0)
{
perror("");
return -1;
}
int x=0,xx=0,y=0,yy=0;
//读取触摸屏的事件值
struct input_event ts; //定义输入系统模型
while(1)
{
read(tsfd,&ts,sizeof(ts));
//处理信息
if(ts.type == EV_ABS && ts.code == ABS_X)
{
//输出X轴的坐标值
x = ts.value;
}
if(ts.type == EV_ABS && ts.code == ABS_Y)
{
//输出X轴的坐标值
y = ts.value;
}
//获取Y轴的坐标点
if(ts.type == EV_KEY && ts.code == BTN_TOUCH && ts.value == 1)
{
//输出X轴的坐标值
xx = x;
yy = y;
printf("xx=%d,yy=%d\n",xx,yy);
}
if(ts.type == EV_KEY && ts.code == BTN_TOUCH && ts.value == 0)
{
//输出X轴的坐标值
printf("x=%d,y=%d\n",x,y);
printf("xx-x=%d,yy-y=%d\n",xx-x,yy-y);
//消除抖动
if(xx-x < -20)
{
return 1;
printf("右\n");
}
if(xx - x > 20)
{
return 2;
printf("左\n");
}
//把上下 也判断出来
if(yy-y < -20)
{
return 3;
printf("下\n");
}
if(yy-y > 20)
{
return 4;
printf("上\n");
}
//清空数据
x = 0;
y = 0;
xx = 0;
yy = 0;
printf("****************************************\n");
}
}
}
//遍历链表显示数据
void show_date(int *lcd_p)
{
//3.遍历链表输出数据
struct list_head *pos = head;
int num=0;
while(1)
{
num = slide();
switch(num)
{
case 1:
{
//取数据 tmp 保存大结构体的首地址
pos=pos->next;
struct big_list *tmp = list_entry(pos,struct big_list,list);
printf("tmp->date = %s\n",tmp->name);
//判断图片格式
int len = strlen(tmp->name);
//判断.jpg
if(tmp->name[len-1] == 'g' && \
tmp->name[len-2] == 'p' && \
tmp->name[len-3] == 'j' && \
tmp->name[len-4] == '.' )
{
// printf("path=%s\n",name);
read_JPEG_file(tmp->name);
}
//判断.bmp
if(tmp->name[len-1] == 'p' && \
tmp->name[len-2] == 'm' && \
tmp->name[len-3] == 'b' && \
tmp->name[len-4] == '.' )
{
// printf("path=%s\n",name);
showbmp(tmp->name);
}
//显示单个汉子
unsigned char c='A';
//lcd_put_ascii(lcd_p,100,100,c);
//wchar_t *wtext 宽字符
wchar_t *p = L"我想你";
Lcd_Show_FreeType(lcd_p,p,64,0x00ff00,1,0,100,200);
wchar_t *p0 = L"我好饿";
Lcd_Show_FreeType(lcd_p,p0,64,0x00ff00,0,0,100,300);
break;
}
case 2:
{
//取数据 tmp 保存大结构体的首地址
pos=pos->prev;
struct big_list *tmp = list_entry(pos,struct big_list,list);
printf("tmp->date = %s\n",tmp->name);
//判断图片格式
int len = strlen(tmp->name);
//判断.jpg
if(tmp->name[len-1] == 'g' && \
tmp->name[len-2] == 'p' && \
tmp->name[len-3] == 'j' && \
tmp->name[len-4] == '.' )
{
// printf("path=%s\n",name);
read_JPEG_file(tmp->name);
}
//判断.bmp
if(tmp->name[len-1] == 'p' && \
tmp->name[len-2] == 'm' && \
tmp->name[len-3] == 'b' && \
tmp->name[len-4] == '.' )
{
// printf("path=%s\n",name);
showbmp(tmp->name);
}
break;
}
case 3:
{
//取数据 tmp 保存大结构体的首地址
pos=pos->prev;
struct big_list *tmp = list_entry(pos,struct big_list,list);
printf("tmp->date = %s\n",tmp->name);
//判断图片格式
int len = strlen(tmp->name);
//判断.jpg
if(tmp->name[len-1] == 'g' && \
tmp->name[len-2] == 'p' && \
tmp->name[len-3] == 'j' && \
tmp->name[len-4] == '.' )
{
// printf("path=%s\n",name);
read_JPEG_file(tmp->name);
}
//判断.bmp
if(tmp->name[len-1] == 'p' && \
tmp->name[len-2] == 'm' && \
tmp->name[len-3] == 'b' && \
tmp->name[len-4] == '.' )
{
// printf("path=%s\n",name);
showbmp(tmp->name);
}
break;
}
case 4:
{
//取数据 tmp 保存大结构体的首地址
pos=pos->prev;
struct big_list *tmp = list_entry(pos,struct big_list,list);
printf("tmp->date = %s\n",tmp->name);
//判断图片格式
int len = strlen(tmp->name);
//判断.jpg
if(tmp->name[len-1] == 'g' && \
tmp->name[len-2] == 'p' && \
tmp->name[len-3] == 'j' && \
tmp->name[len-4] == '.' )
{
// printf("path=%s\n",name);
read_JPEG_file(tmp->name);
}
//判断.bmp
if(tmp->name[len-1] == 'p' && \
tmp->name[len-2] == 'm' && \
tmp->name[len-3] == 'b' && \
tmp->name[len-4] == '.' )
{
// printf("path=%s\n",name);
showbmp(tmp->name);
}
break;
}
}
}
}
//读取目录函数
int read_dir(char *dirpath)
{
//读取目录
DIR *fd=opendir(dirpath);
if(fd == NULL)
{
perror("opendir fail\n");
return -1;
}
//开始遍历目录
while(1)
{
//读取目录
struct dirent *p=readdir(fd);
if(p == NULL)
{
break;
}
//跳过隐藏文件
if(p->d_name[0] == '.')
{
continue;
}
//判断文件夹的类型
if(p->d_type == DT_DIR) //目录
{
//再次调用读取目录函数
//路径名的拼接
char newpath[1024]={0};
sprintf(newpath,"%s/%s",dirpath,p->d_name);
read_dir(newpath);
}
if(p->d_type == DT_REG) //普通文件
{
//输出目录的名字
//printf("path=%s\n",p->d_name);
//处理bmp与jpg图片
get_type(p->d_name,dirpath);
}
}
//关闭已经打开的目录
closedir(fd);
}
int main(int argc,char *argv[])
{
//判断用户输入的参数是否正确
if(argc != 2)
{
printf("请输入需要遍历的目录./main xxx\n");
return -1;
}
get_lcd_info();
//打开LCD设备
int fd = open("/dev/fb0",O_RDWR);
if(fd < 0)
{
printf("open lcd fail\n");
}
//对LCD设备进行映射操作
lcd = mmap(NULL,800*480*4,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
head = (struct list_head*)malloc(sizeof(struct list_head));
//初始化头节点
INIT_LIST_HEAD(head); //初始化头结点
//调用遍历目录函数
read_dir(argv[1]);
//显示链表中的数据
show_date(lcd);
close(fd);
munmap(lcd,800*480*4);
}