tobimori/kirby-blurhash

带有优化BlurHash集成的图像占位符

资助包维护!
tobimori

安装: 926

依赖: 0

建议者: 0

安全性: 0

星标: 36

关注者: 2

分叉: 1

公开问题: 3

类型:kirby-plugin

1.2.0 2023-03-08 11:39 UTC

This package is auto-updated.

Last update: 2024-09-08 14:37:27 UTC


README

Kirby BlurHash Banner

Kirby BlurHash

BlurHash是一种在Wolt开发的优化图像占位符算法。占位符由小的(∼20-50字节)哈希值表示,而不是更大的(∼1kB+)base64编码图像。

此插件将BlurHash支持添加到Kirby 3,使您可以实现如渐进式图像加载或内容感知的预告图等UX改进如Mastodon

底层,繁重的工作由kornrunner的PHP实现BlurHash完成:kornrunner/php-blurhash

请注意,BlurHash目前没有透明度支持,因此将以黑色渲染。

要求

安装

下载

下载并将此存储库复制到/site/plugins/kirby-blurhash

Composer

composer require tobimori/kirby-blurhash

用法

客户端解码

$file->blurhash()

使用BlurHash对图像进行编码,并返回字符串形式的BlurHash

BlurHash的默认实现假定字符串将在客户端进行解码,使用类似Wolt的blurhashfast-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();

有关asset()助手的更多信息,请在此处查看.

别名

$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,
    ],
];

比较

Comparison image Comparison image Comparison image

致谢

许可协议

MIT License 版权© 2023 Tobias Möritz