一、现象:
基于6818开发板的BMP图片播放器
二、直接上代码:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
#include <sys/mman.h>
#include <linux/input.h>
int *plcd,*lcd_p;
int lcd_fd;
unsigned char bmppath[128][128]={
"./pictures/1.bmp",
"./pictures/2.bmp",
"./pictures/3.bmp",
"./pictures/4.bmp",
"./pictures/5.bmp",
"./pictures/6.bmp",
"./pictures/7.bmp",
"./pictures/8.bmp",
};
void *lcd_init(){
lcd_fd=open("/dev/fb0",O_RDWR);
if(lcd_fd==-1){
perror("open lcd_file error\n");
return MAP_FAILED;
}
plcd=(int *)mmap(NULL,
800*480*4,
PROT_READ|PROT_WRITE,
MAP_SHARED,
lcd_fd,
0
);
return plcd;
}
int uninit_lcd(){
close(lcd_fd);
if(munmap(lcd_p,800*480*4)==-1){
return -1;
}
return 0;
}
void lcd_draw_point(int x,int y,int color){
*(plcd+y*800+x) = color;
}
// 绘图(BMP格式)
// 下面的代码几乎是一套模板,照着抄就行
// 培训老师给的代码 ^_^
void LCD_DrawBMP(int x,int y,const char *bmpname){
unsigned char buf[4]={0};
int fd = open(bmpname,O_RDONLY);
if(fd == -1){
perror("open bmp file failed:");
return;
}
lseek(fd,0,SEEK_SET);
int ret=read(fd,buf,2);
if(ret!=2){
perror("LCD_DrawBMP-read bmp picture-error");
return;
}
// 首先判断它是不是一个BMP图片
if(buf[0]!=0x42 || buf[1]!=0x4D){
printf("This image format is not bmp!\n");
return;
}
// 读位图宽度
int bmp_w=0;
lseek(fd,0x12,SEEK_SET);
ret=read(fd,&bmp_w,4);
if(ret!=4){
perror("read picture width error");
return ;
}
// 读位图高度
int bmp_h=0;
lseek(fd,0x16,SEEK_SET);
ret=read(fd,&bmp_h,4);
if(ret!=4){
perror("read picture length error");
return;
}
// 读位图色深
int bmp_colordepth=0;
lseek(fd,0x1C,SEEK_SET);
ret=read(fd,&bmp_colordepth,2);
if(ret!=2){
perror("read picture colordepth error");
return;
}
//printf("bmp:%ld*%ld*%ld\n",bmp_w,bmp_h,bmp_colordepth);
// 下面的代码用来读像素数组内容,并通过画点函数画出来
lseek(fd,54,SEEK_SET);// 把光标偏移到像素数组位置
int i,j;
for(i=0;i<bmp_h;i++){
for(j=0;j<bmp_w;j++){
int color=0;
read(fd,&color,bmp_colordepth/8);
lcd_draw_point(x+j,y+(bmp_h>0?(bmp_h-1-i):i),color);//位图高度为正数时,会上下颠倒存放数据
}
lseek(fd,(4-bmp_colordepth/8*bmp_w%4)%4,SEEK_CUR);//跳过无用数据
}
close(fd);
}
// 获取点击屏幕的坐标
int get_coordinate(int *x,int *y){
struct input_event et;
int fd = open("/dev/input/event0",O_RDONLY);
if(fd == -1){
perror("open even0 failed");
return -1;
}
while(1){
int r = read(fd,&et,sizeof et);
if(r == sizeof et){
if(et.type==EV_ABS && et.code==ABS_X){
*x = et.value; // 保存x坐标
}
if(et.type==EV_ABS && et.code==ABS_Y){
*y=et.value; // 保存y坐标
}
if(et.type==EV_KEY&&et.code==BTN_TOUCH&&et.value==0){
close(fd);
return 0;
}
}
else {
perror(" get_coordinate-read-error");
return -1;
}
}
return 0;
}
int main()
{
lcd_p=lcd_init();
if(lcd_p == MAP_FAILED){
perror(" lcd_init error\n");
return -1;
}
else printf("lcd init succuss!\n");
LCD_DrawBMP(0,0,"./pictures/-1.bmp");
int i=-1;
while(1){
int x,y;
// 得到点击屏幕处的坐标
get_coordinate(&x,&y);
printf("x=%d y=%d\n",x,y);
// x和y的范围可以自己试出来,不一定要和我的一样
if(x>=0&&x<=280&&y>=515&&y<=600){
usleep(5000);
i--;
if(i<0) i=7;
printf("use picture %d\n\n",i);
LCD_DrawBMP(0,0,bmppath[i]);
}
else if(x>=745&&x<=1030&&y>=515&&y<=600){
usleep(5000);
i++;
if(i>7) i=0;
printf("use picture %d\n\n",i);
LCD_DrawBMP(0,0,bmppath[i]);
}
}
if(uninit_lcd()==-1){
perror("munmap error!\n");
return -1;
};
return 0;
}
三、打包文件:
// 使用方式
先在终端输入命令:chmod 777 kezhixingwenjian
再输入:./kezhixingwenjian