diff --git a/include/meow_ui_image.h b/include/meow_ui_image.h index 88c15e0..b2de71a 100644 --- a/include/meow_ui_image.h +++ b/include/meow_ui_image.h @@ -26,6 +26,9 @@ int meow_img_w(meow_img *img); int meow_img_h(meow_img *img); void meow_ui_img(int x, int y, meow_img *img); /* 原始尺寸 */ +/* 内存瘦身:最近邻等比缩放到最长边 ≤maxdim,返回新图;原图已 ≤maxdim 返回 NULL。 + * 调用方负责 free 旧图与返回值(若返回)。封面/背景大图驻留内存瘦身用。 */ +meow_img *meow_img_downscale(meow_img *img, int maxdim); void meow_ui_img_scaled(int x, int y, int w, int h, meow_img *img); /* 最近邻缩放 */ void meow_ui_img_alpha(int x, int y, int w, int h, meow_img *img, int alpha); void meow_ui_img_cover(int x, int y, int size, meow_img *img); /* 居中裁方 → size×size */ diff --git a/meow_ui_img.c b/meow_ui_img.c index c2bd08b..96c37f0 100644 --- a/meow_ui_img.c +++ b/meow_ui_img.c @@ -96,6 +96,30 @@ static unsigned char *scale_buf(const meow_img *im, int dw, int dh, int cover) return out; } +/* 内存瘦身:把大图按最近邻等比缩放到「最长边 ≤ maxdim」,返回新图;调用方负责 + * meow_img_free 旧图 + 新图。原图已 ≤maxdim → 返回 NULL(无需缩放)。 + * 典型:网易云全尺寸封面 1448×1448 RGBA=8MB,显示只需 ≤480px(屏幕 480 宽)→ + * 480×480=0.9MB,省 ~7MB anon(设备 RAM 仅 56MB,OOM 真机被杀)。 + * 复用 scale_buf(cover=0,最近邻锁比例),不做插值(App 封面/背景无需高质量缩放)。 */ +meow_img *meow_img_downscale(meow_img *im, int maxdim) +{ + if (!im || maxdim <= 0) return NULL; + if (im->w <= maxdim && im->h <= maxdim) return NULL; /* 已够小,不缩放 */ + int dw, dh; + if (im->w >= im->h) { + dw = maxdim; + dh = (int)((long)im->h * maxdim / im->w); + } else { + dh = maxdim; + dw = (int)((long)im->w * maxdim / im->h); + } + if (dw < 1) dw = 1; + if (dh < 1) dh = 1; + unsigned char *tmp = scale_buf(im, dw, dh, 0); + if (!tmp) return NULL; + return img_alloc(dw, dh, tmp); +} + void meow_ui_img(int x, int y, meow_img *im) { if (!im) return;