神奇的 PNG 缩略图魔术
有位朋友向我显摆了一个小技巧,某个网站有张图片,缩略图看着是图 A,当鼠标悬浮于缩略图上/或点击缩略图时,却显示成另外一张图像 B。
是不是有点小神奇呢?我在本文尝试解释这一「魔术」的原理,并且重新实现这个特效。
(编注:那个网站需梯子,请直接把下图保存到本地,然后你再打开看看)
行为
某些 png 文件渲染器显示一张图片,而其他渲染器可能会显示为完全不同的另外一张图片。一张图片总是暗的,一张是亮的。
例子:
能显示亮色图的东西
- 缩略图渲染器(Facebook等)
- 苹果 png 渲染器
- Windows png 渲染器
能显示暗色图的东西
- Firefox(以及使用 libpng 的任何扩展)
- Google Chrome
这可以带来有意思的组合:
- 直接外链 Facebook 上的图片,缩略图是图 A,但是当链接被点击时就完全不同。
- 可以用来检测用户浏览器。(Chrome、Firefox 或Safari)
- 图片在浏览器中显示一种结果,当下载到用户(受害者)的电脑中是另外一样。
- 经典的图片板块缩略图。
挑战与胜利
我开始苦苦思索这个效果是如何实现的,以便我可以复制。通往启迪的道路包括了很多错误的弯路,比如认为图片被转换为GIF。但是我最终发现了真相。
我发现了秘密之后,用 Ruby 写了一个名叫双视觉(doubleVision)命令行工具,这样任何人都可以生成神奇的缩略图。
双视觉(doubleVision)是一个可执行的Ruby gem,源码我放在 Github 上了。
输出的图片看起来像这样:
试试把它下到你电脑上看看。酷不酷呢?
它是如何工作的
PNG 的说明中包含了一个元数据属性,允许你渲染图片时带上指定的 Gamma 值。这个属性是用来保证图片在所有的电脑上看起来一样。这是非常正常的图像处理过程,叫做伽马修正。
PNG 的说明中定义了伽马块(块存储了伽马值)来改变图片的输出,像这样:
light_out = image_sample^(1 / gamma)
这个公式根据伽马值的倒数作为指数调整图像的值。如果伽马值像通常一样在 1 附近,这个函数就没有明显影响。在这个过程中,对于一个像素来说最低亮度是0,最高的为1。
如果我们把 PNG 的伽马属性设为很低的值,使得指数值很高(因为是倒数),所有更暗的像素变得更黑,所有更亮的像素被映射到正常的频谱。
指数伽马映射
我们可以对非常低的伽马属性值反过来映射(我用 0.023),把PNG图像中所有像素映射到非常亮的颜色。如果我们接下来把PNG的伽马值设为0.023,图像会看来正常些,除了在截断图像高值引入的误差附近。
问题是,并不是所有的渲染器度支持伽马属性。如果我们在一个不支持伽马属性的渲染器中试着查看图片,它会显示得太亮而无法辨认。
我们可以滥用这个方法来创建一个神奇的缩略图,利用两种同尺寸的图片创建一个原始维度两倍的新图片。一张图片利用之前提到的反向伽马滤波处理,使得所有像素非常亮,另一个没有很亮的像素因此变暗。然后,把两张图放在网格中相互环绕(参见下图)。最后把图存为伽马值为 0.023 的PNG文件。
当图片在支持伽马的渲染器(像Firefox/Chrome)中显示时,浅色像素变得相当的暗,但是可见颜色和正常的像素变成了一个暗像素的网格。当图片在不支持伽马的渲染器(像 Apple/Microsoft 渲染)中显示时,未转换的图片看起来被一个白色像素的网格围绕。
安装和使用
你可以安装双视觉(doubleVision)gem 执行下面的命令:
1 | $ gem install doubleVision |
然后像这样运行程序:
1 | doubleVision withgamma.png withoutgamma.png out.png |
显式地用你自己的文件名进行替换。
它会把图片组合成一个图(out.png),用支持伽马的渲染器查看时显示 withgamma.png (例如,Firefox中),不支持伽马的显示 withoutgamma.png (例如,作为缩略图)。
更多详细的说明看 Github 上的 README。
其他例子:(图片另存到本地后再看看哈~)
生成自:
本文文字及图片出自 伯乐在线
你也许感兴趣的:
- 具有魔法的 H.264
- 多用户环境中的 rootless Docker
- 【外评】微软的人工智能聊天机器人将 “回忆 “您在其新 PC 上所做的一切
- 【外评】苹果需要解释重新出现已删除照片的错误
- 你需要知道的现代 CSS 技巧(2024 年春季版)
- 使用 :has() 作为 CSS 父选择器及其他更多内容
- 【外评】大科技公司致欧盟:“去死”
- npm又被滥用,灰产用《庆余年2》盗版资源——把开源公共基础设施的羊毛薅秃了
- 【外评】如果您没有在 Edge 中使用必应,微软现在会说您的电脑需要 “修复”
- Chrome 浏览器开发工具(DevTools)现在使用双子座(Gemini )来帮助处理控制台中的 JavaScript 错误
你对本文的反应是: