ESP32-S3 + Arduino 各种 JPEG 解码库速度对比,到底哪个才是最快的?

前段时间做了个 ESP32-S3 串流小电视(见 桌面小电视新思路,ESP32-S3 + 12864 OLED 串流视频)的项目,最近准备试试显示彩色图片,这就需要持续显示 JPEG 图片来模拟视频播放。

在 Arduino 生态中找到了好几个解码库,虽然也有一些对比测试,还是想自己实测一下,看看具体的效果怎么样 😃。

起因

在串流进行视频播放时,需要视频的每一帧解码、上屏,如果需要达到 30 FPS 的刷新率,那么解码 + 上屏的时间要在 1000 / 30 = 33.333 ms 以内。在这种情况下,图片解码性能直接影响用户体验。

另外,ESP32-S3 有双核 + 更高主频 + PSRAM + SIMD 指令支持,理论上应该可以跑得更快,但是具体能快多少,不同库之间差距多大,都需要实测数据。

测试环境

硬件平台

  • 开发板: ESP32-S3-Zero 开发板
  • PSRAM: 2MB PSRAM
  • CPU 频率: 240MHz (双核)
  • Flash: 4MB
  • Arduino 版本: PlatformIO Espressif 32 (55.3.34)

测试样本

测试图片使用了经典的计算机图像处理测试图片 Lenna(见 https://en.wikipedia.org/wiki/Lenna)。

不同尺寸使用 ImageMagick 缩放、裁切,并使用 80% 质量导出为 JPEG 图片。

esp32-jpeg-decoder-test-2

JPEG 图片测试样本:

  • 160x80 像素,质量 80,文件大小约 4KB
  • 240x240 像素,质量 80,文件大小约 12KB
  • 320x240 像素,质量 80,文件大小约 49KB

测试视频

解码库介绍

JPEGDEC

项目地址: https://github.com/bitbank2/JPEGDEC

bitbank2 大佬的作品,支持 JPEG、Progressive JPEG,代码精简,专门为嵌入式优化。Arduino Library Manager 可以直接安装,并且新版本也支持了 SIMD 指令。

特点:

  • 代码体积小
  • 支持部分解码
  • 可以直接输出到 LCD

TJpg_Decoder

项目地址: https://github.com/Bodmer/TJpg_Decoder

基于 TinyJPEG 的 Arduino 封装库,Bodmer 大佬维护,和 TFT_eSPI 配合使用非常方便。

特点:

  • 集成度高
  • 和 TFT_eSPI 无缝配合
  • 支持缩放输出
  • 纯软件解码

ESP32_NEW_JPEG

项目地址: https://github.com/espressif/esp-adf-libs/tree/master/esp_new_jpeg

乐鑫官方提供的 JPEG 硬件加速库,理论上也是使用 SIMD 指令加速,仅提供 lib 库使用,不开放源代码。

特点:

  • 硬件加速
  • 理论性能最强
  • 功耗更低

乐鑫官方在 2025 年 9 月才宣布这个库,也是相当新了,文章见 https://developer.espressif.com/blog/2025/09/esp-new-jpeg-introduction/

另外有个问题,ESP32_NEW_JPEG 只支持 Baseline JPEG,不支持 Progressive JPEG,如果遇到 Progressive JPEG 会解码失败。

JPEG 解码性能测试

测试代码

测试方法很简单,测试图片直接生成 C 头文件,编译到固件中,然后在固件中每个尺寸的每个图片,均解码 10 次并上屏,记录平均耗时。

static bool DecodeWithJpegdec(const uint8_t *data, size_t len) {
  BeginRunMetrics();
  // Image arrays are stored in flash (.rodata) on ESP32, so use openFLASH().
  int rc = gJpegDec.openFLASH(data, static_cast<int>(len), JpegdecOutput);
  if (rc == 0) {
    EndRunMetrics();
    return false;
  }
  gJpegDec.setPixelType(RGB565_LITTLE_ENDIAN);
  rc = gJpegDec.decode(0, 0, 0);
  gJpegDec.close();
  EndRunMetrics();
  return rc != 0;
}

static bool DecodeWithTjpg(const uint8_t *data, size_t len) {
  BeginRunMetrics();
  TJpgDec.setSwapBytes(false);
  TJpgDec.setCallback(TjpgOutput);
  const bool ok = TJpgDec.drawJpg(0, 0, data, static_cast<uint32_t>(len)) == JDR_OK;
  EndRunMetrics();
  return ok;
}

其他库的测试代码类似,主要是调整 API 调用方式。

测试结果

160x80 JPEG 解码速度

Library Decode(ms) Draw(ms) Total(ms) FPS
JPEGDEC 6.79 7.67 14.46 69.2
Tjpg_Decoder 10.54 8.63 19.16 52.2
ESP32_NEW_JPEG 3.89 7.51 11.40 87.7

240x240 JPEG 解码速度

Library Decode(ms) Draw(ms) Total(ms) FPS
JPEGDEC 26.64 33.98 60.62 16.5
Tjpg_Decoder 43.05 38.67 81.72 12.2
ESP32_NEW_JPEG 26.08 34.87 60.95 16.4

320x240 JPEG 解码速度

Library Decode(ms) Draw(ms) Total(ms) FPS
JPEGDEC 34.89 45.37 80.26 12.5
Tjpg_Decoder 56.53 51.54 108.07 9.3
ESP32_NEW_JPEG 34.48 46.46 80.95 12.4

可以看到,ESP32_NEW_JPEG 硬件加速真的强,在低分辨率下比软件解码快了 2 倍多。

但是 JPEGDEC 新版本在使用了 SIMD 之后,性能也很强劲,甚至在 320x240 分辨率下领先 ESP32_NEW_JPEG 一点点,当然这也有可能是测试误差 😃。

内存占用对比

除了速度,内存占用也很重要,特别是对于复杂项目。

注意:这里只是简单的统计了堆内存和栈大小的变化,并不是很严谨,仅供参考。

Size Library HeapDelta(B) StackDelta(B)
160x80 JPEGDEC 0 1271
160x80 Tjpg_Decoder 0 1189
160x80 ESP32_NEW_JPEG 38024 1006
240x240 JPEGDEC 0 1272
240x240 Tjpg_Decoder 0 1241
240x240 ESP32_NEW_JPEG 128648 989
320x240_B JPEGDEC 0 1265
320x240_B Tjpg_Decoder 0 1252
320x240_B ESP32_NEW_JPEG 167560 987

可以看到只有 ESP32_NEW_JPEG 使用到了堆内存,而另外两个库直接通过栈内存解码。

另外不管图片大小,几个库在栈内存使用上都差不多。

注:ESP32_NEW_JPEG 还有 block 方式解码,这里没有使用,内存使用情况可以会有所不同。

小结

经过一番测试,得出以下结论:

JPEG 解码选择指南:

场景 推荐库 理由
追求性能 JPEGDEC 或 ESP32_NEW_JPEG 硬件加速,速度快
节省内存 JPEGDEC 内存占用小,速度也不错
需要 Progressive JPEG JPEGDEC ESP32-JPEG 不支持
配合 TFT_eSPI TJpg_Decoder 集成度高,使用方便

在完成测试之前,以为 ESP32_NEW_JPEG 会有绝对优势领先,毕竟官方理论上可以发挥 ESP32-S3 的全部性能。

但是在测试完成后发现 JPEGDEC 在有 SIMD 指令加持下之后,性能也相当不错。

核心建议:

  1. 优先使用 ESP32-JPEG - 如果内存上不太紧张,并且图片都是 Baseline JPEG,可以优先选择 ESP32-JPEG,毕竟官方库。
  2. JPEGDEC 作为备选 - 内存比较紧张,或者需要兼容 Progressive JPEG 时使用。

顺便再提一句,ESP32 系列中,只有 ESP32-S3 以及 ESP32-P4 才支持 SIMD 指令,因此如果是使用 ESP32-S3 以外的芯片,可能测试结果会有所不同。

再再提一下,这些数据都是我自己测的,在不同的图片质量、编码方式、测试代码上性能可能会有差异,仅供参考 😃。

参考资料

发表评论?

0 条评论。

发表评论


注意 - 你可以用以下 HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>