下面是有关BMP图片显示的相关代码及解释,希望对你有所帮助!
目录
BMP图片显示
1. BMP 图像介绍
我们常用的图片格式有很多,一般最常用的有三种: JPEG(或 JPG)、 PNG、 BMP 和 GIF。其中 JPEG (或 JPG)、 PNG 以及 BMP 都是静态图片,而 GIF 则可以实现动态图片。
BMP(全称 Bitmap)是 Window 操作系统中的标准图像文件格式,文件后缀名为“.bmp”,使用非常 广。它采用位映射存储格式,除了图像深度可选以外,图像数据没有进行任何压缩,因此,虽然BMP 图像文件 所占用的空间很大,但是没有失真、 并且解析 BMP 图像简单。
BMP 文件的图像深度可选 lbit、 4bit、 8bit、 16bit、24bit 以及 32bit。
典型的 BMP 图像文件由四部分组成:
①、 BMP 文件头(BMP file header),它包含 BMP 文件的格式、大小、 位图数据的偏移量等信息;
②、位图信息头(bitmap information) ,它包含位图信息头大小、 图像的尺寸、 图像大小、 位平面数、 压缩方式以及颜色索引等信息;
③、调色板(color palette),这部分是可选的,如果使用索引来表示图像, 调色板就是索引与其对应颜 色的映射表;
④、位图数据(bitmap data),也就是图像数据。
BMP 文件头、位图信息头、调色板和位图数据, 总结如下表所示:
数据段名称 | 大小(Byte) | 说明 |
bmp 文件头 (bmp file header) | 14 | 包含 BMP 文件的格式、大小、到位图数据的 偏移量等信息 |
位图信息头 (bitmap information) | 通常为 40 或 56 字节 | 包含位图信息头大小、 图像的尺寸、图像大 小、位平面数、 压缩方式以及颜色索引等信 息; |
调色板 (color palette) | 由颜色索引数决定 | 可选,如果使用索引来表示图像的颜色, 则调 色板就是索引与其对应颜色的映射表; |
位图数据 (bitmap data) | 由图像尺寸决定 | 图像数据 |
一般常见的图像都是以 16 位(R、 G、 B 三种颜色分别使用 5bit、 6bit、 5bit 来表示)、 24 位(R、 G、 B 三种颜色都使用 8bit 来表示) 图像为主,我们称这样的图像为真彩色图像, 真彩色图像是不需要调色板 的,即位图信息头后面紧跟的就是位图数据了。
RGB
在 24bits 中,低 8 位表示 Blue 分量;中 8 为表示 Green 分量;高 8 位表示 Red 分量。而在 32bpp-RGB 中,低 24 位的编码方式与 24bpp 位图相同,最高 8 位用来表示透明度 Alpha 分量。32bpp 的位图尺寸太大,一般只有在图像处理的中间过程中使用。对于需要半透过效果的图像,更好的选择是 PNG 格式。
2. 在 LCD 上显示 BMP 图像
下面是一个简单的bmp图片显示代码,每行代码有对应的注释,条理清晰,看不懂的可以在评论区讨论。
示例代码
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <linux/fb.h>
int main()
{
struct fb_fix_screeninfo fb_fix; //固定参数信息
struct fb_var_screeninfo fb_var; //可变参数信息
unsigned int size; //定义无符号屏幕缓冲区大小
unsigned char bmpbuf[1024*600*3]; //定义一个数组用以存储图片信息
//step1. 打开图片
int bmpfd = open("./test.bmp", O_RDWR);
if(bmpfd == -1) //打开失败
{
perror("open bmp error");
exit(-1);
}
//step2. 读图片信息
lseek(bmpfd, 54, SEEK_SET); //跳过文件头信息
read(bmpfd, bmpbuf, 1024*600*3); //读取图片上的像素点 1024*600*24/8
//step3. 显示图片信息,打开LCD(显示屏)
int lcdfd = open("/dev/fb0", O_RDWR); //可读可写
if(lcdfd < 0)
{
perror("open lcd error");
exit(-1);
}
//获取显示屏信息并存储
ioctl(lcdfd, FBIOGET_VSCREENINFO, &fb_var);
ioctl(lcdfd, FBIOGET_FSCREENINFO, &fb_fix);
size = fb_fix.line_length * fb_var.yres; //屏幕显示缓冲区的大小
int width = fb_var.xres; //屏幕的水平分辨率
int height = fb_var.yres; //屏幕的垂直分辨率
int i = 0;
//step4. 数据处理转化为RGB存储格式
unsigned int lcdbuf[1024*600]; //定义一个数组用以存放转换后的像素点数据ARGB B G R A
for(i=0; i<1024*600; i++)
{
//将每一个像素点进行转换
// blue + green + red + a
lcdbuf[i] = bmpbuf[3*i] | bmpbuf[3*i+1]<<8 | bmpbuf[3*i+2]<<16 | 0<<24;
}
//step5. 内存映射
int *screen = mmap(NULL, size, PROT_WRITE | PROT_READ, MAP_SHARED, lcdfd, 0);
if(screen == NULL)
{
perror("mamp error");
exit(-1);
}
//step6. 数据写入
int x,y;
for(y = 0; y < 600; y++)
{
for(x = 0; x<1024; x++)
{
*(screen + x + y*1024) = lcdbuf[(599-y)*1024 + x];
}
}
munmap(screen, size); // 取消映射
close(bmpfd); // 关闭bmp文件
close(lcdfd); //关闭lcd显示屏
return 1;
}
3.准备BMP图片
准备一张像素为1024*600的BMP图片,并将它命名为“test.bmp”,你可以在画图工具中设置属性并导出bmp图片。
4. 在开发板上测试
在Linux终端进行交叉编译生成可执行文件
在SecureCRT软件拷贝文件,给执行权限,运行程序
如果喜欢请不吝给予三连支持!