1)24位bmp的特点
① 三原色排列顺序(相反) √
② 系统在存放bmp图片的时候,纵方向反正存放。 (控制y变量:当y=0,改成y=479) 479-y √
③ 右边的一小列像素点被挤到了左边。
24位bmp图片文件中前54个字节不是存放像素点,存放了图片本身的属性信息(头信息),
这些信息不是像素点,不需要给映射指针。
24位bmp图片字节大小 = __像素点总字节___+__头信息54个字节___;
实现鸡蛋在极品屠龙上面跑起来
#include <stdio.h>
#include <error.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <unistd.h>
#include<time.h>
#include <fcntl.h>
/*结构体类型*/
typedef struct lcd_dis_inf
{
char *TQ;
int skip;
int lcd_fd;
int *mmap_start;
int bmp_h, bmp_w;
int mmap_offset;
int g;
} * LDI;
/*函数的申明*/
LDI Dis_Init();
LDI Displaying(LDI ldi, const char *bmp_path);
LDI Dis_Free(LDI ldi);
LDI Dis_Init()
{
LDI ldi = (LDI)malloc(sizeof(struct lcd_dis_inf));
if (ldi == NULL)
{
perror("init malloc");
return (LDI)-1;
}
memset(ldi, 0, sizeof(struct lcd_dis_inf));
ldi->lcd_fd = open("/dev/fb0", O_RDWR);
if (ldi->lcd_fd == -1)
{
perror("init open");
return (LDI)-1;
}
ldi->mmap_start = mmap(NULL, 800 * 480 * 4, PROT_READ | PROT_WRITE, MAP_SHARED, ldi->lcd_fd, 0);
if (ldi->mmap_start == MAP_FAILED)
{
perror("init mmap");
return (LDI)-1;
}
return ldi;
}
LDI Displaying(LDI ldi, const char *bmp_path)
{
printf("输入速度");
scanf("%d",&ldi->g);
getchar();
//先打开 图片
int bmp_fd = open(bmp_path, O_RDONLY);
if (bmp_fd == -1)
{
perror("display open");
return (LDI)-1;
}
//先偏移到第18个字节
lseek(bmp_fd, 18, SEEK_SET);
read(bmp_fd, &(ldi->bmp_w), 4); //获取宽度
read(bmp_fd, &(ldi->bmp_h), 4); //获取高度
printf("图片w:%d---h:%d\n", ldi->bmp_w, ldi->bmp_h);
//判断宽度是不是4的倍数 (宽度是w*3)
if (ldi->bmp_w * 3 % 4 == 0)
{
ldi->skip = 0;
}
else
{
ldi->skip = 4 - (ldi->bmp_w * 3 % 4);
}
ldi->TQ = (char *)malloc(ldi->bmp_w * ldi->bmp_h * 3 + (ldi->skip * ldi->bmp_h)); //给铁锹申请空间
if (ldi->TQ == NULL)
{
perror("display malloc");
return (LDI)-1;
}
/*可以在这里清空malloc对应的空间*/
lseek(bmp_fd, 54, SEEK_SET);
read(bmp_fd, ldi->TQ, ldi->bmp_w * ldi->bmp_h * 3 + (ldi->skip * ldi->bmp_h));
//
int a[ldi->bmp_h * ldi->bmp_w];
int n = 0;
for (int i = 0; i < 480; i++)
{
for (int j = 0; j < 800; j++, n += 3)
{
*(a + 800 * (ldi->bmp_h - 1 - i) + j) = ldi->TQ[n] << 0 |
ldi->TQ[n + 1] << 8 |
ldi->TQ[n + 2] << 16;
}
n += ldi->skip;
}
//将屠龙设置为背景,如果要让球跳动应该让背景图和蛋黄图同时画
int x0 = 100, y0 = 150, r_max = 50, r_min = 25;
//让蛋黄东的前提肯定是让他的圆心动,圆心满足的条件实际上是一个正方形
srand(time(0));
while (1)
{
if (x0 < (800 - r_max) && (x0 > r_max) && (y0 < 480 - r_max) && (y0 > r_max))
{
for (int y = 0; y < 480; y++)
{
for (int x = 0; x < 800; x++)
{
if ((x - x0) * (x - x0) + (y - y0) * (y - y0) < r_max * r_max)
{
if ((x - x0) * (x - x0) + (y - y0) * (y - y0) < r_min * r_min)
*(ldi->mmap_start + 800 *(479 - y) + x) = 0xffff00;
else
*(ldi->mmap_start + 800 *(479 - y) + x) = 0xffffff; //画蛋白
}
else
{
*(ldi->mmap_start + 800 * (479 - y) + x) = *(a + 800 * (ldi->bmp_h - 1 - y) + x);
}
}
}
}else{
x0=rand()%500;
y0=rand()%500;
}
x0=x0+ldi->g;
y0=y0+ldi->g;
}
free(ldi->TQ);
close(bmp_fd);
return (LDI)0;
}
LDI Dis_Free(LDI ldi)
{
close(ldi->lcd_fd);
munmap(ldi->mmap_start, 800 * 480 * 4);
free(ldi);
return (LDI)0;
}
int main()
{
LDI ldi = Dis_Init();
if (ldi == (LDI)-1)
{
printf("init error!\n");
return -1;
}
Displaying(ldi, "/IOT/jptl.bmp");
LDI dis_free_ret = Dis_Free(ldi);
if (dis_free_ret == (LDI)-1)
{
printf("free error!\n");
return -1;
}
return 0;
}