粤嵌实习(电梯运行演示系统)

了解并使用bmp图片和交叉开发

bmp文件格式

bitmap文件头(14字节):

偏移量大小用途
0000H2字节用于标识BMP和DIB文件的魔数,一般为0x42 0x4D
0002H4字节BMP文件的大小(单位为字节)
0006H2字节保留,实际值因创建程序而异
0008H2字节保留,实际值因创建程序而异
000AH4字节位图数据(像素数组)的地址偏移,也就是起始地址。

DIB头(40字节):

偏移量大小用途
OEH4字节该头结构的大小(40字节)
12H4字节位图宽度,单位为像素(有符号整数)
16H4字节位图宽度,单位为像素(有符号整数)
1AH2字节色彩平面数,只有1为有效值
1CH2字节每个像素所占位数,即图像的色深,典型值为1、4、8、16、24和32
1EH4字节所使用的的压缩方法
22H4字节图像大小。原指位图数据的大小,与文件大小不是同一概念
26H4字节图像的横向分辨率,单位为像素每米(有符号整数)
2AH4字节图像的纵向分辨率,单位为像素每米(有符号整数)
2EH4字节调色板的颜色数,为0时表示颜色数为默认的2的色深数次方个
32H4字节重要颜色数,为0时表示所有颜色都是重要的,通常不使用本项

调色板(颜色值数组)

像素数组:这部分逐个像素表示图像,每一个像素使用一个或多个字节表示。通常像素是从上到下,从左到右保存的。

应用:读取一张图片的数据

先在共享文件夹下存放一张图片。

编写代码读取图片信息并打印。

int fd = open("./kkk.bmp",O_RDONLY);//共享文件夹下的图片
 if(fd == -1)
 {
  perror("open bmp error:");
  return -1;
 }
	unsigned char buf[64] = {0};
	read(fd,buf,64);

 //操作
 //判断是否为BMP图片
 if(buf[0] != 0x42 || buf[1] != 0x4d)
 {
  printf("NO\n");
  close(fd);
  return -1;
 }
 printf("Yes\n");
}

    //bmp图片信息的读取
	int fd = open(bmpname,O_RDWR);
	int size,width,high;
    short depth;     //两个字节
	lseek(fd,2,SEEK_SET);
	read(fd,&size,4);//读取图片的大小
	lseek(fd,0x12,SEEK_SET);
	read(fd,&width,4);//读取图片的宽度
	lseek(fd,0x16,SEEK_SET);
	read(fd,&high,4);//读取图片的高度
	lseek(fd,0x1C,SEEK_SET);
	read(fd,&depth,2);//读取图片的色深
	printf("bmp size=%d width=%d high = %d depth=%d\n",size,width,high,depth);

结果如下:

在这里插入图片描述

交叉开发:

1.连接与配置

(1)连接好开发板,启动开发板。

(2)打开设备管理器,查找识别出的端口号。

在这里插入图片描述

​ 若不能正确识别端口号,则需要安装驱动。

在这里插入图片描述

(3)使用SecureCRT软件来对开发板进行终端控制。

在这里插入图片描述

(4)打开SecureCRT.exe文件,连接开发板。

在这里插入图片描述

连接成功:

在这里插入图片描述

(5)创建工作文件夹。

①先删除home目录下的所有文件。

cd /home 
rm -rf *

②创建并进入自己的工作文件夹,下次使用开发板先进入此文件夹。

mkdir /home/117
cd /home/117

如下:

在这里插入图片描述

2.在开发板上运行一个程序

(1)编辑一个C文件,并保存到共享文件夹中。

(2)将其在虚拟机中编译成开发板上可执行文件。

如:

arm-linux-gcc hello.c -o hello

在这里插入图片描述

(3)传送可执行文件到开发板上,并执行。

rx 可执行文件名

chmod 0777 可执行文件名

./可执行文件名

在这里插入图片描述

应用:读取图片的数据并显示到开发板上

开发板屏幕为800*480。

定义BMP数据结构:

//定义一个bmp图片信息相关的结构体类型
typedef struct BMP
{
    char* bmpname;          //保存bmp图片的名称
    int size;               //文件的总大小
    int width;              //文件的宽
    int height;             //文件的高
    short bpp;              //色深
    char* data;             //像素数组的首地址
}BMP;

定义相关要用到的函数:

//屏幕初始化
void lcd_init();
//解除屏幕初始化
void lcd_uninit();
//画点
void lcd_point(int x,int y,int color);
//获取bmp图片信息
BMP get_bmp_info(char* bmpname);
//画一张bmp图片
void lcd_draw_bmp(char* bmpname, int x, int y);

