framebuffer 对 (1bpp)BMP 图片的支持

关于bmp的相关文件格式及其知识,可以参考http://blog.chinaunix.net/u/21684/showart_1332660.html

 

这里主要说下Framebuffer对于1bpp BMP文件的显示的实现。

 

按照文件格式,将图片数据复制到framebuffer,可以显示垂直和水平的线条,但是斜线显示就会出现问题。后来经过比对发现这个现象的原因,比如说要在framebuffer的左上角(0,0)显示一个亮点,那framebuffer的第一个字节应该位0x01.而对于bmp图片来说,如果要在图片的左上角显示一个亮点,则在bmp文件中的图片数据区的对应字节(最后一行第一个字节)应该位0x80。也就是说当把图片的数据按照格式复制到framebuffer时候,对于相同意义的显示内容,他们每个字节的高低位完全相反,所以在display的时候, 需要对图片数据区内容的每个字节进行转换,具体实现可以不一样。

 

对于单色图片的显示定位,也需要考虑移位,因为当显示的像素位置不是一个字节开始的时候,就需要对于该行的数据进行相应移位,移位的时候需要注意 c语言中的潜在的类型转换,一定要确定移位的结果是自己预先想要的。另外一个就是每行的第一字节,需要和framebuffer原有的数据进行比对,然后输出。

 

### 在GCE6818开发板上显示或存储BMP图片的方法 要在GCE6818开发板上显示或存储BMP图片,可以通过以下方法实现: #### 一、显示BMP图片 要实现在GCE6818开发板上显示BMP图片的功能,通常需要完成以下几个核心部分的操作。 1. **打开并读取BMP文件** 使用标准C库中的`open()`函数来打开指定的BMP文件,并通过`read()`函数将其内容读取到缓冲区中。此过程涉及解析BMP文件头以提取图像的关键参数(如宽度、高度和颜色深度)。这些信息对于后续绘制至关重要[^1]。 2. **映射LCD设备内存** 需要将LCD设备文件(通常是`/dev/fb0`)映射至进程地址空间以便直接访问显存区域。这一步骤可通过`mmap()`系统调用来完成。例如,在初始化阶段需设置好帧缓冲器大小以及保护权限等属性[^2]。 3. **绘制像素数据** 将解码后的RGB值逐点写入已映射的显存区域内即可呈现目标图形对象于屏幕上。具体而言就是遍历整个位图矩阵并将每个像素的颜色值赋给对应的显存单元位置。 以下是用于显示 BMP 图像的一个简化版代码片段: ```c #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <unistd.h> #include <sys/mman.h> void show_bmp(const char *filename) { int fd = open(filename, O_RDONLY); if (fd == -1) { perror("Failed to open file"); return; } struct stat st; fstat(fd, &st); unsigned char *buffer = malloc(st.st_size); read(fd, buffer, st.st_size); // 假设我们已经知道如何解析 BMP 头部结构... int width = *(int *)(buffer + 18); // 宽度偏移量为 18 字节 int height = *(int *)(buffer + 22); // 高度偏移量为 22 字节 short bpp = (*(short *)(buffer + 28)) / 8; // BPP 换为字节数 printf("Image size: %dx%d\n", width, height); int lcd_fd = open("/dev/fb0", O_RDWR); if (lcd_fd == -1) { perror("Failed to open framebuffer device"); free(buffer); close(fd); return; } int screen_width = 800; // 屏幕分辨率假设为 800x480 int screen_height = 480; void *fb_ptr = mmap(0, screen_width * screen_height * 4, PROT_READ | PROT_WRITE, MAP_SHARED, lcd_fd, 0); for (int y = 0; y < height && y < screen_height; ++y) { for (int x = 0; x < width && x < screen_width; ++x) { int offset_in_bitmap = ((height - 1 - y) * width + x) * bpp; int offset_in_fb = (y * screen_width + x) * 4; fb_ptr[offset_in_fb + 0] = buffer[offset_in_bitmap + 2]; // R fb_ptr[offset_in_fb + 1] = buffer[offset_in_bitmap + 1]; // G fb_ptr[offset_in_fb + 2] = buffer[offset_in_bitmap + 0]; // B } } munmap(fb_ptr, screen_width * screen_height * 4); free(buffer); close(lcd_fd); close(fd); } ``` --- #### 二、存储BMP图片 如果希望在GCE6818开发板上保存一张新的BMP图片,则主要考虑两个方面的工作流程设计思路如下所示: 1. 创建一个新的空白BMP文件模板; 2. 设置必要的头部字段值比如尺寸规格等等基本信息填充进去之后再把实际待记录下来的彩色图案按照一定顺序排列组合形成最终完整的比特流形式输出保存下来成为正式可用的标准格式化版本文件实例[^4]. 下面给出一段简单的示例程序演示如何创建一个纯色矩形作为测试用的小型 bmp 文件: ```c #include <stdint.h> #include <string.h> typedef uint8_t BYTE; // Define BMP header structures #pragma pack(push, 1) struct BitmapFileHeader { uint16_t type; // Magic number ('BM') uint32_t fileSize; // File size in bytes uint16_t reserved1; // Reserved field (set to zero) uint16_t reserved2; // Reserved field (set to zero) uint32_t pixelArrayOffset;// Offset from start of file to image data }; struct BitmapInfoHeader { uint32_t headerSize; // Size of this structure int32_t width; // Image width in pixels int32_t height; // Image height in pixels uint16_t planes; // Number of color planes (must be set to 1) uint16_t bitsPerPixel; // Bits per pixel (e.g., 24bpp means RGB format) }; #pragma pack(pop) void save_bmp(const char *filename, int w, int h, const void *pixels) { FILE *f = fopen(filename, "wb"); struct BitmapFileHeader bfhdr = { .type=0x4D42 }; struct BitmapInfoHeader bihdr = {}; memset(&bfhdr, 0, sizeof(bfhdr)); memset(&bihdr, 0, sizeof(bihdr)); bfhdr.fileSize = sizeof(struct BitmapFileHeader) + sizeof(struct BitmapInfoHeader) + w*h*3; bfhdr.pixelArrayOffset = sizeof(struct BitmapFileHeader) + sizeof(struct BitmapInfoHeader); bihdr.headerSize = sizeof(struct BitmapInfoHeader); bihdr.width = w; bihdr.height = h; bihdr.planes = 1; bihdr.bitsPerPixel = 24; fwrite(&bfhdr, sizeof(bfhdr), 1, f); fwrite(&bihdr, sizeof(bihdr), 1, f); fwrite(pixels, w*h*3, 1, f); fclose(f); } int main() { int w = 100, h = 100; BYTE img[w][h][3]; for (int i = 0; i < w; ++i) { for (int j = 0; j < h; ++j) { img[i][j][0] = 255*(i%2==0 ? 1 : 0); // Red component alternating pattern img[i][j][1] = 0; // Green always off img[i][j][2] = 0; // Blue also off } } save_bmp("test.bmp", w, h, img); return 0; } ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值