打印
[RISC-V MCU 创新应用比赛]

沁恒 CH32V103 解码bmp格式位图并显示到12864

[复制链接]
16426|65
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
本帖最后由 gtbestom 于 2021-8-19 17:19 编辑

#申请原创#   @21小跑堂
  在 CH32V103 上移植成功 FATFS 文件系统后,就可以对存储卡里的 电子书,图片,音乐 等文件进行读取了
  每种文件都有特定的格式,记录文件的信息
  就拿 BMP 格式的位图来说
  BMP 文件特定区域记录着文件的 宽度、高度、位深 等信息
  BMP 格式文件 编解码相对简单
  我们化繁为简,长话短说
  先上图,要读取内存卡里的 2 张单色位图,并显示在 oled 12864 上





  图片竖向保存,方便按字节顺序直接显示在 oled 屏上

  BMP 格式文件有个信息头,记录文件的各种信息
  前2字节是 “BM” 标识这是一个 BMP 格式的文件
  长话短说,用结构体表示
//BMP头文件结构体
typedef struct
{
  u16 bfType;           // 文件标志.只对'BM' 0x424D ,用来识别BMP位图类型
  u32 bfSize;                // 文件大小,包括这14个字节
  u16 bfReserved1;      // 保留
  u16 bfReserved2;      // 保留
  u32 bfOffBits;        // 从文件开始到位图数据(bitmap data)开始之间的的偏移量,前三个部分的长度之和
}__attribute__((packed)) BITMAPFILEHEADER;      // 固定14个字节
  这开头的14字节就标识了一些文件信息,紧接着又是固定的40字节
//BMP信息头
typedef struct
{
  u32 biSize;                    // 说明BITMAPINFOHEADER结构所需要的字数
  s32 biWidth;          // 说明图象的宽度,以象素为单位
  s32 biHeight;         // 说明图象的高度,以象素为单位
  u16 biPlanes;         // 为目标设备说明位面数,其值将总是被设为1
  u16 biBitCount;       // 说明比特数/象素,其值为1、4、8、16、24、或32
  u32 biCompression;    // 说明图象数据压缩的类型。其值可以是下述值之一:
                            // BI_RGB:没有压缩;
                            // BI_RLE8:每个象素8比特的RLE压缩编码,压缩格式由2字节组成(重复象素计数和颜色索引);
                            // BI_RLE4:每个象素4比特的RLE压缩编码,压缩格式由2字节组成
                            // BI_BITFIELDS:每个象素的比特由指定的掩码决定。
  u32 biSizeImage;      // 说明图象的大小,以字节为单位。当用BI_RGB格式时,可设置为0
  s32 biXPelsPerMeter;  // 说明水平分辨率,用象素/米表示
  s32 biYPelsPerMeter;  // 说明垂直分辨率,用象素/米表示
  u32 biClrUsed;        // 说明位图实际使用的彩色表中的颜色索引数
  u32 biClrImportant;   //  说明对图象显示有重要影响的颜色索引的数目,如果是0,表示都重要。
}__attribute__((packed)) BITMAPINFOHEADER ;        // 固定40个字节
  进一步说明了文件的各种信息,其中重要的就是 文件宽度 biWidth,高度 biHeight,位深 biBitCount,数据偏移 bfOffBits
  紧接着还有一个颜色对照表,文末再说,不影响单色位图解码
  单色位图也有颜色对照表,但是我发现 Win10 系统不会对照表显示,都是显示黑白两色,所以我们不做对照表
  根据数据偏移 bfOffBits 信息,我们可以直接跳转到图像数据区(跳过 54 字节信息表、n 字节颜色对照表)
  f_lseek(&imginfo->FileInfo, imginfo->OffsetByte);
  读取图像信息
  f_read(&imginfo->FileInfo, Buff, 1024, &cout);
  由于我们使用的是 12864 点阵屏,128x64/8 = 1024 为了简要说明,所以直接读取全部图像数据
  接着对读取的数据进行排列和整理,以防止出现错乱和颠倒
  for(i=0;i<128;i++)
  {
    for(j=0;j<8;j++)
    {
      gd_DispBuf[j][i] = ~SWAP(Buff[i*8+j]);
    }
  }
  SWAP 函数用来交换高低位
  这样处理后,gd_DispBuf 的数据就可以直接写到 OLED12864了

  至于位深更高的 16 色图、256 色图,需要用到颜色对照表
  还有 24 位图,就是我们比较常见的 RGB888 也就是 16,777,216 色图了,24 位图就不需要对照表了,直接读数据显示

  16 色图、256 色图涉及的颜色转换表,也用结构体表示:
  // 彩色表
  typedef struct
  {
    u8 rgbBlue;           // 指定蓝色强度
    u8 rgbGreen;          // 指定绿色强度
    u8 rgbRed;            // 指定红色强度
    u8 rgbReserved;       // 保留,设置为0
  }__attribute__((packed)) RGBQUAD;
  16 色图因为只有 16 种颜色,只需要 16 个对照表,也就是 16x4=64 字节的对照表
  256 色图因为有 256 种颜色,需要 256 个对照表,也就是 256x4=1024 字节的对照表
  获取偏移位置后的图像数据后,不能直接显示,要经过对照表处理,转换成 RGB888 数据,才能正常使用

  24 位图转 RGB565 换算如下