全部写在bmp.h文件中,具体文件内容如下:

#ifndef __BMP_H
#define __BMP_H

#include <stdio.h>
#include <stdlib.h>
//open
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
//mmap
#include <sys/mman.h>
//close,read,write
#include <unistd.h>

//定义一个bmp图片信息相关的结构体类型
typedef struct BMP
{
    char* bmpname;          //保存bmp图片的名称
    int size;               //文件的总大小
    int width;              //文件的宽
    int height;             //文件的高
    short bpp;              //色深
    char* data;             //像素数组的首地址
}BMP;

//屏幕初始化
void lcd_init();
//解除屏幕初始化
void lcd_uninit();
//画点
void lcd_point(int x,int y,int color);
//获取bmp图片信息
BMP get_bmp_info(char* bmpname);
//画一张bmp图片
void lcd_draw_bmp(char* bmpname, int x, int y);

#endif

①读取所有像素点的信息。

BMP get_bmp_info(char* bmpname)
{
	//可以下载其他格式的图片,在电脑自带的图片编辑中,将图片的像素进行调整,另存为bmp(24位)图片即可
	//size --> 0x02 - 4字节   宽 --> 0x12 -- 4字节  高 ->> 0x16 -- 4字节      色深 ->> 0x1c -- 2字节
	int fd_bmp = open(bmpname, O_RDONLY);//写入bmp文件名
	if (fd_bmp == -1)
	{
		printf("open bmp error\n");
		exit(1);
	}
    //判断是否是bmp文件
	char bm[2] = {0};
	read(fd_bmp, bm, 2);
	if (!(bm[0] == 'B' && bm[1] == 'M'))
	{
	printf("%s is not a bmp file\n", bmpname);
	exit(1);
	}
	
BMP bmp;
bmp.bmpname = bmpname;

//大小
lseek(fd_bmp, 0x02, SEEK_SET);
read(fd_bmp, &bmp.size, 4);

//宽
lseek(fd_bmp, 0x12, SEEK_SET);
read(fd_bmp, &bmp.width, 4);
//高
read(fd_bmp, &bmp.height, 4);
//色深
lseek(fd_bmp, 0x1c, SEEK_SET);
read(fd_bmp, &bmp.bpp, 2);

//开辟一块空间用来保存像素数组
bmp.data = (char*)malloc(bmp.size - 54);
lseek(fd_bmp, 0x36, SEEK_SET);
read(fd_bmp, bmp.data, (bmp.size-54));

close(fd_bmp);
return bmp;
}

②将图片显示到开发板上。

void lcd_draw_bmp(char* bmpname, int x, int y)
{
	BMP bmp = get_bmp_info(bmpname);
	//打印图片的基本信息
	printf("bmpname = %s, size = %d, width = %d, height = %d, bpp = %hd\n", 
			bmp.bmpname, bmp.size, bmp.width, bmp.height, bmp.bpp);

	//一行的有效字节数
	int line_types = abs(bmp.width) * bmp.bpp / 8;

	//一行的填充字节数
	int pad_types = (line_types % 4 == 0) ? 0 : (4 - (line_types % 4));

	int color;
	char* p = bmp.data; //遍历指针,遍历整个像素数组

	//解析像素数组中的数据并画到开发板上
	for (int h = 0; h < abs(bmp.height); h++) //表示行
	{
		for (int w = 0; w < abs(bmp.width); w++) //表示列
		{
			char b = *(p++);
			char g = *(p++);
			char r = *(p++);
			char a = (bmp.bpp == 24) ? 0 : *(p++);

			color = a << 24 | r << 16 | g << 8 | b;

			// width > 0 : 从左到右保存每一个像素点
            // width < 0 : 从右到左保存每一个像素点
			// height > 0: 从下到上保存每一个像素点
            // height < 0: 从上到下保存每一个像素点

			int m =x+(bmp.width>0?w:(bmp.width-1-w));
			int n =y+(bmp.height<0?h:(bmp.height-1-h));

			lcd_point(m, n, color);
		}
		p += pad_types;//跳过填充字节
	}

③编译运行程序

1.先在linux下编译程序。

​ 此处采用了gcc编译同时编译多个c文件,需将各个.c文件和.h文件放在同一个文件夹下。

在这里插入图片描述

2.向工作文件夹中传入所需的图片(此处已经传入在开发板中文件名为bg1的图片bg1.bmp)

在这里插入图片描述

在这里插入图片描述

3.传入并执行文件。

在这里插入图片描述

4.结果如下:

在这里插入图片描述

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