summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorjacqueline <me@jacqueline.id.au>2024-07-17 17:22:59 +1000
committerjacqueline <me@jacqueline.id.au>2024-07-17 17:22:59 +1000
commit2ab459598c60b7df0d4b0dddf4a1e7c71ae985a1 (patch)
tree6b459f78acef7adf8737789d7d3534cccee6dd20 /src
parent7012e64a14841fb018289529d08e5542e33f2151 (diff)
downloadtangara-fw-2ab459598c60b7df0d4b0dddf4a1e7c71ae985a1.tar.gz
Encode snapshots as PNGs when saving to disk
Diffstat (limited to 'src')
-rw-r--r--src/tangara/ui/screenshot.cpp48
-rw-r--r--src/tangara/ui/screenshot.hpp17
-rw-r--r--src/tangara/ui/ui_fsm.cpp18
3 files changed, 67 insertions, 16 deletions
diff --git a/src/tangara/ui/screenshot.cpp b/src/tangara/ui/screenshot.cpp
new file mode 100644
index 00000000..e4f9cc3f
--- /dev/null
+++ b/src/tangara/ui/screenshot.cpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2024 jacqueline <me@jacqueline.id.au>
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#include "screenshot.hpp"
+#include <sys/_stdint.h>
+
+#include <string>
+
+#define LODEPNG_NO_COMPILE_CPP
+#include "libs/lodepng/lodepng.h"
+
+#include "esp_log.h"
+#include "lvgl.h"
+
+namespace ui {
+
+[[maybe_unused]] static constexpr char kTag[] = "screenshot";
+
+auto SaveScreenshot(lv_obj_t* obj, const std::string& path) -> void {
+ lv_draw_buf_t* buf = lv_snapshot_take(obj, LV_COLOR_FORMAT_RGB888);
+ if (!buf) {
+ return;
+ }
+
+ // LVGL appears to output BGR data instead. Not quite sure why, but swapping
+ // each pair is quite easy.
+ for (size_t i = 0; i < buf->data_size; i += 3) {
+ uint8_t temp = buf->data[i];
+ buf->data[i] = buf->data[i + 2];
+ buf->data[i + 2] = temp;
+ }
+
+ // The LVGL lodepng fork uses LVGL's file API, so an extra '/' is needed.
+ std::string fullpath = "//sdcard/" + path;
+
+ auto res = lodepng_encode_file(fullpath.c_str(), buf->data, buf->header.w,
+ buf->header.h, LCT_RGB, 8);
+
+ lv_draw_buf_destroy(buf);
+ if (res != 0) {
+ ESP_LOGE(kTag, "lodepng error: '%s'", lodepng_error_text(res));
+ }
+}
+
+} // namespace ui
diff --git a/src/tangara/ui/screenshot.hpp b/src/tangara/ui/screenshot.hpp
new file mode 100644
index 00000000..d19be0f0
--- /dev/null
+++ b/src/tangara/ui/screenshot.hpp
@@ -0,0 +1,17 @@
+/*
+ * Copyright 2024 jacqueline <me@jacqueline.id.au>
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#pragma once
+
+#include <string>
+
+#include "lvgl.h"
+
+namespace ui {
+
+auto SaveScreenshot(lv_obj_t* obj, const std::string& path) -> void;
+
+}
diff --git a/src/tangara/ui/ui_fsm.cpp b/src/tangara/ui/ui_fsm.cpp
index 4f93fe61..cd39dc9c 100644
--- a/src/tangara/ui/ui_fsm.cpp
+++ b/src/tangara/ui/ui_fsm.cpp
@@ -65,6 +65,7 @@
#include "ui/screen.hpp"
#include "ui/screen_lua.hpp"
#include "ui/screen_splash.hpp"
+#include "ui/screenshot.hpp"
#include "ui/ui_events.hpp"
namespace ui {
@@ -371,22 +372,7 @@ void UiState::react(const Screenshot& ev) {
if (!sCurrentScreen) {
return;
}
- ESP_LOGI(kTag, "taking snapshot");
- lv_draw_buf_t* buf =
- lv_snapshot_take(sCurrentScreen->root(), LV_COLOR_FORMAT_RGB888);
- if (!buf) {
- ESP_LOGW(kTag, "snapshot failed");
- return;
- }
- ESP_LOGI(kTag, "writing to file");
- std::string fullpath = "//sdcard/" + ev.filename;
- auto res = lv_draw_buf_save_to_file(buf, fullpath.c_str());
- lv_draw_buf_destroy(buf);
- if (res == LV_RESULT_OK) {
- ESP_LOGI(kTag, "write okay!");
- } else {
- ESP_LOGE(kTag, "write failed!");
- }
+ SaveScreenshot(sCurrentScreen->root(), ev.filename);
}
void UiState::react(const system_fsm::KeyLockChanged& ev) {