开发板随机显示bmp图片

开发板随机显示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图片显示,若有错误,欢迎各路大神指正。
备注:虽然不满足彭工(彭龙老师)上课说的小球乱逛,但我照片乱逛应该也算一个想法吧,哈哈哈。

  • 11
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值