(Buff>>3) | ((Buff[i+1]>>2)<<5) | ((Buff[i+2]>>3))<<11
  256 色转 RGB565 换算如下
(imginfo->ColorTab[Buff].rgbBlue>>3) | ((imginfo->ColorTab[Buff].rgbGreen>>2)<<5) | ((imginfo->ColorTab[Buff].rgbRed>>3)<<11)
  16 色转 RGB565 换算如下

(imginfo->ColorTab[Buff>>4].rgbBlue>>3) | ((imginfo->ColorTab[Buff>>4].rgbGreen>>2)<<5) | ((imginfo->ColorTab[Buff>>4].rgbRed>>3)<<11)
(imginfo->ColorTab[Buff&0x0f].rgbBlue>>3) | ((imginfo->ColorTab[Buff&0x0f].rgbGreen>>2)<<5) | ((imginfo->ColorTab[Buff&0x0f].rgbRed>>3)<<11)

使用特权

评论回复

相关帖子

63
noDevice| | 2025-2-11 17:51 | 只看该作者
oled 4只能显示单一颜色的像素,这是低成本的

使用特权

评论回复
62
星闪动力| | 2024-12-3 20:45 | 只看该作者
屏幕的刷新速度是多少?

使用特权

评论回复
61
AutoMotor| | 2024-11-11 06:26 | 只看该作者
如何从bmp文件中读取一些像素数据并显示出来

使用特权

评论回复
60
流星flash| | 2024-11-7 18:42 | 只看该作者
保存最后解码的数据用于缓冲或直接输出用于显示。,

使用特权

评论回复
59
理想阳| | 2024-10-7 16:00 | 只看该作者
如何显示bmp格式位图tc语言?

使用特权

评论回复
58
AIsignel| | 2024-8-4 13:06 | 只看该作者
如何将bmp图片保存为24位位图格式,

使用特权

评论回复
57
软核硬核| | 2024-7-10 14:07 | 只看该作者
将最后解码的数据保存到缓冲区或直接输出到显示器。

使用特权

评论回复
56
Pretext| | 2024-7-8 20:00 | 只看该作者
bmp格式位图tc语言如何显示?

使用特权

评论回复
55
小夏天的大西瓜| | 2024-4-16 16:00 | 只看该作者
这个应该是提前存储好的相关点位进行显示的

使用特权

评论回复
54
janewood| | 2024-4-8 12:59 | 只看该作者
BMP文件是一种位图图像文件格式,其结构包括位图文件头、位图信息头和位图数据等部分。为了在12864液晶屏上显示,需要提取出位图数据并按照一定的规则进行转换。

使用特权

评论回复
53
pmp| | 2024-4-8 10:42 | 只看该作者
解析 BMP 文件头,获取图像的宽、高、颜色深度等参数。然后将位图数据转换为适合你的显示模块的颜色格式(通常是单色或16位色)。

使用特权

评论回复
52
averyleigh| | 2024-4-7 20:43 | 只看该作者
可以通过观察12864液晶屏上的显示效果来判断解码和显示是否成功。如果显示效果符合预期,那么就可以认为解码和显示过程已经完成。

使用特权

评论回复
51
pl202| | 2024-4-7 18:49 | 只看该作者
BMP文件的数据可能需要转换为适合12864显示的格式。12864是一种典型的液晶显示屏,具有特定的宽高比和显示分辨率。你可能需要将BMP图像的数据进行旋转、缩放或裁剪,以确保它适合显示在12864上。

使用特权

评论回复
50
mnynt121| | 2024-4-7 16:31 | 只看该作者
需要将转换后的数据通过CH32V103的SPI接口发送到12864液晶屏上进行显示。在这个过程中,需要设置好CH32V103的SPI接口参数,确保数据能够正确地传输到液晶屏上。

使用特权

评论回复
49
linfelix| | 2024-4-7 14:40 | 只看该作者
在CH32V103上成功移植了FATFS文件系统。这样您才能从存储卡中读取bmp图片文件。

使用特权

评论回复
48
51xlf| | 2024-4-7 12:27 | 只看该作者
如果BMP文件存储在外部存储器(如SD卡或闪存)上,你需要编写代码来读取文件内容。
将读取的数据解析为文件头、信息头和像素数据。

使用特权

评论回复
47
febgxu| | 2024-4-7 10:19 | 只看该作者
将bmp图像解码后的数据通过编写的液晶屏驱动程序发送到屏幕上,实现图像的显示。

使用特权

评论回复
46
youtome| | 2024-4-6 19:58 | 只看该作者
找到一个适用于CH32V103的bmp图像解码算法。这个算法需要能够处理bmp格式的图像文件,并将其转换为12864液晶屏可以显示的格式。

使用特权

评论回复
45
iyoum| | 2024-4-6 15:46 | 只看该作者
BMP格式通常包含文件头、信息头和像素数据。你需要理解这些部分的结构以正确解析图像。
对于简单的256色BMP,你可能只需要关注调色板信息和像素数据。

使用特权

评论回复
44
macpherson| | 2024-4-6 13:54 | 只看该作者
BMP解码和LCD显示可能都是资源密集型的任务,特别是在资源有限的MCU上。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

19

主题

110

帖子

0

粉丝