在GEC6818开发平台上可以显示JPG格式的图片
一. 任务:显示RGB颜色LCD液晶屏幕中 --> 例如: 填充紫色到LCD上。
1. 分析技术点
1)了解LCD液晶屏幕组成架构?
2)在嵌入式平台如何处理LCD屏幕?
3)如何在工程访问LCD液晶屏?
4)如何写入数据到LCD屏幕中?数据是什么?该如何表示颜色?
二. 研究LCD液晶屏幕参数
1. 什么是分辨率?GEC6818平台LCD屏幕分辨率是多少?
分辨率指的是设备总像素点数是多少,例如:电视机1080*720 -> 一共有1080*720这么多个像素点
GEC6818平台分辨率->800*480
2. 什么是像素点?
像素,就是图像元素,指的是由RGB颜色组成一个点。
3. 究竟每个像素点如何组成?
像素点占多少个字节数? --> 通过在GEC6818平台输入命令知道
[root@GEC6818 /]#cat /sys/class/graphics/fb0/bits_per_pixel
32
---> 1个像素点 --> 32位
已知:1个字节 = 8位
---> 1个像素点 --> 4个字节
结论: 每一个像素点 --> 透明度,红色,绿色,蓝色
三. 在嵌入式平台如何处理LCD屏幕?
原理:在linux下,一切都是文件。 --->在linux下,LCD液晶屏是被看作是一个文件。
LCD液晶屏幕对应的文件名是什么?
--->规律:嵌入式平台硬件设备文件名存放dev目录 dev->device
1. 切换到/dev目录下
[root@GEC6818 /]#cd /dev/
[root@GEC6818 /dev]#
2. 查看当前目录下所有的文件名是什么?
[root@GEC6818 /dev]#ls
fb0 --> 就是LCD液晶屏幕的文件名
四. 如何在工程访问/关闭LCD液晶屏? --> 新的函数:open
1. 在Ubuntu中,输入命令查看open函数用法
gec@ubuntu:~$ man 2 open --> 结束查询->按‘q’
头文件是什么?
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
函数原型是什么?
int open(const char *pathname, int flags);
参数填什么?
pathname:需要打开的文件的路径名 -> 文件在哪里?
flags:操作文件的权限
O_RDONLY --> read only -> 只读
O_WRONLY --> write only -> 只写
O_RDWR --> read write -> 可读可写
返回值是什么?
成功:new file descriptor -> 新的文件描述符 --> 其实是大于等于0 >=0
失败:-1
2. 如何关闭?
在Ubuntu中,输入命令查看close函数使用方法:
头文件是什么?
#include <unistd.h>
函数原型是什么?
int close(int fd);
参数填什么?
fd: -> file descriptor -> 文件描述符
返回值是什么?
成功:0
失败:-1
练习: 写一个程序 --> LCD设备名字: /dev/fb0
1. 首先访问LCD屏幕
如果访问成功,则在终端打印open lcd ok!
如果访问失败,则在终端打印open lcd error!
2. 然后关闭LCD屏幕
如果关闭成功,则在终端打印close lcd ok!
如果关闭失败,则在终端打印close lcd error!
参考代码:
------------------------------------------
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main() //->函数头
{
//->函数体,写一些可执行的内容
//->使用了printf才需要包含头文件
printf("this is first program!\n");
int lcd_fd;//关于LCD液晶屏幕的文件描述符
lcd_fd = open("/dev/fb0",O_RDWR);
if(lcd_fd >= 0)
{
printf("open lcd ok!\n");
}
else{
printf("open lcd error!\n");
}
int ret;
ret = close(lcd_fd);
if(ret == 0)
{
printf("close lcd ok!\n");
}
else{
printf("close lcd error!\n");
}
return 0; //->返回值 成功:0 失败:非0
}
---------------------------------------
五. 如何写入数据到LCD屏幕中?数据是什么?该如何表示颜色?
1. 如何写入? --> 新函数:write()
在Ubuntu中输入查询命令:
gec@ubuntu:/mnt/hgfs/zdnf/02$ man 2 write
头文件是什么?
#include <unistd.h>
函数原型是什么?
ssize_t write(int fd, const void *buf, size_t count);
参数填什么?
fd: -> file descriptor -> 文件描述符
buf:-> buffer --> 写入的数据的缓冲区 --> RGB颜色
count: --> 写入的总字节数
返回值是什么?
成功:已经写入的字节数
失败:-1
2. 数据是什么?
既然任务是填充RGB颜色到LCD屏幕,数据就应该RGB颜色。
write()
颜色 --------> LCD液晶
3. 该如何表示颜色?
结论: 每一个像素点 --> 透明度,红色,绿色,蓝色
例子:红色如何表示?
一个像素点=32位
00000000111111110000000000000000 --> 红色
0x00FF0000 --> 红色
0x00FF00FF --> 紫色
0x00FFFF00 --> 黄色
---------------------填充红色示例代码-------------------------------
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main() //->函数头
{
//->函数体,写一些可执行的内容
//->使用了printf才需要包含头文件
printf("this is first program!\n");
int lcd_fd;//关于LCD液晶屏幕的文件描述符
lcd_fd = open("/dev/fb0",O_RDWR);
if(lcd_fd >= 0)
{
printf("open lcd ok!\n");
}
else{
printf("open lcd error!\n");
}
int color = 0x00FF0000;
int i;
for(i=0;i<800*480;i++)
{
write(lcd_fd,&color,4);
}
int ret;
ret = close(lcd_fd);
if(ret == 0)
{
printf("close lcd ok!\n");
}
else{
printf("close lcd error!\n");
}
return 0; //->返回值 成功:0 失败:非0
}
-----------------------------------------------
练习:填充紫色到LCD屏幕。
一. 项目: 基于网络远程控制多媒体系统
socket通信
客户端 <------------> 服务器
UI界面 播放视频
触摸屏 控制视频状态
二. UI界面如何设计?JPG格式图形特点?JPG图片如何显示LCD液晶屏幕?
1. UI界面如何设计?
已知GEC6818平台LCD液晶屏幕分辨率->800*480 -->横:800个像素点 竖:480个像素点
想在LCD液晶上全屏显示JPG格式图片-> UI界面->分辨率:800*480
2. 根据项目要求设计UI界面
1)按钮内容
控制视频状态:快进、快退、音量+、音量-、暂停/继续、静音/恢复、退出。
2)按钮大小 -> 由于在客户端中触摸屏控制按钮,所以必须清楚知道按钮的范围!
画图软件:
重新调整大小->像素->把"保持纵横比"选项去掉
水平:800
垂直:480
3. 为什么选择使用jpg格式图片?
由于jpg格式文件经过压缩的,所以文件大小相对其它格式图片较小,方便开发时进行数据传输。
而且显示jpg图片编译移植jpg库,然后jpg源码调用库里面的接口就可以。
三. JPG图片如何显示LCD液晶屏幕?
任务: UI.jpg --> 显示在GEC6818平台
首先拿到两个文件:
jpeg_show.c --> 显示jpg图片的源码
jpegsrc.v9a.tar.gz --> jpg库
1. 在Ubuntu中,切换到源码所在的路径
gec@ubuntu:~$ cd /mnt/hgfs/zdnf/02/
2. 尝试在Ubuntu Linux系统编译源码:
gec@ubuntu:/mnt/hgfs/zdnf/02$ arm-linux-gcc jpeg_show.c -o jpeg_show
编译出错:
error: jpeglib.h: No such file or directory -> 找不到jpeglib.h这个头文件。
jpeglib.h->其实是存在于jpg库中,所以编译之前,首先要编译移植jpg库。
四. 编译移植jpg库?
1. 什么是编译移植?
其实就是安装jpg库的文件到Ubuntu linux系统中。
2. 如何编译移植?
jpegsrc.v9a.tar.gz --> jpg库: 开源免费
1)先把jpg库放置在共享目录下
2)在linux中,切换到jpg库所在的路径下
gec@ubuntu:~$ cd /mnt/hgfs/zdnf/02/
3)在linux中解压jpg库,一般地解压到家目录下 --> 因为在家目录下,拥有一切权限。
gec@ubuntu:/mnt/hgfs/zdnf/02$ tar zxvf jpegsrc.v9a.tar.gz -C ~
tar: 解压/压缩的linux命令
z: 处理以.gz结尾的压缩包
x: 解压 c:压缩
v: 以可见的方式进行解压,这个参数不是必须。
f: 文件
-C: 指定解压之后的路径
~: 家目录
如果有v选项,则会打印解压的过程
jpeg-9a/
jpeg-9a/wrppm.c
jpeg-9a/wrrle.c
jpeg-9a/maketdsp.vc6
jpeg-9a/jdinput.c
4)回到家目录下,看看有没有一个新的目录叫jpeg-9a/
gec@ubuntu:/mnt/hgfs/zdnf/02$ cd ~
gec@ubuntu:~$ ls --> 看到jpeg-9a/目录
5)在家目录下创建一个新的目录,作为安装之后的目录,并给予权限
创建目录linux命令:mkdir --> make diretcory
gec@ubuntu:~$ mkdir jpgbuf --> 创建目录
gec@ubuntu:~$ chmod 777 jpgbuf --> 修改目录权限
为什么要修改目录权限?
因为在windows中,创建了一个新的文件夹,我们可以直接把文件丢进去。
但是在linux下,创建一个新的目录,是默认没有写的权限,我们不能丢文件进去,所以就没办法安装到目录中
--> 结论: 创建完目录后,通过chmod命令给予权限。
6)切换到解压之后的目录下
gec@ubuntu:~$ cd ~/jpeg-9a/
gec@ubuntu:~/jpeg-9a$ ls --> 看到一个文件,叫configure -> 配置文件。
7)配置
gec@ubuntu:~/jpeg-9a$ ./configure --host=arm-linux --prefix=/home/gec/jpgbuf
其中:
./configure --> 执行当前目录下的configure文件
--host=arm-linux --> 指定是交叉编译
--prefix=/home/gec/jpgbuf -->指定安装路径
8)编译
gec@ubuntu:~/jpeg-9a$ make
make all-am
make[1]: Entering directory `/home/gec/jpeg-9a'
make[1]: Leaving directory `/home/gec/jpeg-9a' --> 则需要清除链接文件
gec@ubuntu:~/jpeg-9a$ make clean -> 清除链接文件
rm -f cjpeg djpeg jpegtran rdjpgcom wrjpgcom
test -z "testout.ppm testout.bmp testout.jpg testoutp.ppm testoutp.jpg testoutt.jpg" || rm -f testout.ppm testout.bmp testout.jpg testoutp.ppm testoutp.jpg testoutt.jpg
test -z "libjpeg.la" || rm -f libjpeg.la
rm -f ./so_locations
rm -rf .libs _libs
rm -f *.o
rm -f *.lo
gec@ubuntu:~/jpeg-9a$ make --> 重新编译
CC jaricom.lo
CC jcapimin.lo
CC jcapistd.lo --> 正在编译
9)安装
gec@ubuntu:~/jpeg-9a$ make install
安装结果:切换到jpgbuf路径看看
gec@ubuntu:~/jpeg-9a$ cd ~/jpgbuf
gec@ubuntu:~/jpgbuf$ ls
bin include lib share --> 如果看到有4个目录,则编译移植jpg库成功!
五. 分析jpg库编译移植之后文件有哪些?
bin:
cjpeg djpeg jpegtran rdjpgcom wrjpgcom --> 二进制文件
include:
jconfig.h jerror.h jmorecfg.h jpeglib.h --> jpg库头文件
lib:
libjpeg.a libjpeg.la libjpeg.so libjpeg.so.9 libjpeg.so.9.1.0 --> 库文件
share:
man --> 帮助文档
六. 已经编译移植完,接下来让源码调用库里面的内容。
1. 切换到源码的位置
gec@ubuntu:~/jpgbuf/share$ cd /mnt/hgfs/zdnf/02/
2. 重新编译
gec@ubuntu:/mnt/hgfs/zdnf/02$ arm-linux-gcc jpeg_show.c -o jpeg_show
编译出错:error: jpeglib.h: No such file or directory
为什么编译移植之后,还是找不到?
因为用户编译移植完jpg库之后,编译器是不知道已经编译完成了,所以我们需要告诉编译器,头文件在哪里。
如何告诉编译器,头文件在哪里? --> 使用编译器选项: -I 头文件的路径
gec@ubuntu:/mnt/hgfs/zdnf/02$ arm-linux-gcc jpeg_show.c -o jpeg_show -I /home/gec/jpgbuf/include
编译出错:
/tmp/cc2O0oBN.o: In function `main':
jpeg_show.c:(.text+0x440): undefined reference to `jpeg_std_error'
jpeg_show.c:(.text+0x45c): undefined reference to `jpeg_CreateDecompress'
jpeg_show.c:(.text+0x474): undefined reference to `jpeg_mem_src'
原因:找不到对应的函数的定义,函数的定义其实在库文件中,找不到函数的定义,其实就是找不到库文件,库文件就是lib中。
如何告诉编译器,库文件在哪里? --> 使用编译器选项: -L 库文件的路径 -l库的名字
gec@ubuntu:/mnt/hgfs/zdnf/02$ arm-linux-gcc jpeg_show.c -o jpeg_show -I /home/gec/jpgbuf/include -L /home/gec/jpgbuf/lib
编译出错:
/tmp/cc2O0oBN.o: In function `main':
jpeg_show.c:(.text+0x440): undefined reference to `jpeg_std_error'
jpeg_show.c:(.text+0x45c): undefined reference to `jpeg_CreateDecompress'
jpeg_show.c:(.text+0x474): undefined reference to `jpeg_mem_src'
-l库的名字 --> -l后面是没有空格的
libjpeg.so.9.1.0 --> 库的名字是lib与.so中间的名字
--> -ljpeg
gec@ubuntu:/mnt/hgfs/zdnf/02$ arm-linux-gcc jpeg_show.c -o jpeg_show -I /home/gec/jpgbuf/include -L /home/gec/jpgbuf/lib -ljpeg
编译通过,生成一个新的文件:jpeg_show
七. 烧写程序到开发板中
1. 烧写可执行程序,输入烧写命令
[root@GEC6818 /]#cd /
[root@GEC6818 /]#rx jpeg_show
C
2. 传输->发送Xmodom->选择jpeg_show文件->发送
3. 修改权限
[root@GEC6818 /]#chmod 777 jpeg_show
4. 执行
[root@GEC6818 /]#./jpeg_show
./jpeg_show: error while loading shared libraries: libjpeg.so.9: cannot open shared object file: No such file or directory
解决方案:将缺少的库libjpeg.so.9下载到开发板的/lib中
5. 下载libjpeg.so.9到开发板中
[root@GEC6818 /]#cd /lib
[root@GEC6818 /lib]#rx libjpeg.so.9
C
传输->发送Xmodom->选择libjpeg.so.9文件->发送
6. 回到根目录,再下载图片到开发板中
[root@GEC6818 /]#cd /
[root@GEC6818 /]#rx UI.jpg
C
传输->发送Xmodom->选择UI.jpg文件->发送
|