tobimori / kirby-blurhash
带有优化BlurHash集成的图像占位符
Requires
- php: >=8.0.0
- getkirby/composer-installer: ^1.2
- kornrunner/blurhash: ^1.2
Requires (Dev)
- getkirby/cms: ^3.8
README
Kirby BlurHash
BlurHash是一种在Wolt开发的优化图像占位符算法。占位符由小的(∼20-50字节)哈希值表示,而不是更大的(∼1kB+)base64编码图像。
此插件将BlurHash支持添加到Kirby 3,使您可以实现如渐进式图像加载或内容感知的预告图等UX改进如Mastodon。
底层,繁重的工作由kornrunner的PHP实现BlurHash完成:kornrunner/php-blurhash
请注意,BlurHash目前没有透明度支持,因此将以黑色渲染。
要求
- Kirby 3.9.2+ for asset methods
- PHP 8.0+
gd
扩展(由Kirby要求)
安装
下载
下载并将此存储库复制到/site/plugins/kirby-blurhash
。
Composer
composer require tobimori/kirby-blurhash
用法
客户端解码
$file->blurhash()
使用BlurHash对图像进行编码,并返回字符串形式的BlurHash
BlurHash的默认实现假定字符串将在客户端进行解码,使用类似Wolt的blurhash或fast-blurhash的库。
这提供了最大的好处,特别是更好的颜色表示和更小的负载大小,但需要在客户端执行此类库,因此更适合与无头站点或大量使用客户端无限滚动/加载的网站一起使用。
以下是一个示例实现,使用BlurHash字符串生成占位符图像
<div data-blurhash="<?= $image->blurhash() ?>" // BlurHash string as attribute, to access via JS style="aspect-ratio: <?= $image->ratio() ?>;"> // Aspect ratio is required as canvas is absolutely positioned </div>
import { decodeBlurHash } from 'fast-blurhash' // https://github.com/mad-gooze/fast-blurhash const el = document.querySelector('div[data-blurhash]') if (!el) return const { blurhash } = el.dataset if (!blurhash) return const pixels = decodeBlurHash(blurhash, 32, 32) const canvas = document.createElement('canvas') canvas.width = 32 canvas.height = 32 const ctx = canvas.getContext('2d') if (!ctx) return const imageData = ctx.createImageData(32, 32) imageData.data.set(pixels) ctx.putImageData(imageData, 0, 0) el.appendChild(canvas)
div { position: relative; width: 400px; } canvas { position: absolute; top: 0; right: 0; bottom: 0; left: 0; height: 100%; width: 100%; }
您的实现细节可能会有所不同,例如,这可能不包含懒加载功能,或者您可能想使用不同的库,但基本思想是使用BlurHash字符串作为元素的属性,然后在客户端解码BlurHash字符串。
平均颜色
$file->blurhashColor()
使用BlurHash对图像进行编码,并返回十六进制字符串形式的平均颜色
为了在客户端库加载之前仍然提供小的占位符,BlurHash还会编码图像的平均颜色,我们可以访问并使用它来增强懒加载,当还没有加载脚本时。
我们可以将上面的代码片段更新如下
<div data-blurhash="<?= $image->blurhash() ?>" style="aspect-ratio: <?= $image->ratio() ?>; background-color: <?= $image->blurhashColor() ?>;"> </div>
当您想获取平均颜色,但已经生成了BlurHash时,您可以在BlurHash
类上使用averageColor
静态方法而不是这样
<?php use tobimori\BlurHash; $blurhash = 'LKN]Rv%2Tw=w]~RBVZRi};RPxuwH'; echo BlurHash::averageColor($blurhash); // #d0b1a3
服务器端解码
$file->blurhashUri()
使用BlurHash对图像进行编码,然后解码并光栅化它。最后,以数据URI的形式返回它,可以不使用任何客户端库使用。
除了简单地输出用于客户端的BlurHash字符串外,此插件还提供了一种服务器端解码选项,允许您输出一个base64编码的图像字符串,可以用作占位图,无需任何客户端库,类似于Kirby Blurry Placeholder。
这在您网站上只有少量图像或不想麻烦使用客户端库输出占位符时特别有用。使用这种方法,您仍然会比常规图像缩小得到更好的颜色表示,但图像预览仍然大约为~1kB。
<img src="<?= $image->blurhashUri() ?>" />
使用像vanilla-lazyload(支持所有功能)或Loadeer.js(更小/更快,不支持iframe、视频或背景图像)这样的懒加载库,您的实现可能如下所示
<img src="<?= $image->blurhashUri() ?>" data-src="<?= $image->url() ?>" // Original src attribute that will be replaced by the lazy-loading library data-lazyload // Attribute for browser to know what to lazy-load alt="<?= $image->alt() ?>" />
import LazyLoad from 'vanilla-lazyload' const lazy = new LazyLoad({ elements_selector: '[data-lazyload]' })
裁剪图像
Kirby不支持裁剪图像的文件方法,因此您必须使用原始图像,并将比例作为属性传递给元素以获得正确的BlurHash。
<?php $cropped = $original->crop(500, 400) ?> <img src="<?= $original->blurhashUri(5/4) ?>" data-src="<?= $cropped->url() ?>" data-lazyload alt="<?= $original->alt() ?>" />
这同样由$file->blurhash($ratio)
和$file->blurhashColor($ratio)
支持。
处理静态资源(使用asset()
助手)
从Kirby 3.9.2和kirby-blurhash
v1.2.0开始,所有方法都以资产方法的形式可用。
asset('assets/image.jpg')->blurhash(); asset('assets/image.jpg')->blurhashUri(); asset('assets/image.jpg')->blurhashColor();
别名
$file->bh(); // blurhash() $file->bhUri(); // blurhashUri() $file->bhColor(); // blurhashColor()
清除缓存
当图像被替换或更新时,编码缓存会自动清除,但是您也可以使用clearCache
静态方法手动清除缓存
<?php use tobimori\BlurHash; BlurHash::clearCache($file);
当您使用第三方插件编辑图像,并且它们不触发Kirby的内部文件更新钩子,而是有自己的钩子时,这可能很有用。
选项
选项允许您微调插件的行为。您可以在您的config.php
文件中设置它们
return [ 'tobimori.blurhash' => [ 'sampleMaxSize' => 200, 'componentsTarget' => 12, 'decodeTarget' => 100, ], ];
比较
致谢
- Johann Schopplich的Kirby Blurry Placeholder插件为这个插件设定了基线(许可协议为MIT License - 版权© 2020-2022 Johann Schopplich)
许可协议
MIT License 版权© 2023 Tobias Möritz