这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 活动中心 » 板卡试用 » 【分享开发笔记,赚取电动螺丝刀】MAX78000开发板制作的电子相册

共1条 1/1 1 跳转至

【分享开发笔记,赚取电动螺丝刀】MAX78000开发板制作的电子相册

助工
2025-10-21 15:19:44     打赏

之前的两篇帖子分别搞定了MAX78000开发板读取SD卡和驱动TFT液晶屏。这次将SD卡和液晶屏结合起来制作一个电子相册。

一、图片格式预处理:这个2.4寸SPI液晶屏模块240*320TFT模块,主控芯片为ILI9341。电脑中的图片是以jpg方式保存的图片。显示图片的第一步,就是要将jpg图片转换为位图形式,一种方法是在MAX78000开发板上解码jpg图片,需要用到jepg图片解码库。我这里是在电脑上预先将jpeg图片,转换为320X240大小的bmp(位图)的格式,保存在SD卡上。

# 将jpeg图片转换为bmp图片,并限定尺寸
import os
import time
import cv2 as cv
filePath = os.path.dirname(os.path.abspath(__file__))
# 获取当前文件夹下的文件名列表
def readfilename(filepath):
  names = None
  try:
    names = os.listdir(filepath)
  except Exception as e:
    print(e)
  else:
    return names

# 图片转换
def handleImage(filepath,names):
  for name in names:
    suffixs = name.split('.')
    suffix = suffixs.pop()
    if suffix in ['jpg']:
      img = cv.imread(filepath+"//"+name)
      # 调整图像大小
      res = cv.resize(img, (320, 240),interpolation=cv.INTER_CUBIC)
      cv.imwrite(f'{filepath}/{suffixs[0]}.bmp', res)

if __name__ == "__main__":
  filelist=readfilename("g://")
  print(filelist)
  handleImage("g://",filelist)

二、读取SD卡文件,并过滤bmp格式文件。

系统首先初始化各个硬件,然后从SD卡上读取文件,并将以“bmp”为后缀名的文件进行过滤。这里偷了个懒,SD卡中所有图片都以数字命名,从1开始,这样后边循环播放图片时,只需要简单地将文件名加一即可。首先统计出SD卡上有多少张图片。

//获取文件列表 返回获取到文件的个数
int ls_bmp(char cwd[]) {
	DIR dir;
	FILINFO fno;
	uint8_t num=0;
	if (!mounted) {
		mount();
	}
	if ((err = f_opendir(&dir, cwd)) == FR_OK) {
		while (1) {
			err = f_readdir(&dir, &fno);
			if (err != FR_OK || fno.fname[0] == 0) {
				break;
			}
			printf("%s\n", fno.fname);
			if(strstr(fno.fname, ".bmp")){
				num++;
			}
		}
		f_closedir(&dir);
	} else {
		printf("Error opening directory!\n");
		return err;
	}
	return num;
}

三、将RGB888格式数据转换为RGB565格式数据。

SD卡中读取到的bmp文件的数据,每个像素点是RGB888格式数据,即每个像素点由8X3位数据构成,分别记录红绿蓝三种颜色的信息。MAX78000开发板在TFT屏幕上显示时,使用的是RGB565格式数据,即每个像素点由8X2位数据构成,前5位为红色数据,中间6位为绿色数据,后边5位为蓝色数据。所以需要对每个点数据进行转换。

#define IMAGE_SIZE_X     320
#define IMAGE_SIZE_Y     240
uint8_t data565[IMAGE_SIZE_X * 2];
//step为传入数据中每个像素点所占字节数 3、4
void cover_rgb888_rgb565(uint8_t *data, uint8_t step) {
	uint8_t r, g, b;
	uint16_t rgb;
	uint16_t offset = 0;
	for (int i = 0; i < step * IMAGE_SIZE_X; i += step) {
		if (step == 4) {
			r = data[i];
			g = data[i + 1];
			b = data[i + 2];
		}
		if (step == 3) {
			b = data[i];
			g = data[i + 1];
			r = data[i + 2];
		}

		rgb = ((r & 0b11111000) << 8) | ((g & 0b11111100) << 3) | (b >> 3);
		data565[offset++] = (rgb >> 8) & 0xFF;
		data565[offset++] = rgb & 0xFF;
	}
}

四、显示图片数据。

MAX78000开发板因为内存有限,与电脑处理图片不同,不能一次将整个图片文件载入内存进行处理。这里我采用每次读取一行(320个像素点)数据来进行处理,处理后在屏幕上绘制改行数据,然后继续后边一行的图片数据,如此循环,直至一张图片处理完毕。

image.png

//绘制SD卡图片到屏幕
void draw_sdimg_tft(uint8_t i) {
	FIL file; //FFat File Object
	FRESULT err; //FFat Result (Struct)
	char filename[7];
	int row = 0;
	UINT bytes_read;
	uint8_t imgdata[IMAGE_SIZE_X * 3] = { 0 }; //全彩图
	sprintf(filename, "/%d.bmp", i);
	printf("read img %s\n", filename);
	if ((err = f_open(&file, filename, FA_READ)) != FR_OK) {
		f_mount(NULL, "", 0);
		return err;
	}
	// Image data begins at 0x54   跳过文件头
	if ((err = f_lseek(&file, 54)) != FR_OK) {
		printf("Error seeking file: %d\n", err);
		f_mount(NULL, "", 0);
		return err;
	}

	do {
//		每次读取320个像素
		if ((err = f_read(&file, imgdata, IMAGE_SIZE_X * 3, &bytes_read))
				!= FR_OK) {
			printf("Error reading file: %d\n", err);
			f_mount(NULL, "", 0);
			return err;
		}
		cover_rgb888_rgb565(imgdata, 3);			//转换rgb格式
		MXC_TFT_ShowImageCameraRGB565(0,  row, data565,IMAGE_SIZE_X, 1);
		row++;
	} while (bytes_read == IMAGE_SIZE_X * 3); // bytes_read<255 means the cursor reached EOF

	if ((err = f_close(&file)) != FR_OK) {
		printf("Error closing file: %d\n", err);
		f_mount(NULL, "", 0);
		return err;
	}
}

四、效果展示。

RGB565对图片还是有损失的,图片细腻程度还是有所下降。

30d99bd8d5177c6af3893c7b9873e7c2.jpg15073229e58bbfe1dad212be02b0521a.jpg

、源码。

TFT_Demo.zip


共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]