JPEG图片的显示

 

弄清楚编译,运行程序时候的路径是否合理,地方是否恰当,涉及到符号链接的不能在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;

}

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(JPEG图片的显示)