2022.11.08
blurhashで画像読み込み前のぼかし画像を表示する

複数の大きなサイズの画像を読み込む場合、読み込みから表示されるまでに多少時間がかかることがあります。
そんなとき、「ここに画像が入るよ」というのを予め示しておきたい場合に使えるライブラリを紹介。
仕組みとしては、画像ファイルからハッシュ値を生成し、生成したハッシュ値を利用して画像をぼかした状態のものをcanvasで生成します。
前提条件
以下をインストール済みであること
- Node.js(16系)
- npm または yarn
この記事ではReact(Next.js)のサイトで利用することを前提とします。
使うもの
- Next.js
- blurhash ... ハッシュ値の生成・表示側で利用
- react-blurhash ... 表示側で利用
やること
- blurhashを利用して画像ファイルからハッシュ値を生成
- 1の値を利用して、react-blurhashで表示側でcanvasを生成
1. blurhashを利用して画像ファイルからハッシュ値を生成
ハッシュ生成スクリプト
import { encode } from 'blurhash'
const loadImage = async (src: string) =>
new Promise((resolve, reject) => {
const img = new Image()
img.onload = () => resolve(img)
img.onerror = (...args) => reject(args)
img.src = src
})
const getImageData = async (image: any): Promise<ImageData | undefined> => {
const canvas = document.createElement('canvas')
canvas.width = image.width
canvas.height = image.height
const context = canvas.getContext('2d')
context?.drawImage(image, 0, 0)
return context?.getImageData(0, 0, image.width, image.height)
}
export const encodeImageToBlurHash = async (imageUrl: string): Promise<string> => {
const image = await loadImage(imageUrl)
const imageData = await getImageData(image)
return imageData ? encode(imageData.data, imageData.width, imageData.height, 4, 4) : ''
}
画像からハッシュを生成
const imgElement: HTMLElement | null = document.getElementById('{imgタグのID}')
if (!imgElement) return
const img = imgElement as HTMLImageElement
const imageSrc: string = img.src
const hash: string = await encodeImageToBlurHash(imageSrc)
2. 1の値を利用して、react-blurhashで表示側でcanvasを生成
import React from 'react'
import { BlurhashCanvas } from 'react-blurhash'
interface Props {
blurHash: string // 1で生成したハッシュ値
}
const Component: React.FC<Props> = (props: Props) => {
const { blurHash } = props
return (
<div>
<BlurhashCanvas {...{ hash: blurHash }} />
</div>
)
}
以下の画像で実行した場合
元の画像

表示側のキャプチャ
