Scale Immich photos to cover the display

This commit is contained in:
Adolfo
2026-07-29 22:00:18 -04:00
parent eaccebc95d
commit eb364cb34f
+41 -2
View File
@@ -483,6 +483,38 @@ static void fetch_task_fn(void* arg);
static void hide_chrome(AppCtx* ctx);
static void show_chrome(AppCtx* ctx);
static bool get_png_dimensions(const char* path, int* width, int* height) {
if (!path || !width || !height) return false;
uint8_t header[24];
FILE* file = fopen(path, "rb");
if (!file) return false;
size_t read_size = fread(header, 1, sizeof(header), file);
fclose(file);
static const uint8_t png_signature[8] = { 0x89, 'P', 'N', 'G', 0x0D, 0x0A, 0x1A, 0x0A };
if (read_size != sizeof(header) || memcmp(header, png_signature, sizeof(png_signature)) != 0 ||
memcmp(&header[12], "IHDR", 4) != 0) {
return false;
}
*width = (int)(((uint32_t)header[16] << 24U) | ((uint32_t)header[17] << 16U) |
((uint32_t)header[18] << 8U) | (uint32_t)header[19]);
*height = (int)(((uint32_t)header[20] << 24U) | ((uint32_t)header[21] << 16U) |
((uint32_t)header[22] << 8U) | (uint32_t)header[23]);
return *width > 0 && *height > 0;
}
static uint32_t get_cover_scale(const AppCtx* ctx, int source_width, int source_height) {
if (!ctx || ctx->disp_w <= 0 || ctx->disp_h <= 0 || source_width <= 0 || source_height <= 0) {
return 256;
}
uint32_t scale_x = ((uint32_t)ctx->disp_w * 256U + (uint32_t)source_width - 1U) / (uint32_t)source_width;
uint32_t scale_y = ((uint32_t)ctx->disp_h * 256U + (uint32_t)source_height - 1U) / (uint32_t)source_height;
return scale_x > scale_y ? scale_x : scale_y;
}
static void detect_display_size(AppCtx* ctx, lv_obj_t* parent) {
if (!ctx) return;
int w=FALLBACK_W, h=FALLBACK_H;
@@ -575,10 +607,17 @@ static void ui_update_all(AppCtx* ctx) {
snprintf(lvgl_path, sizeof(lvgl_path), "A:%s", ctx->saved_img_path);
lv_image_set_src(ctx->img_page, lvgl_path);
lv_obj_clear_flag(ctx->img_page, LV_OBJ_FLAG_HIDDEN);
// Fullscreen background: widget covers entire display
// Scale the memory-safe 320x240 source to cover the display while
// preserving its aspect ratio. The parent clips the excess.
int source_width = ctx->img_w;
int source_height = ctx->img_h;
get_png_dimensions(ctx->saved_img_path, &source_width, &source_height);
uint32_t scale = get_cover_scale(ctx, source_width, source_height);
lv_image_set_scale(ctx->img_page, scale);
lv_obj_set_size(ctx->img_page, ctx->disp_w > 0 ? ctx->disp_w : ctx->img_w, ctx->disp_h > 0 ? ctx->disp_h : ctx->img_h);
lv_obj_center(ctx->img_page);
ESP_LOGI(TAG, "lv_img_set_src %s %dx%d", lvgl_path, ctx->disp_w, ctx->disp_h);
ESP_LOGI(TAG, "lv_img_set_src %s display %dx%d source %dx%d scale %u",
lvgl_path, ctx->disp_w, ctx->disp_h, source_width, source_height, (unsigned)scale);
} else {
ESP_LOGW(TAG, "Image file not found for display: %s", ctx->saved_img_path);
lv_image_set_src(ctx->img_page, LV_SYMBOL_IMAGE);