当前位置: 首页 > article >正文

如何使用ST7789展现图片?[ESP--4]

本节我们继续ESP和ST 7789的话题,这节课我们来学学如何展示图片,话不多说,先上效果

在这里插入图片描述

好,教程开始~前情提要,要看懂这篇,建议搭配楼主的前两期文章
使用ESP32驱动LCD-ST7789屏幕[ESP–2]
加速你的LCD-ST7789屏幕![ESP–3]

好,话不多说,直接开始

显示原理

ST7789支持的颜色为RGB565,一般我们常见的颜色是RGB888,就是RGB三色各占一个字节(一个字节8位),ST7789毕竟是MCU模块,自然要减轻负担,所以RGB阉割成了2字节能表示的(人眼对绿光最敏感,所以绿光的色阶更多

然后如何在屏幕上放像素呢?

tft.drawPixel(x , y , 0xFFFF);
//封装好的函数,直接输入一个二字节数就行,多么简单

所以现在的问题就是怎么把图片转换为一个RGB565数组,然后导入我们的程序。这里我使用的是开源的格式转换工具BMPCVT
在网上和GITHUB上有这个软件

使用方法

  • 点击FILE/OPEN 打开你需要转换的文件
    在这里插入图片描述
    选择IMAGE/CONVERT INTO /16BIT COLOR565
    在这里插入图片描述
    选择FILE/SAVE AS/进入下面的界面
    选择C bitmap的格式,保存到你可见的位置
    /

最后的加工

不过这个数组我们现在还不能直接使用,因为我们用的是eSPI 库,这个作者用的是GUI(?)
打开文件,你会看到这个画面

  • 删除include 命令
  • 删除数组的static 修饰符
  • 删去结尾的那个结构体
  • 将这个文件放到你的工程中去
  • 如果可以,把后缀改成H,然后包含一下

在这里插入图片描述

插删掉这个

下面就是代码了

#include <TFT_eSPI.h>
#include <SPI.h>

#include "image_rgb565.cpp"
//包含你的数组


class Timer {
public:
    Timer() : start_timepoint(std::chrono::high_resolution_clock::now()) {}
    
    void reset() {
        start_timepoint = std::chrono::high_resolution_clock::now();
    }
    
    double elapsed() const {
        auto end_timepoint = std::chrono::high_resolution_clock::now();
        std::chrono::duration<double> elapsed_time = end_timepoint - start_timepoint;
        return elapsed_time.count();
    }

private:
    std::chrono::time_point<std::chrono::high_resolution_clock> start_timepoint;
};
Timer timer;

TFT_eSPI tft = TFT_eSPI();  // 使用优化后的TFT_eSPI库

void drawImage() {
  // 将图片数据绘制到 ST7789 上
  int16_t x = 0, y = 0; // 图像绘制起始位置
  for (int16_t j = 0; j < 240; j++) {
    for (int16_t i = 0; i < 240; i++) {
      uint16_t color = image_data[j * 240 + i];
      tft.drawPixel(x + i, y + j, color);
    }
  }
}


void setup() {
  Serial.begin(9600);
  tft.init();
  tft.setRotation(1);  // 设置旋转
  // 如果需要,可以明确调用长宽

  // 显示固定的文本,只在 setup 中显示一次
  tft.fillScreen(TFT_BLACK);
  Serial.printf("Total heap: %d ", ESP.getHeapSize());  // 获取总堆内存大小
  Serial.println();
  Serial.printf("Free heap: %d", ESP.getFreeHeap());    // 获取当前可用堆内存大小
  Serial.println();
  Serial.printf("Total PSRAM: %d", ESP.getPsramSize()); // 获取总PSRAM大小(如果支持)
  Serial.println();
  Serial.printf("Free PSRAM: %d", ESP.getFreePsram());  // 获取当前可用PSRAM大小(如果支持)
  Serial.println();
}

void loop() {
  // 绘制动态变化的部分
  tft.fillRect(0, 0, 100, 50, TFT_BLACK);  // 清除FPS部分

  drawImage();

  float FPS = 1 / (timer.elapsed());
  tft.setCursor(0, 0);
  tft.printf("FPS: %.2f", FPS);

  timer.reset();
  delay(50);
   
}

http://www.kler.cn/a/417006.html

相关文章:

  • vscode卡住---回退版本解决
  • [LeetCode] day19 454. 四数相加 II
  • Win11下搭建Kafka环境
  • 哪吒闹海!SCI算法+分解组合+四模型原创对比首发!SGMD-FATA-Transformer-LSTM多变量时序预测
  • http常用状态码
  • html文件怎么转换成pdf文件,2025最新教程
  • 中国剩余定理——acwing
  • windows中idea选择bash作为控制台指令集,但是系统环境变量未在其中生效处理
  • Vue 2.0->3.0学习笔记(Vue 3 (一)- 创建Vue3.0工程)
  • 白鹿 Hands-on:消除冷启动——基于 Amazon Lambda SnapStart 轻松打造 Serverless Web 应用(二)
  • 《FRAPPE: fast rank approximation with explainable features for tensors》中文校对版
  • 技术分析模板
  • 【rust】前端开发中的应用与前景
  • 安卓延迟自动点击
  • pcb电路板·查错、维修心得笔记
  • 深入解析 Spring MVC:架构、组件与最佳实践
  • 联想Lenovo SR650服务器硬件监控指标解读
  • osg、osgearth源码编译(二)
  • 监控视频汇聚平台:Liveweb视频监控管理平台方案详细介绍
  • PYTHON让大模型固定的返回JSON
  • 泛化调用 :在没有接口的情况下进行RPC调用
  • Windows pc端桌面便签哪个好用?桌面简洁好用的便签软件推荐
  • `console.log`调试完全指南
  • deepin 安装 chrome 浏览器
  • 【Java基础入门篇】三、面向对象和JVM底层分析(2)
  • Artec Leo:航海设备维护的便携式3D扫描利器【沪敖3D】