弄清楚编译,运行程序时候的路径是否合理,地方是否恰当,涉及到符号链接的不能在share目录下面进行;
1、JPEG 是一个图片的格式
也是一种压缩的算法
经过某一种的算法处理
ARGB <=========================> BMP/JPEG/PNG
libjpeg的库 什么是库? 就是一些函数,这些经过了封装-> so(linux下) dll(window下) libc.so
compress(压缩) (ARGB BMP)==> JPEG
decompress(解压缩) JPEG ==> ARGB BMP
就需要有这个JPEG的库文件,来实现,压缩和解压的操作。
2、将jpeg源码包交叉编译移植( 不可以放在共享目录下进行编译!!!!! )
cd (返回home目录)
mkdir xjm (用自己名字新建一个目录)
cd xjm/
tar -zxvf /mnt/hgfs/share/jpegsrc.v8a.tar.gz -C ./
ls
cd jpeg-8a/
ls
mkdir install (这个目录是我们安装编译好的库的一个目录)
cd install (进入这个目录)
pwd (获取当前这个目录的路径,作为安装的路径)
/home/gec/xjm/7.18/jpeg-8a/install (复制这个路径,这个路径就是库文件安装的路径)
cd .. (返回上一级目录进行编译)
./configure --host=arm-linux --target=arm-linux --prefix=/home/gec/xjm/7.18/jpeg-8a/install CC=arm-linux-gcc (配置它--> 生成对应的 Makefile )
make (编译)
make install (安装)
3、NFS挂载,将交叉编译好的库文件,下载到开发板 (NFS --> network file system 网络文件系统 )
sudo ifconfig eth0 IP(设置你可用的IP地址)
sudo route add default gw 192.168.5.1
ping www.baidu.com (如果不通的话,就是域名解析有问题,然后修改域名解析的文件)
sudo vim /etc/resolv.conf 添加一行 -> nameserver 192.168.5.1
修改域名解析地址
sudo vim /etc/resolv.conf
多加下面两行
nameserver 8.8.8.8
nameserver 8.8.4.4
安装NFS服务
sudo apt-get install nfs-kernel-server
sudo apt-get install nfs-common
配置NFS服务
sudo vim /etc/exports
在最后添加一行:
/home/gec/ *(rw,sync,no_root_squash,no_subtree_check)
rw:挂接此目录的客户端对该共享目录具有读写权限
sync:资料同步写入内存和硬盘
no_root_squash:客户机用root访问该共享文件夹时,不映射root用户。(root_squash:客户机用root用户访问该共享文件夹时,将root用户映射成匿名用户)
no_subtree_check:不检查父目录的权限。
重启NFS服务:
sudo /etc/init.d/nfs-kernel-server restart
在根目录下面新建一个nfs挂载的目录
sudo mkdir /nfs
sudo chmod 777 /nfs
本地挂载测试:
sudo mount 192.168.5.3:/home/gec/ /nfs (mount 命令的作用是用来挂载,第一个参数是要挂载的设备,第二个参数是要挂载到哪里,)
查看所挂载的设备
mount
卸载所挂载的路径
sudo umount /nfs
接下来到超级终端,配置开发板的IP和NFS,实现挂载的操作。
192.168.5.2 (这个是Windows的IP)
ifconfig eth0 192.168.5.4 ( 这个IP地址是开发板的IP )
mount -o nolock,tcp 192.168.5.3:/home/gec /mnt (192.168.5.3是你自己虚拟机的IP地址)
存在的问题:
1、三个设备,三个IP,不能一样,有的同学window的IP和虚拟机的IP相同.
2、NFS配置的问题,sudo /etc/init.d/nfs-kernel-server restart 看运行结果,有没有提示fail ,配置脚本/etc/exports,
3、首先要互相ping通,不行的话,可以开发板和电脑直连,测试看行不行。
点开linux虚拟机文件管理,进入caobo文件,找到example.c和libjpeg.txt文件查找相关步骤
4、JPEG的解压缩
1)、分配并且初始化一个jpeg的解压对象
struct jpeg_decompress_struct cinfo; //jpeg解压对象
struct jpeg_error_mgr jerr; //jpeg解压出错处理的结构体
cinfo.err = jpeg_std_error(&jerr); //初始化这两个对象
jpeg_create_decompress(&cinfo);
2)、将需要解压的JPEG图片读进来
FILE * infile;
if ((infile = fopen(filename, "rb")) == NULL) {
fprintf(stderr, "can't open %s\n", filename);
exit(1);
}
jpeg_stdio_src(&cinfo, infile);
3)、读取JPEG的头信息
jpeg_read_header(&cinfo, TRUE);
4)、设置解压的参数,如果不需要修改,就不需要做什么,采用默认的解压参数就可以了。
5)、调用对应的函数,进行解压操作
jpeg_start_decompress(&cinfo);
unsigned char *buffer = malloc(cinfo.output_width * cinfo.output_components);
6)、逐行读入JPEG的数据,并且解压
while ( cinfo.output_scanline < cinfo.output_height )
{
jpeg_read_scanlines(&cinfo, &buffer, 1);
}
7)、调用函数完成解压操作
jpeg_finish_decompress(&cinfo);
8)、释放JPEG解压对象
jpeg_destroy_decompress(&cinfo);
fclose(infile);
编译的命令:
-I 表示需要链接的头文件所在的路径, -L表示库文件所在的路径,-l表示在这个路径里面,你要链接的是哪一个库文件
arm-linux-gcc -o lcdmmap lcdmmap.c -I./jpeg-8a/install/include/ -L./jpeg-8a/install/lib/ -ljpeg
arm-linux-gcc lcdmmup2.c -o lcdmmup2 -I/home/gec/caobo/jpeg-8a/install/include/ -L/home/gec/caobo/jpeg-8a/install/lib/ -ljpeg
sudo cp /home/gec/caobo/jpeg-8a/install/lib/* /lib/ -rf
关于挂载
注意挂载在终端的时候很重要:挂载有两种方式,第一,mount -o nolock,tcp 192.168.5.117:/home/gec /mnt
第二,vi mount.sh
在里面粘贴 ifconfig eth0 192.168.5.182 ( 这个IP地址是开发板的IP )
mount -o nolock,tcp 192.168.5.117:/home/gec /mnt (192.168.5.3是你自己虚拟机的IP地址)保存退出,chimod 777 mount.sh 然后每次./mount.sh就可以实现挂载了;
注意是把虚拟机的家目录挂载在/mnt上,所以要cd /mnt 在/mnt目录下运行程序;
#include
#include
#include
#include
#include
#include
#include
int fd;
int *plcd=NULL;
void LCD_Draw_Point(int x,int y,int color)
{
if(x >=0 && x < 800 && y >=0 && y < 480)
{
*(plcd + 800*y + x) = color;
}
}
void jpeg_display()
{
//1)、分配并且初始化一个jpeg的解压对象
struct jpeg_decompress_struct cinfo; //jpeg解压对象
struct jpeg_error_mgr jerr; //jpeg解压出错处理的结构体
cinfo.err = jpeg_std_error(&jerr); //初始化这两个对象
jpeg_create_decompress(&cinfo);
//2)、将需要解压的JPEG图片读进来
FILE * infile;
if ((infile = fopen("1.jpg", "r")) == NULL) {
fprintf(stderr, "can't open \n");
exit(1);
}
jpeg_stdio_src(&cinfo, infile);
//3)、读取JPEG的头信息
jpeg_read_header(&cinfo, TRUE);
//4)、设置解压的参数,如果不需要修改,就不需要做什么,采用默认的解压参数就可以了。
//5)、调用对应的函数,进行解压操作
printf("cinfo.output_components=%d cinfo.output_height=%d",cinfo.output_components,cinfo.output_height);
jpeg_start_decompress(&cinfo);
printf("cinfo.output_components=%d cinfo.output_height=%d",cinfo.output_components,cinfo.output_height);
unsigned char *buffer = malloc(cinfo.output_width * cinfo.output_components);
printf("cinfo.output_components=%d cinfo.output_height=%d",cinfo.output_components,cinfo.output_height);
//6)、逐行读入JPEG的数据,并且解压
int x,y=0;
while ( cinfo.output_scanline < cinfo.output_height )
{
y=cinfo.output_scanline;
jpeg_read_scanlines(&cinfo, &buffer, 1);
unsigned char a,r,g,b;
int color;
unsigned char *p = buffer;
for(x=0;x < cinfo.output_width;x++)
{
if(cinfo.output_components == 3)
{
a=0; //如果cinfo.output_components == 3 它只有RGB的值
}
else
{
a=*p++; //否则是ARGB的格式
}
r = *p++;
g = *p++;
b = *p++;
color = a << 24 | r << 16 | g << 8 | b;
if(y<480 && x < 800)
{
LCD_Draw_Point( x, y, color);
}
}
}
//7)、调用函数完成解压操作
jpeg_finish_decompress(&cinfo);
//8)、释放JPEG解压对象
jpeg_destroy_decompress(&cinfo);
fclose(infile);
}
void bmp_display()
{
int fdBmp;
int w,h;
unsigned char buf[4];
int color_depth;
//打开对应的文件
fdBmp = open("1.bmp",O_RDONLY);
if(fdBmp<0)
{
perror("bmp open fail");
return;
}
//判断是不是BMP图片
read(fdBmp,buf,2);
if(buf[0] != 0x42 || buf[1] != 0x4d)
{
printf("This is not a BMP picture\n");
return;
}
//读图片的宽度
lseek(fdBmp,0x12,SEEK_SET);
read(fdBmp,buf,4);
w = buf[3] << 24 | buf[2] << 16 | buf[1] << 8 | buf[0];
//读图片的高度
lseek(fdBmp,0x16,SEEK_SET);
read(fdBmp,buf,4);
h = buf[3] << 24 | buf[2] << 16 | buf[1] << 8 | buf[0];
printf("w=%d h=%d\n",w,h);
//读图片的色深
lseek(fdBmp,0x1c,SEEK_SET);
read(fdBmp,buf,2);
color_depth = buf[1] << 8 | buf[0];
//计算图片数据的大小
int size = abs(w*h*color_depth/8) ;
//分配用来保存图片数据的内存空间
unsigned char *pixel = malloc(size);
lseek(fdBmp,54,SEEK_SET);
read(fdBmp,pixel,size);
int x,y;
int i=0;
unsigned char a,r,g,b;
int color;
for(y=0;y < abs(h); y++)
{
for(x=0;x b = pixel[i++]; g = pixel[i++]; r = pixel[i++]; a = (color_depth == 32) ? pixel[i++] : 0; color = a << 24 | r << 16 | g << 8 | b; //组合成一个新的颜色值ARGB int dy = h > 0 ? (h - 1 - y) : y; //判断图片是从左下角还是左上角开始显示 LCD_Draw_Point(x,dy,color); } } free(pixel); close(fdBmp); } int main() { // int fd; // int *plcd=NULL; fd = open("/dev/fb0",O_RDWR); if(fd < 0) { perror("open lcd fail"); return -1; } struct fb_var_screeninfo fbinfo; ioctl(fd,FBIOGET_VSCREENINFO,&fbinfo); printf("x:%d y:%d bit_per_pixel:%d\n",fbinfo.xres,fbinfo.yres,fbinfo.bits_per_pixel); plcd = mmap( NULL ,//表示映射的地址,为空让系统自动分配 fbinfo.xres*fbinfo.yres*fbinfo.bits_per_pixel/8,//分配内存的大小 PROT_WRITE,//对这个内存区域访问的权限 MAP_SHARED,//其他进程访问的权限 fd, 0//偏移量 ); if(plcd == MAP_FAILED) { perror("mmap fail"); close(fd); return -1; } int x,y; for(y=0;y<480;y++) { for(x=0;x<800;x++) { *(plcd + x + y*800) = 0x000000FF; } } //bmp_display(); jpeg_display(); close(fd); munmap(plcd,fbinfo.xres*fbinfo.yres*fbinfo.bits_per_pixel/8); return 0; } 弄清楚编译,运行程序时候的路径是否合理,地方是否恰当,涉及到符号链接的不能在share目录下面进行; 1、JPEG 是一个图片的格式 也是一种压缩的算法 经过某一种的算法处理 ARGB <=========================> BMP/JPEG/PNG libjpeg的库 什么是库? 就是一些函数,这些经过了封装-> so(linux下) dll(window下) libc.so compress(压缩) (ARGB BMP)==> JPEG decompress(解压缩) JPEG ==> ARGB BMP 就需要有这个JPEG的库文件,来实现,压缩和解压的操作。 2、将jpeg源码包交叉编译移植( 不可以放在共享目录下进行编译!!!!! ) cd (返回home目录) mkdir xjm (用自己名字新建一个目录) cd xjm/ tar -zxvf /mnt/hgfs/share/jpegsrc.v8a.tar.gz -C ./ ls cd jpeg-8a/ ls mkdir install (这个目录是我们安装编译好的库的一个目录) cd install (进入这个目录) pwd (获取当前这个目录的路径,作为安装的路径) /home/gec/xjm/7.18/jpeg-8a/install (复制这个路径,这个路径就是库文件安装的路径) cd .. (返回上一级目录进行编译) ./configure --host=arm-linux --target=arm-linux --prefix=/home/gec/xjm/7.18/jpeg-8a/install CC=arm-linux-gcc (配置它--> 生成对应的 Makefile ) make (编译) make install (安装) 3、NFS挂载,将交叉编译好的库文件,下载到开发板 (NFS --> network file system 网络文件系统 ) sudo ifconfig eth0 IP(设置你可用的IP地址) sudo route add default gw 192.168.5.1 ping www.baidu.com (如果不通的话,就是域名解析有问题,然后修改域名解析的文件) sudo vim /etc/resolv.conf 添加一行 -> nameserver 192.168.5.1 修改域名解析地址 sudo vim /etc/resolv.conf 多加下面两行 nameserver 8.8.8.8 nameserver 8.8.4.4 安装NFS服务 sudo apt-get install nfs-kernel-server sudo apt-get install nfs-common 配置NFS服务 sudo vim /etc/exports 在最后添加一行: /home/gec/ *(rw,sync,no_root_squash,no_subtree_check) rw:挂接此目录的客户端对该共享目录具有读写权限 sync:资料同步写入内存和硬盘 no_root_squash:客户机用root访问该共享文件夹时,不映射root用户。(root_squash:客户机用root用户访问该共享文件夹时,将root用户映射成匿名用户) no_subtree_check:不检查父目录的权限。 重启NFS服务: sudo /etc/init.d/nfs-kernel-server restart 在根目录下面新建一个nfs挂载的目录 sudo mkdir /nfs sudo chmod 777 /nfs 本地挂载测试: sudo mount 192.168.5.3:/home/gec/ /nfs (mount 命令的作用是用来挂载,第一个参数是要挂载的设备,第二个参数是要挂载到哪里,) 查看所挂载的设备 mount 卸载所挂载的路径 sudo umount /nfs 接下来到超级终端,配置开发板的IP和NFS,实现挂载的操作。 192.168.5.2 (这个是Windows的IP) ifconfig eth0 192.168.5.4 ( 这个IP地址是开发板的IP ) mount -o nolock,tcp 192.168.5.3:/home/gec /mnt (192.168.5.3是你自己虚拟机的IP地址) 存在的问题: 1、三个设备,三个IP,不能一样,有的同学window的IP和虚拟机的IP相同. 2、NFS配置的问题,sudo /etc/init.d/nfs-kernel-server restart 看运行结果,有没有提示fail ,配置脚本/etc/exports, 3、首先要互相ping通,不行的话,可以开发板和电脑直连,测试看行不行。 点开linux虚拟机文件管理,进入caobo文件,找到example.c和libjpeg.txt文件查找相关步骤 4、JPEG的解压缩 1)、分配并且初始化一个jpeg的解压对象 struct jpeg_decompress_struct cinfo; //jpeg解压对象 struct jpeg_error_mgr jerr; //jpeg解压出错处理的结构体 cinfo.err = jpeg_std_error(&jerr); //初始化这两个对象 jpeg_create_decompress(&cinfo); 2)、将需要解压的JPEG图片读进来 FILE * infile; if ((infile = fopen(filename, "rb")) == NULL) { fprintf(stderr, "can't open %s\n", filename); exit(1); } jpeg_stdio_src(&cinfo, infile); 3)、读取JPEG的头信息 jpeg_read_header(&cinfo, TRUE); 4)、设置解压的参数,如果不需要修改,就不需要做什么,采用默认的解压参数就可以了。 5)、调用对应的函数,进行解压操作 jpeg_start_decompress(&cinfo); unsigned char *buffer = malloc(cinfo.output_width * cinfo.output_components); 6)、逐行读入JPEG的数据,并且解压 while ( cinfo.output_scanline < cinfo.output_height ) { jpeg_read_scanlines(&cinfo, &buffer, 1); } 7)、调用函数完成解压操作 jpeg_finish_decompress(&cinfo); 8)、释放JPEG解压对象 jpeg_destroy_decompress(&cinfo); fclose(infile); 编译的命令: -I 表示需要链接的头文件所在的路径, -L表示库文件所在的路径,-l表示在这个路径里面,你要链接的是哪一个库文件 arm-linux-gcc -o lcdmmap lcdmmap.c -I./jpeg-8a/install/include/ -L./jpeg-8a/install/lib/ -ljpeg arm-linux-gcc lcdmmup2.c -o lcdmmup2 -I/home/gec/caobo/jpeg-8a/install/include/ -L/home/gec/caobo/jpeg-8a/install/lib/ -ljpeg sudo cp /home/gec/caobo/jpeg-8a/install/lib/* /lib/ -rf 关于挂载 注意挂载在终端的时候很重要:挂载有两种方式,第一,mount -o nolock,tcp 192.168.5.117:/home/gec /mnt 第二,vi mount.sh 在里面粘贴 ifconfig eth0 192.168.5.182 ( 这个IP地址是开发板的IP ) mount -o nolock,tcp 192.168.5.117:/home/gec /mnt (192.168.5.3是你自己虚拟机的IP地址)保存退出,chimod 777 mount.sh 然后每次./mount.sh就可以实现挂载了; 注意是把虚拟机的家目录挂载在/mnt上,所以要cd /mnt 在/mnt目录下运行程序; #include #include #include #include #include #include #include int fd; int *plcd=NULL; void LCD_Draw_Point(int x,int y,int color) { if(x >=0 && x < 800 && y >=0 && y < 480) { *(plcd + 800*y + x) = color; } } void jpeg_display() { //1)、分配并且初始化一个jpeg的解压对象 struct jpeg_decompress_struct cinfo; //jpeg解压对象 struct jpeg_error_mgr jerr; //jpeg解压出错处理的结构体 cinfo.err = jpeg_std_error(&jerr); //初始化这两个对象 jpeg_create_decompress(&cinfo); //2)、将需要解压的JPEG图片读进来 FILE * infile; if ((infile = fopen("1.jpg", "r")) == NULL) { fprintf(stderr, "can't open \n"); exit(1); } jpeg_stdio_src(&cinfo, infile); //3)、读取JPEG的头信息 jpeg_read_header(&cinfo, TRUE); //4)、设置解压的参数,如果不需要修改,就不需要做什么,采用默认的解压参数就可以了。 //5)、调用对应的函数,进行解压操作 printf("cinfo.output_components=%d cinfo.output_height=%d",cinfo.output_components,cinfo.output_height); jpeg_start_decompress(&cinfo); printf("cinfo.output_components=%d cinfo.output_height=%d",cinfo.output_components,cinfo.output_height); unsigned char *buffer = malloc(cinfo.output_width * cinfo.output_components); printf("cinfo.output_components=%d cinfo.output_height=%d",cinfo.output_components,cinfo.output_height); //6)、逐行读入JPEG的数据,并且解压 int x,y=0; while ( cinfo.output_scanline < cinfo.output_height ) { y=cinfo.output_scanline; jpeg_read_scanlines(&cinfo, &buffer, 1); unsigned char a,r,g,b; int color; unsigned char *p = buffer; for(x=0;x < cinfo.output_width;x++) { if(cinfo.output_components == 3) { a=0; //如果cinfo.output_components == 3 它只有RGB的值 } else { a=*p++; //否则是ARGB的格式 } r = *p++; g = *p++; b = *p++; color = a << 24 | r << 16 | g << 8 | b; if(y<480 && x < 800) { LCD_Draw_Point( x, y, color); } } } //7)、调用函数完成解压操作 jpeg_finish_decompress(&cinfo); //8)、释放JPEG解压对象 jpeg_destroy_decompress(&cinfo); fclose(infile); } void bmp_display() { int fdBmp; int w,h; unsigned char buf[4]; int color_depth; //打开对应的文件 fdBmp = open("1.bmp",O_RDONLY); if(fdBmp<0) { perror("bmp open fail"); return; } //判断是不是BMP图片 read(fdBmp,buf,2); if(buf[0] != 0x42 || buf[1] != 0x4d) { printf("This is not a BMP picture\n"); return; } //读图片的宽度 lseek(fdBmp,0x12,SEEK_SET); read(fdBmp,buf,4); w = buf[3] << 24 | buf[2] << 16 | buf[1] << 8 | buf[0]; //读图片的高度 lseek(fdBmp,0x16,SEEK_SET); read(fdBmp,buf,4); h = buf[3] << 24 | buf[2] << 16 | buf[1] << 8 | buf[0]; printf("w=%d h=%d\n",w,h); //读图片的色深 lseek(fdBmp,0x1c,SEEK_SET); read(fdBmp,buf,2); color_depth = buf[1] << 8 | buf[0]; //计算图片数据的大小 int size = abs(w*h*color_depth/8) ; //分配用来保存图片数据的内存空间 unsigned char *pixel = malloc(size); lseek(fdBmp,54,SEEK_SET); read(fdBmp,pixel,size); int x,y; int i=0; unsigned char a,r,g,b; int color; for(y=0;y < abs(h); y++) { for(x=0;x b = pixel[i++]; g = pixel[i++]; r = pixel[i++]; a = (color_depth == 32) ? pixel[i++] : 0; color = a << 24 | r << 16 | g << 8 | b; //组合成一个新的颜色值ARGB int dy = h > 0 ? (h - 1 - y) : y; //判断图片是从左下角还是左上角开始显示 LCD_Draw_Point(x,dy,color); } } free(pixel); close(fdBmp); } int main() { // int fd; // int *plcd=NULL; fd = open("/dev/fb0",O_RDWR); if(fd < 0) { perror("open lcd fail"); return -1; } struct fb_var_screeninfo fbinfo; ioctl(fd,FBIOGET_VSCREENINFO,&fbinfo); printf("x:%d y:%d bit_per_pixel:%d\n",fbinfo.xres,fbinfo.yres,fbinfo.bits_per_pixel); plcd = mmap( NULL ,//表示映射的地址,为空让系统自动分配 fbinfo.xres*fbinfo.yres*fbinfo.bits_per_pixel/8,//分配内存的大小 PROT_WRITE,//对这个内存区域访问的权限 MAP_SHARED,//其他进程访问的权限 fd, 0//偏移量 ); if(plcd == MAP_FAILED) { perror("mmap fail"); close(fd); return -1; } int x,y; for(y=0;y<480;y++) { for(x=0;x<800;x++) { *(plcd + x + y*800) = 0x000000FF; } } //bmp_display(); jpeg_display(); close(fd); munmap(plcd,fbinfo.xres*fbinfo.yres*fbinfo.bits_per_pixel/8); return 0; }