开发板随机显示bmp图片
前言
记录一下第一次做了个自己感觉还可以的微小项目,它的效果就是在开发板上可以随机位置显示图片,图片可以是任意大小,但是不要超过开发板大小,那么话不多说,直接开始正餐。
一、开发环境
VScode、wsL(windows下的linux系统)
二、开发工具
GEC6818开发板 800*480
交叉编译工具:arm-linux-gnueabi-5.4.0.tar.xz
串口:secure CRT
传输:tftp技术
三、实现相关
文件IO C语言及其相关函数
四、相关代码
1.显示任意大小图片
代码如下:
//显示任意大小的图片
void show_anybmp(char* bmp_msg, int x_begin, int y_begin, int photo_width, int photo_high)
{
//打开图片
int bmp_fd = open(bmp_msg, O_RDWR);
if(bmp_fd==-1)
{
printf("图片打开失败!\n");
return;
}
//打开液晶屏
int lcd_fd = open("/dev/fb0", O_RDWR);
if(lcd_fd==-1)
{
printf("液晶屏打开失败!\n");
return;
}
//跳过图片头信息的54个字节
lseek(bmp_fd,54,SEEK_SET);
//定义存储空间存储图片信息
char bmp_buf[3];
//定义空间存储由BGR转化为RGB后的图片信息,转化后每一个都表示一个像素
int tran_bmp_buf[photo_high*photo_width];
//读取图片数据
int ret;
int invalid_byte = (4 - (photo_width*3)%4)%4;//保存无效字节,每张图片一行的总字节数都是4的倍数,不够用无效字节补充
for(int i=0; i<photo_high; i++)
{
for(int k=0; k<photo_width; k++)
{
ret = read(bmp_fd, bmp_buf, 3);
if(ret == -1)
{
perror("读取失败!\n");
return;
}
tran_bmp_buf[k+i*photo_width] = 0x00 << 24 | bmp_buf[2] << 16 |
bmp_buf[1] << 8 | bmp_buf[0];//相当于按行读取图片像素点信息
}
lseek(bmp_fd,invalid_byte,SEEK_CUR);
}
//获取液晶屏内存映射的首地址
int* lcd_addr;
lcd_addr = (int*)mmap(NULL, 800*480*4, PROT_READ|PROT_WRITE, MAP_SHARED, lcd_fd, 0);
if (lcd_addr == MAP_FAILED)
{
printf("内存映射失败!\n");
close(bmp_fd);
close(lcd_fd);
return;
}
//清屏
for(int i=0; i<SCREEN_HIGH*SCREEN_WIDTH; i++)
{
lcd_addr[i] = 0x00000000;
}
//往映射的内存填充图片信息
int count=0;
for(int i=0; i<PHOTO_HIGH; i++)
{
for(int k=0; k<PHOTO_WIDTH; k++)
{
lcd_addr[(i+y_begin)*SCREEN_WIDTH + k+x_begin] = tran_bmp_buf[i*PHOTO_WIDTH + k];//寻找开始点
}
}
printf("成功\n");
//解除内存映射
munmap(lcd_addr, 800*480*4);
//关闭图片
close(bmp_fd);
//关闭液晶屏
close(lcd_fd);
}
2.随机显示实现
代码如下:
//运行函数-随机
void operation_rand(char* pathname)
{
int x_begin,y_begin;
srand((unsigned int)time(NULL));//根据时间产生随机种子
while(1)
{
x_begin = rand()%((800 - PHOTO_WIDTH + 1) - 0);//产生0-700随机数,公式:[min,max] rand()%((max-min)+min+1)
y_begin = rand()%((480 - PHOTO_HIGH + 1) - 0);//产生0-361随机数
show_anybmp(pathname, x_begin, y_begin, PHOTO_WIDTH, PHOTO_HIGH);
sleep(1);
}
}
3.屏保显示
代码如下:
//运行函数-屏保
void operation_screen(char* pathname)
{
int x_begin,y_begin;
int array_xy[4][2] = {{363,0}, {700,235}, {383,361},{0,225}};//坐标计算要和图片实际大小来计算
while(1)
{
for(int i=0; i<4; i++)
{
x_begin = array_xy[i][0];
y_begin = array_xy[i][1];
show_anybmp(pathname, x_begin, y_begin, PHOTO_WIDTH, PHOTO_HIGH);
sleep(3);
}
}
}
4.主函数
int main(int argc, char** argv)
{
if(argc != 2)
{
perror("输入一个图片名字!\n");
return -1;
}
operation(argv[1]);
return 0;
}
5.宏定义
// #define X_BEGIN 700
// #define Y_BEGIN 361
#define SCREEN_WIDTH 800
#define SCREEN_HIGH 480
#define PHOTO_WIDTH 100
#define PHOTO_HIGH 119
6.头文件
#ifndef _MYHEAD_H_
#define _MYHEAD_H_
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <error.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <math.h>
#include <dirent.h>
#include <stdbool.h>
#include <time.h>
//#include <linux/errno.h>
//#include <linux/input.h>
#endif
五.效果
##1.随机显示图片
随机显示图片
##2.屏保动画
屏保
六.总结
以上就是今天分享的内容,本文仅仅简单介绍了bmp图片显示,若有错误,欢迎各路大神指正。
备注:虽然不满足彭工(彭龙老师)上课说的小球乱逛,但我照片乱逛应该也算一个想法吧,哈哈哈。