算法与数据结构 / 图片占位 · 从一块主色到一团模糊预览 待审核 2 页

图片占位 · 从一块主色到一团模糊预览

懒加载时先铺一块「主色背景」、给封面配一套主题色、统计一张图的代表色——背后都是同一个问题:从几万种颜色里选出 K 种代表色 (color quantization), 再挑像素最多的那一个当主导色 (dominant color)

本系列先用 octree (八叉树) 把 24-bit RGB 颜色空间逐位细分, 再自底向上折叠相近色, 取出调色板与主导色, 并与 median-cut、k-means 对照;再往上走一档, 看一块主色如何升级成 CSS-LQIP、BlurHash、ThumbHash 这类一团模糊预览的占位编码。

octree · 量化与主导色

八叉树取主导色 · color quantization

把 (r,g,b) 各 8 bit 看成一条 8 层下降路径,相近的颜色多半落进同一棵子树;叶子过多时自底向上折叠最细的分支,剩下的叶子即调色板,像素最多的那个是主导色。

三种占位图 hash

占位图 hash:把一张图压成一小串

把整张图的低频轮廓压进一小串数据。CSS-only LQIP 用一个 20-bit 整数加纯 CSS 解码,BlurHash 与 ThumbHash 用余弦基低频,三者是同一思路的不同精度。

一条主线

四种占位是同一条思路的不同精度:先有一块纯色, 加几个低频项就成了 CSS-LQIP、BlurHash、ThumbHash。octree 的长处是建树 O(N)O(N)、插入与折叠都是局部操作, 经典实现还能做到常数级内存上界并逐像素流式处理, 适合浏览器里实时给图片取主色;对画质有极致要求才上 median-cut 或 k-means。

延伸阅读

  • Dominant Colors for Lazy Loading Images manu.ninja 用八叉树为懒加载图片生成主色占位的完整讲解与实现, 本系列的直接出发点。
  • color-thief github.com 最流行的「从图片取调色板」库 (浏览器与 Node), 量化器用的是 modified median cut (MMCQ), 而默认聚类空间已是 oklch, 可与八叉树对照。
  • Color quantization wikipedia.org octree、median-cut、k-means 等量化方法的综述与历史;八叉树法由 Gervautz 与 Purgathofer 于 1988 年提出, 该条目有综述。
  • CSS-only LQIP leanrada.com 把图压成一个 20-bit 整数塞进 CSS 变量、渲染期纯 CSS 解码 (零 JS) 的 LQIP 方案, 占位图 hash 那页的来源。