ARM型号我不太记得了(其实也不太懂);
好像是:三星 ARM-Cortex-A9 吧,由粤嵌公司做的一个板子。。。
周六周日两天,由粤嵌公司的工程师带我们做了一个项目——电子音乐相册。
不过这只是初步。。。毕竟我们以前没接触过 ARM 的开发。(部分同学学过单片机,我只是多学了个初等的 Arduino)
本以为这次是从入门到完成,从 Linux 系统上安装 ARM 编译所需--到-- ARM 下驱动编写以及多进程同时调度音乐播放和图片播放。
结果……老师觉得我们不行,都封装好给我们了(Ubuntu的镜像都直接集成了,ARM与计算机的网口通信,还有可怜的音乐图片不能同时播放,以及没有触屏功能)。
所以课程还是比较轻松(对于我来说)。。。
这两天感觉心情不错,主要是做出东西总是有成就感的(虽然这个巨人有点大)。
但也感到很多不足,包括Linux的自大,网络知识的自负,ARM的无知,操作系统的无视,还有体力的自信。。。
总之,要感谢这两天教导我们的 邓工程师,以及粤嵌公司的其它老师。。。
_________________________________________________________
以下,邓工程师的教导笔记(日记吧)
linux 环境编程: -------> linux 一切都是文件
设备文件存放在 /dev ----> /dev/fb0
----------------------------安装共享文件夹------------------------------
Vmware
VM ---> setting ---> Options ---> share folders ---> Always enable
配置 windows 系统的共享目录:
D:/share
在 linux系统中:
cd /mnt/hgfs/share
------------------------------tftp32使用-------------------------------------
确保开发板与PC的IP同一网段
开发板:
ifconfig eth0 192.168.2.xx -----> xx 为开发板的ip
tftp 192.168.2.yy -g -r xxx.bmp ----> yy 为tftp32的ip
tftp 192.168.2.yy -g -r lcd
------------------------------------------------------------------------
编程控制设备:
1) 文件IO API
2) linux 管理系统
3) 设备访问规则
3.1) 获取资源许可: -----> man man
open();
获得LCD控制许可:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *pathname, int flags);
pathname: “/dev/fb0”
flags: O_RDWR
3.2) 控制LCD
#include <unistd.h>
write/read
ssize_t write(int fd, const void *buf, size_t count);
fd: lcd的文件描述符 ,open成功返回的int 值
buf: 写入LCD的图形数据
count: 写入数据的大小
// cat /bin/busybox > /dev/fb0
// LCD 显示的是颜色 ---> RGB数值 ---> 32bit =》 8:8:8:8(透明度:红色:绿色:蓝色)
// LCD 显示的大小 ---> 分辨率 ---> 800*480
// LCD 显示一帧图像的 存储容量: 800*480*4 = 1536000字节 = 1.5M
// RGB =》 0xFFFFFF ---> 白色 0x00000000 --> 黑色
3.3)回收资源
#include <unistd.h>
int close(int fd);
fd: lcd的文件描述符 ,open成功返回的int 值
3.4) 图片操作
open();
read();
ssize_t read(int fd, void *buf, size_t count);
fd:图片的文件描述符 ,open成功返回的int 值
buf: 图片内容
count: 读取图片内容的大小
文件指针移动
lseek(int fd, off_t offset, int whence);
fd:图片的文件描述符 ,open成功返回的int 值
offset: 文件操作指针移动偏移量
whence: 文件指针操作的起始位置
SEEK_SET 文件头部
SEEK_CUR 文件当前位置
SEEK_END 文件尾部
lseek(bmp_fd,54,SEEK_SET);
3.5 ) 多张图片操作
3.5.1) 文件夹操作
#include <sys/types.h>
#include <dirent.h>
//打开文件目录,获取目录流指针
DIR *opendir(const char *name);
name : 文件目录名称
DIR: 文件目录流结构
//读取目录流指针,获取当前的struct dirent目录项指针
struct dirent *readdir(DIR *dirp);
struct dirent {
ino_t d_ino; /* inode number */
off_t d_off; /* offset to the next dirent */
unsigned short d_reclen; /* length of this record */
unsigned char d_type; /* type of file; not supported
by all file system types */
char d_name[256]; /* filename */
};
在开发板建立图片目录:
mkdir pic
将图片下载到pic中,让后通过代码进行目录访问:
DIR * pic_dir = opendir("/pic");
struct dirent * pic_dirent ;
char pathname[30];
while( (pic_dirent= readdir(pic_dir)) != NULL )
{
if(strstr(pic_dirent->d_name,".bmp"))
{
snprintf(pathname,30,"/pic/%s",pic_dirent->d_name);
bmp_fd[i] = open(pathname,O_RDWR);
...
}
}
closedir(pic_dir);
3.6) 图片翻转
//24bit to 32bit
for(i=0,j=800*480*4-1;i<800*480*3;i+=3)
{
pic_mem[j-3] = bmp_mem[i] ;
pic_mem[j-2] = bmp_mem[i+1] ;
pic_mem[j-1] = bmp_mem[i+2] ;
j-=4;
}
3.7) 微缩图操作
char narrow_buf[4][400*240*3];
for(i=0,j=0;i<pic_count;i++)
{
//移动文件读取指针位置,从头部54字节地方开始
lseek(bmp_fd[i],54,SEEK_SET);
//读取图片数据800*480*3+54
read(bmp_fd[i],bmp_mem,800*480*3);
j=0;
for(y=479;y>=0;y-=2)
for(x=0;x<800*3;x+=3)
{
for(count=0;count<3;count++)
narrow_buf[i][j++] = bmp_mem[y*800*3+x++] ;
}
}
for(i=0,j=0;i<pic_count;i++)
{
j=0;
for(y=0+(i/2)*240;y<240+(i/2)*240;y++)
for(x=0+(i%2)*400*4;x<400*4+(i%2)*400*4;x++)
{
pic_mem[y*800+x] = narrow_buf[i][j++];
if( x!= 0 && x%3 == 0)
x++;
}
}
3.8)按键操作
1) 通过open对按键发起访问
open("/dev/eventX",O_RDWR);
2)通过read 获取按键的数据
struct input_event {
struct timeval time;
__u16 type; // 事件类型
__u16 code; //按键键值
__s32 value; //按键状态 1按下 0 弹起
};
struct input_event key_event;
read(fd,&key_event,sizeof(key_event));
if(key_event.type == EV_KEY) //是否读到一个按键事件
{
if(key_event.code == KEY_LEFT) //如果是左键按下
{
... //放大微缩图
}
if(key_event.code == KEY_RIGHT) //如果是右键按下
{
... //显示微缩图
}
....
}
----------------具体操作-------------------
1、将驱动下载到开发板,并加载:
input_key.ko
在开发板安装驱动: insmod input_key.ko
在开发板卸载驱动: rmmod input_key
查看安装的驱动: lsmod
2、修改代码,访问按键按键驱动:
#include <linux/input.h>
int key_fd;
struct input_event key_event;
key_fd = open("/dev/event1",O_RDWR);
if(key_fd < 0)
{
perror(" open key err !");
return -1;
}
read(key_fd,&key_event,sizeof(key_event));
if(key_event.type == EV_KEY)
{
if(key_event.code == KEY_LEFT)
{
//显示放大图片
}
if(key_event.code == KEY_RIGHT)
{
//显示微缩图
}
}
close(key_fd)
3.9) 幻灯片播放
4.0)音乐播放
--------------------------------------------------------------------------------------------
程序编译:
本地编译: 运行与编译的环境一致 (PC 编程)
交叉编译: 运行与编译的环境不一致 (在一个平台编译另外一个平台的代码,PC --> ARM)
编译器: 本地编译器 ,交叉编译器
gcc arm-linux-gcc
使用:
cd /mnt/hgfs/share
arm-linux-gcc lcd.c -o lcd //得到执行程序 lcd
查看文件的类型属性:
file a.out
在开饭的超级终端中将应用程序下载到开发板运行测试:
输入: rx lcd 回车
超级终端选择:“传送” ---> 发送文件 ----> 协议: Xmodem 文件: d:/share/lcd 回车
修改文件执行权限: chmod 777 lcd
执行测试: ./lcd
-------------------------BMP图片下载-----------------------------
rx 1.bmp 回车
pwd 查看当前路径
------------man man ---(q 退出)---------
1 Executable programs or shell commands
2 System calls (functions provided by the kernel)
3 Library calls (functions within program libraries)
-------------------------------------------------------
第一天
关于图片的读取与打印屏幕,文件目录文件的读取与24位位图转成32位图
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <dirent.h>
char bmp_mem[800*480*3];
char pic_mem[800*480*4];
DIR * pic_dir;
struct dirent *pic_dirent;
char pathname[30];
int pic_count;
int main(int argc,char **argv)
{
int fd,bmp_fd[30];
int i=0,j,k;
//获取LCD资源
fd = open("/dev/fb0",O_RDWR);
//获取失败处理
if(fd < 0)
{
perror(" open LCD Err !");
return -1;
}
//写屏幕
memset(pic_mem, 0xFF, 800*480*4);
write(fd, pic_mem, 800*480*4);
sleep(3);
//打开目录
pic_dir = opendir("/pic");
//读目录
while( ( pic_dirent = readdir(pic_dir)) != NULL )
{
if(strstr(pic_dirent->d_name,".bmp"))
{
snprintf(pathname,30,"/pic/%s",pic_dirent->d_name);
//打开图片,获取图片操作许可
//打开文件,将文件描述符写入文件描述符数组
bmp_fd[i++] = open(pathname,O_RDWR);
if( bmp_fd[i] <0)
{
perror(" open bmp err ");
return -1;
}
pic_count = i;
}
}
for(k=0;k<pic_count;k++)
{
//移动文件读取指针位置,从头部54字节地方开始
lseek(bmp_fd[k],54,SEEK_SET);
//读取图片数据800*480*3+54
read(bmp_fd[k],bmp_mem,800*480*3);
//24bit to 32bit
for(i=0,j=0;i<800*480*3;i+=3)
{
pic_mem[j] = bmp_mem[i] ;
pic_mem[j+1] = bmp_mem[i+1] ;
pic_mem[j+2] = bmp_mem[i+2] ;
j+=4;
}
//移动显存指针位置,从头部开始
lseek(fd,0,SEEK_SET);
//将读到的图片数据写入LCD
write(fd,pic_mem,800*480*4);
//休眠3秒
sleep(3);
}
//回收资源
close(fd);
closedir(pic_dir);
for(i=0;i<pic_count;i++)
close(bmp_fd[i]);
return 0; //成功返回 0 ;失败返回的是负数: -1
}
【个人的打印屏幕代码】
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
//控制LCD屏幕
char pic_mem[800*480*4]; /* 图像地址? */
void pic_set(int ss, int ee, char color){
int i;
for(i=ss; i<=ee; i++){
pic_mem[i] = color;
}
}
int main(int argc, char **argv){
char pathname[] = "/dev/fb0"; /* 文件路径 */
int flags = O_RDWR; /* 访问方式 */
int fd = open(pathname, flags); /* 获取文件句柄 */
if( fd < 0 ){ /* 获取失败 处理 */
printf("OPEN LCD ERROR!\n");
return -1;
}
//memset(pic_mem, 0xFF, sizeof(pic_mem));
pic_set(0, 500000, 0x00);
pic_set(500000, 1000000, 0xFF);
pic_set(1000000,1500000, 0x00);
pic_set(1500000,2000000, 0xFF);
pic_set(2500000,3000000, 0x00);
pic_set(3500000,4000000, 0xFF);
pic_set(4500000,5000000, 0x00);
/** 写屏幕 */
write(fd, pic_mem, 800*480*4); /* 写位置,来源,需要写多少 */
/* LCD 颜色8:8:8:8(透明度,红,绿,蓝) */
/* LCD 大小 分辨率 800*480 *4Byte */
/* 故, 写一张图片大小 1.5M */
/* WHITE=0xFFFFFFFF, BLACK=0x00000000 */
close(fd); /* 关闭文件,回收资源 */
return 0; /** SUCCESS 0, ERROR -1 */
}
【个人代码,随机循环变色(还没加图片处理)】
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
//控制LCD屏幕
char pic_mem[800*480*4]; /* 图像地址? */
#define SET_COLOR(color, no) (char)( ((color)>>(8*no))&0xFF )
unsigned int rand_color(){
unsigned int res = 0;
int i;
for(i=0; i<4; i++)
res |= (res<<8) | ( rand()%256 );
return res;
}
void pic_set(int ss, int ee, unsigned int color){
int i, j;
for(i=ss; i<=ee; i+=4)
for(j=3; j>=0; j--)
pic_mem[i+j] = SET_COLOR(color, j);
}
int open_err(char path[], int st){
int pd = open(path, st);
if( pd < 0 ){
perror("OPEN file Error!\n");
return -1;
}
return pd;
}
int main(int argc, char **argv){
char pathname[] = "/dev/fb0"; /* 文件路径 */
char p01name[] = "/p01.bmp"
int flags = O_RDWR; /* 访问方式 */
srand(time(NULL));
//memset(pic_mem, 0xaa, sizeof(pic_mem));
unsigned int c[2] = {0x520A0B0C , 0x00AABBCC}, delay_time;
int flag = 0;
int fd = open(pathname, flags); /* 获取文件句柄 */
if( fd < 0 ){ /* 获取失败 处理 */
printf("OPEN LCD ERROR!\n");
return -1;
}
while( 1 ){
/* 打开图片 */
//int bmp_fd = open_err(p01name, flags);
int bmp_fd;
read(bmp_fd, p01name, 800*480*3);
pic_set(0*480*4, 400*480*4, rand_color());
pic_set(400*480*4, 800*480*4, rand_color());
flag = 1-flag;
/** 写屏幕 */
write(fd, pic_mem, 800*480*4); /* 写位置,来源,需要写多少 */
/* LCD 颜色8:8:8:8(透明度,红,绿,蓝) */
/* LCD 大小 分辨率 800*480 *4Byte */
/* 故, 写一张图片大小 1.5M */
/* WHITE=0xFFFFFFFF, BLACK=0x00000000 */
/* 关闭文件,回收资源 */
for(delay_time=0x00FFFFFF; delay_time; delay_time--);
}
close(fd);
return 0; /** SUCCESS 0, ERROR -1 */
}
【个人代码,24位图拓展为32位图(多余Byte为透明度控制),没加翻转处理】
果然没有 邓工程师 NB,人家处理的时候带翻转的,那速度可不是一个数量级的。。
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <dirent.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
void delay(unsigned int dt){
int i;
while( dt-- )
for(i=80000; i; i--);
}
char p_tmp[800*480*4];
char picture[800*480*4];
void execute_picture(char picture[]){
int i, j, len = 800*480*3;
for(i=0, j=0; i<len; i++, j++){
if( j%4==3 ){
p_tmp[j] = 0x33;
j++;
}
p_tmp[j] = picture[i];
}
memcpy(picture, p_tmp, 800*480*4);
}
int main(int argc, char **argv){
int fd, fds[100], plen=0;
char printpath[] = "/dev/fb0";
char dir_path[] = "/test";
char tmp_path[123];
DIR * pic_dir = opendir(dir_path);
struct dirent * pic_dirent;
while( ( pic_dirent = readdir( pic_dir ) ) != NULL ){
if( strstr(pic_dirent->d_name, ".bmp") != NULL ){
snprintf(tmp_path, 111, "%s/%s", dir_path, pic_dirent->d_name);
fds[plen] = open(tmp_path, O_RDWR);
if( fds[plen] < 0 ){
perror("ERROR!\n");
return -1;
}
plen++;
}
};
fd = open(printpath, O_RDWR);
if( fd<0 ){
perror("ERROR");
return -1;
}
int i;
while( 1 ){
for(i=0; i<plen; i++){
lseek(fds[i], 54, SEEK_SET);
read(fds[i], picture, 800*480*3);
execute_picture(picture);
write(fd, p_tmp, 800*480*4);
lseek(fd, 0, SEEK_SET);
sleep(3);
}
}
for(i=0; i<plen; i++)
close(fds[i]);
close(fd);
return 0;
}
第二天
图像压缩,按键监控,音频播放
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <dirent.h>
#include <linux/input.h>
char bmp_mem[800*480*3];
char swap_bmp[800*480*3];
char pic_mem[800*480*4];
char narrow_buf[4][400*240*3];
DIR * pic_dir;
struct dirent *pic_dirent;
char pathname[30];
int pic_count;
int main(int argc,char **argv)
{
int fd,bmp_fd[30];
int i=0,j,k,x,y,count;
int key_fd;
struct input_event key_event;
//获取LCD资源
fd = open("/dev/fb0",O_RDWR);
//获取失败处理
if(fd < 0)
{
perror(" open LCD Err !");
return -1;
}
//写屏幕
memset(pic_mem, 0xFF, 800*480*4);
write(fd, pic_mem, 800*480*4);
sleep(3);
//打开目录
pic_dir = opendir("/pic");
//读目录
while( ( pic_dirent = readdir(pic_dir)) != NULL )
{
if(strstr(pic_dirent->d_name,".bmp"))
{
snprintf(pathname,30,"/pic/%s",pic_dirent->d_name);
//打开图片,获取图片操作许可
//打开文件,将文件描述符写入文件描述符数组
bmp_fd[i++] = open(pathname,O_RDWR);
if( bmp_fd[i] <0)
{
perror(" open bmp err ");
return -1;
}
pic_count = i;
}
}
//获取微缩图
for(k=0;k<pic_count;k++)
{
//移动文件读取指针位置,从头部54字节地方开始
lseek(bmp_fd[k],54,SEEK_SET);
//读取图片数据800*480*3+54
read(bmp_fd[k],bmp_mem,800*480*3);
//24bit to 32bit
for(i=0,j=800*480*4-1;i<800*480*3;i+=3,j-=4)
{
pic_mem[j-3] = bmp_mem[i] ;
pic_mem[j-2] = bmp_mem[i+1] ;
pic_mem[j-1] = bmp_mem[i+2] ;
}
//移动显存指针位置,从头部开始
lseek(fd,0,SEEK_SET);
//将读到的图片数据写入LCD
write(fd,pic_mem,800*480*4);
printf(" pic:%d sleep 1 s ,goto next \n",k);
sleep(1);
j=0;
for(y=479;y>=2;y-=2)
for(x=0;x<800*3;x+=3)
{
for(count=0;count<3;count++)
narrow_buf[k][j++] = bmp_mem[y*800*3+x++] ;
}
}
//清屏,白屏
lseek(fd,0,SEEK_SET);
memset(pic_mem,0xff,800*480*4);
write(fd,pic_mem,800*480*4);
//将微缩图填充到帧图像数组
for(i=0;i<pic_count;i++)
{
j=0;
for(y=0+(i/2)*240;y<240+(i/2)*240;y++)
for(x=0+(i%2)*400*4;x<400*4+(i%2)*400*4;)
{
//.....
}
}
//移动显存指针位置,从头部开始
lseek(fd,0,SEEK_SET);
//将读到的帧图像数据写入LCD
write(fd,pic_mem,800*480*4);
key_fd = open("/dev/event1",O_RDWR);
if(key_fd < 0)
{
perror(" open key err !");
return -1;
}
while(1)
{
read(key_fd,&key_event,sizeof(key_event));
if(key_event.type == EV_KEY)
{
if(key_event.code == KEY_LEFT && key_event.value == 1)
{
//显示放大图片
printf(" KEY_LEFT !\n ");
}
if(key_event.code == KEY_RIGHT && key_event.value == 1)
{
//显示微缩图
printf(" KEY_RIGHT !\n ");
}
}
}
#if 0
//正常循环显示图片
for(k=0;k<pic_count;k++)
{
//移动文件读取指针位置,从头部54字节地方开始
lseek(bmp_fd[k],54,SEEK_SET);
//读取图片数据800*480*3+54
read(bmp_fd[k],bmp_mem,800*480*3);
//24bit to 32bit
for(i=0,j=800*480*4-1;i<800*480*3;i+=3)
{
pic_mem[j-3] = bmp_mem[i] ;
pic_mem[j-2] = bmp_mem[i+1] ;
pic_mem[j-1] = bmp_mem[i+2] ;
j-=4;
}
//移动显存指针位置,从头部开始
lseek(fd,0,SEEK_SET);
//将读到的图片数据写入LCD
write(fd,pic_mem,800*480*4);
//休眠3秒
sleep(3);
}
#endif
//回收资源
close(fd);
close(key_fd);
closedir(pic_dir);
for(i=0;i<pic_count;i++)
close(bmp_fd[i]);
return 0; //成功返回 0 ;失败返回的是负数: -1
}
madplay 音频播放命令
命令格式:
madplay option filename
option:
-v 获取播放时间
-q 不存在任何打印,但现实警告
-Q 不存在任何打印
–downsample 只采用一半数据
-i 忽略CRC校验错误
-o PATH/xx.wav 可以用来转码,将mp3转为wav
也可以是其他格式,见说明;.raw 表示是元素pcm,.hex等
-a 开启衰减音量,增加音量,衰减系统为-175~+18 (当然通过键盘+ —也可以调整音量)
-A 同-a
-1 -2 -m -S 分别指左声道,右声道,双声道,立体声
-s 用于seek播放如:0:1:20:11 ,seek到1小时,2分钟,11秒时开始播放
-t 用于播放时间现在 0:1:20:11 ,播放到1小时,2分钟,11秒时就停止
-z 用于随机播放列表
-r, –repeat[=MAX] 循环播放无限次或Max次
–tty-control enable keyboard controls 默认是使能热键
–no-tty-control disable keyboard controls
热键使用
下一首歌曲; f,或ctrl+n 或者>
上一首歌曲 b ,或ctrl+p 或者<
退出:q, Q,获取ctrl+c
获取播放状态信息: i ?
调节音量: – + _ =
暂停恢复:p
停止:s
【个人代码,图片处理,翻转,压缩,移动】
还是一样的分步处理,邓工程师 可是 处理+翻转 or 处理+翻转+压缩。。。
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <dirent.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>
#include <stdarg.h>
void delay(unsigned int dt){
int i;
while( dt-- )
for(i=80000; i; i--);
}
char p_tmp[800*480*4];
char picture[800*480*4];
char p_pic[800*480*4];
char pcom[16][480*800*4/4];
int s_d[4][2] = { 0*800+0,400, 0*800+400,400, 240*800+0,400, 240*800+400,400 };
void re_row(char s[], char t[], int row, int col){
int i, j;
col *= 4;
for(i=0; i<row; i++)
for(j=0; j<col; j++)
s[ (row-1-i)*col + j ] = t[ i*col + j ];
}
void execute_picture(char picture[]){
int i, j, len = 800*480*3;
for(i=0, j=0; i<len; i++, j++){
if( j%4==3 ){
p_tmp[j] = 0x33;
j++;
}
p_tmp[j] = picture[i];
}
memcpy(picture, p_tmp, 800*480*4);
//re_row(picture, p_tmp, 480, 800);
}
void compress_picture(int bb, char s[], char t[], int row, int col, int rb, int cb){
int i, j, k, len=0;
for(i=row-1; i>=0; i-=rb){
for(j=0; j<col*bb; j+=bb){
for(k=0; k<bb; k++)
s[len++] = t[ i*col*bb + j++ ];
}
}
}
void set_picture(int bb, int no, char s[], char t[], int row, int col, int rb, int cb){
int i, j, k=0, len=0;
for(i=0+(no/rb)*(row/rb); i<(row/rb)+(no/rb)*(row/rb); i++){
for(j=0+(no%cb)*(col/cb); j<(col/cb)+(no%cb)*(col/cb); j++){
for(k=0; k<bb; k++)
s[ (i*col + j)*bb + k ] = t[len++];
}
}
}
int main(int argc, char **argv){
int fd, fds[100], plen=0;
char printpath[] = "/dev/fb0";
char dir_path[] = "/test";
char tmp_path[123];
DIR * pic_dir = opendir(dir_path);
struct dirent * pic_dirent;
while( ( pic_dirent = readdir( pic_dir ) ) != NULL ){
if( strstr(pic_dirent->d_name, ".bmp") != NULL ){
snprintf(tmp_path, 111, "%s/%s", dir_path, pic_dirent->d_name);
fds[plen] = open(tmp_path, O_RDWR);
if( fds[plen] < 0 ){
perror("ERROR!\n");
return -1;
}
plen++;
}
};
fd = open(printpath, O_RDWR);
if( fd<0 ){
perror("ERROR");
return -1;
}
int i=0, cnt, part = 9;
while( 1 ){
for(cnt=0; cnt<part; cnt++){
lseek(fds[i], 54, SEEK_SET);
read(fds[i], picture, 480*800*3);
compress_picture(3, pcom[i], picture, 480, 800, 2, 2);
set_picture(3, cnt, p_pic, pcom[i], 480, 800, 2, 2);
i = (i+1)%plen;
}
execute_picture(p_pic);
lseek(fd, 0, SEEK_SET);
write(fd, p_pic, 800*480*4);
sleep(3);
}
for(i=0; i<plen; i++)
close(fds[i]);
close(fd);
return 0;
}
/*
for(i=0; i<plen; i++){
//srand(time(NULL)); i = rand()%plen;
lseek(fds[i], 54, SEEK_SET);
read(fds[i], picture, 800*480*3);
execute_picture(picture);
//re_row(p_tmp, picture, 480, 800);
compress_picture(picture, p_tmp, 480, 800, 2, 2);
set_picture(p_pic, picture, s_d[i][0], s_d[i][1], 240, 400);
//set_picture(p_pic, picture, (i%2*240*800)+(i%2*400), 400, 240, 400);
}
*/
/*
void compress_picture(char s[], char t[], int row, int col, int rb, int cb){
int i, j, k, len=0;
col *= 4;
cb *= 4;
for(i=0; i<row; i+=rb){
for(j=0; j<col; j+=cb){
for(k=0; k<4; k++){
s[len++] = t[ i*col + j + k ];
}
}
}
}
*/
/*
void set_picture(char s[], char t[], int start, int dis, int row, int col){
int i, j, k;
start *= 4;
dis *= 4;
col *= 4;
for(i=0, k=start; i<row; i++){
for(j=0; j<col; j++, k++){
s[k] = t[ i*col + j ];
}
k += dis;
}
}
*/
【个人代码,按键控制图片缩放】
本来还想加个 缩略图 随机位置显示的,可是没成功 picture_xy() 函数。
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <dirent.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>
#include <stdarg.h>
#include <linux/input.h>
#define PRINT_PATH "/dev/fb0"
#define BUTTON_PATH "/dev/event1"
#define DIR_PATH "/test"
#define PIC_NAME ".bmp"
#define MUSIC_NAME ".mp3"
#define MUSIC_PLAY "madplay"
#define MUSICS "1.mp3"
int fd, fkey;
int options;
int pics[100], pic_count=0;
char nametmp[123];
char picture[480*800*4];
char p_tmp[480*800*4];
char part[16][480*800*3];
char pic_now[480*800*4];
struct input_event key_event;
void execute_picture(char picture[]){
int i, j, len = 800*480*3;
for(i=0, j=480*800*4-1; i<800*480*3; i+=3){
p_tmp[j-3] = picture[i];
p_tmp[j-2] = picture[i+1];
p_tmp[j-1] = picture[i+2];
j -= 4;
}
memcpy(picture, p_tmp, 480*800*4);
/*
for(i=0, j=0; i<len; i++, j++){
if( j%4==3 ){
p_tmp[j] = 0x33;
j++;
}
p_tmp[j] = picture[i];
}
memcpy(picture, p_tmp, 800*480*4);
*/
//re_row(picture, p_tmp, 480, 800);
}
void execute_picture000(char picture[]){
int i, j, len = 800*480*3;
for(i=0, j=0; i<len; i++, j++){
if( j%4==3 ){
p_tmp[j] = 0x33;
j++;
}
p_tmp[j] = picture[i];
}
memcpy(picture, p_tmp, 800*480*4);
}
void re_row(char s[], char t[], int row, int col){
int i, j;
col *= 4;
for(i=0; i<row; i++)
for(j=0; j<col; j++)
s[ (row-1-i)*col + j ] = t[ i*col + j ];
}
void compress_picture(int bb, char s[], char t[], int row, int col, int rb, int cb){
int i, j, k, len=0;
for(i=row-1; i>=0; i-=rb){
for(j=0; j<col*bb; j+=bb){
for(k=0; k<bb; k++)
s[len++] = t[ i*col*bb + j++ ];
}
}
}
void xy_picture(int bb, int x, int y, char s[], char t[], int dis, int row, int col){
int i, j, now=0, len=0;
for(i=0; i<row; i++){
for(j=0; j<col*bb; j++){
s[ i*col*bb + j + now ] = t[len++];
}
now += dis*bb;
}
}
void set_picture(int bb, int no, char s[], char t[], int row, int col, int rb, int cb){
int i, j, k=0, len=0;
for(i=0+(no/rb)*(row/rb); i<(row/rb)+(no/rb)*(row/rb); i++){
/*
for(j=0+(no%cb)*(col/cb)*bb; j<(col/cb)*bb+(no%cb)*(col/cb)*bb; j++){
for(k=0; k<3; k++)
s[i*col + j] = t[len++];
j++;
}
*/
for(j=0+(no%cb)*(col/cb); j<(col/cb)+(no%cb)*(col/cb); j++){
for(k=0; k<bb; k++)
s[ (i*col + j)*bb + k ] = t[len++];
}
}
}
void picture_origin(int pic_fd){
lseek(pic_fd, 54, SEEK_SET);
read(pic_fd, picture, 480*800*3);
execute_picture(picture);
lseek(fd, 0, SEEK_SET);
write(fd, picture, 480*800*4);
}
void picture_mini(int pic_fd){
int i;
lseek(pic_fd, 54, SEEK_SET);
read(pic_fd, picture, 480*800*3); /* 24bit */
compress_picture(3, p_tmp, picture, 480, 800, 2, 2);
for(i=0; i<4; i++){
set_picture(3, i, picture, p_tmp, 480, 800, 2, 2);
}
execute_picture000(picture);
//re_row(picture, pic_now, 480, 800);
lseek(fd, 0, SEEK_SET);
write(fd, picture, 480*800*4);
}
void picture_xy(int pic_fd){
int i, x, y, color;
x = rand()%240;
y = rand()%400;
color = (char)(rand()%256);
lseek(pic_fd, 54, SEEK_SET);
read(pic_fd, picture, 480*800*3); /* 24bit */
compress_picture(3, p_tmp, picture, 480, 800, 2, 2);
memset(picture, (char)color, 480*800*3);
xy_picture(3, x, y, picture, p_tmp, 800/2, 480, 800);
execute_picture000(picture);
//re_row(picture, pic_now, 480, 800);
lseek(fd, x*800*4+y*4, SEEK_SET);
write(fd, picture, 480*800*4);
}
int no;
void solve(int pic_fd){
read(fkey, &key_event, sizeof(key_event));
if( key_event.type == EV_KEY ){
if( key_event.code == KEY_LEFT && key_event.value == 1 ){
puts("KEY_LEFT");
no = (no+1)%pic_count;
options = 0;
}
else if( key_event.code == KEY_RIGHT && key_event.value == 1 ){
puts("KEY_RIGHT");
no = (no+1)%pic_count;
options = 1;
}
else if( key_event.code == KEY_DOWN && key_event.value == 1 ){
puts("KEY_DOWN");
no = (no+1)%pic_count;
options = 2;
}
else if( key_event.code == KEY_UP && key_event.value == 1 ){
puts("KEY_UP");
snprintf(nametmp, 111, "./%s %s", MUSIC_PLAY, MUSICS);
system(nametmp); //system("./madplay 1.mp3");
}
}
pic_fd = pics[no];
switch( options ){
case 0:
picture_origin(pic_fd);
//sleep(3);
break;
case 1:
picture_mini(pic_fd);
//sleep(3);
break;
case 2:
picture_xy(pic_fd);
//sleep(2);
break;
default:
printf(" hoooooooooo \n");
}
}
int main(){
fd = open(PRINT_PATH, O_RDWR);
if( fd < 0 ){
perror("OPEN PRINT_PATH Error !\n");
return -1;
}
DIR * pic_dir = opendir(DIR_PATH);
struct dirent * pic_dirent;
while( ( pic_dirent = readdir( pic_dir ) ) != NULL ){
if( ( strstr(pic_dirent->d_name, PIC_NAME) ) != NULL ){
snprintf(nametmp, 111, "%s/%s", DIR_PATH, pic_dirent->d_name);
pics[pic_count] = open(nametmp, O_RDWR);
if( pics[pic_count] < 0 ){
perror("OPEN nametmp Error !\n");
return -1;
}
pic_count++;
}
}
fkey = open(BUTTON_PATH, O_RDWR);
if( fkey < 0 ){
perror("OPEN BUTTON_PATH Error !\n");
return -1;
}
int i, j;
srand( time(NULL) );
while( 1 ){
//for(i=0; i<pic_count; i++){
//picture_origin(pics[i]);
solve(pics[no]);
//sleep(1);
//}
}
close(fd);
close(fkey);
return 0;
}
最后,END