一、把二维图片拉成一条线
一张宽 W、高 H 的图片有 W×H 个像素。要重排它们,最直接的办法是先给每个像素编一个先后顺序。常见的“从左到右、从上到下”会让相邻像素在顺序中也紧挨着,但这样上下相邻的像素却相隔很远,空间关系被割裂。
希尔伯特曲线是一种空间填充曲线,它能一笔走遍整个网格,并且在顺序上相近的像素,在画面上也大致相近。这种“保持局部性”的特点,让重排后的图片呈现出细腻的块状纹理,而不是粗糙的横条。
二、任意尺寸怎么办
经典希尔伯特曲线只适用于边长是 2 的幂的正方形。本站使用的是广义版本(常被称为 gilbert),它通过递归地把矩形切成两块或三块,让曲线也能覆盖任意宽高的长方形,如 1920×1080、1179×2556 等手机截图尺寸。
切分时算法会尽量让子区域边长为偶数,从而让曲线保持连续,不出现大跳跃。这一步仅依赖宽和高,所以对同尺寸的图片,曲线完全相同。
三、黄金分割平移
得到像素顺序后,把整条链循环平移 round(0.618 × W × H) 个位置。第 i 个像素的颜色,被搬到第 i+偏移 个位置上,超出末尾的部分绕回开头。
选择黄金分割比例,是因为它在“不太近也不太远”之间有较好的均匀性,能让原图中的内容被推到画面上相距较远的地方,同时又不会与自身重叠成简单的镜像。
四、为什么可以完美还原
平移是一个一一对应的操作:每个像素恰好去往一个新位置,也恰好有一个像素来到它的位置。因此解混淆时只需要把平移方向反过来,每个像素都能回到原处,不丢失、不重复。
由于偏移量完全由图片尺寸算出,所以不需要密码或额外数据,这也是它“即开即用”的原因。
五、强度边界要看清
这种方法属于视觉混淆,而不是加密。它没有密钥,算法公开,任何了解原理的人都可以还原。它的价值在于:避免缩略图、预览和路人的一眼识别,而不是对抗有意的破解。
如果您需要真正的保密,请使用成熟的加密工具对文件加密,再进行传输。
六、性能与精度
本站用类型化数组保存曲线上每个点的线性下标,并按 32 位整体复制像素,比逐像素构造数组快得多。处理的是 RGBA 像素值,在 PNG 下不会产生任何精度损失;而 JPG 保存会改变像素值,所以解混淆时可能带有噪点。
为避免浏览器内存不足,超过 800 万像素或单边超过 4000 像素的图片会在载入时被等比缩小。