弄清楚编译,运行程序时候的路径是否合理,地方是否恰当,涉及到符号链接的不能在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 <stdio.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <jpeglib.h>
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<abs(w);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 <stdio.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <jpeglib.h>
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<abs(w);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;
}