BlurHash ジェネレーター

任意の画像から BlurHash プレースホルダー文字列を生成。~30 バイトの短い文字列がぼかし画像として表示され、Next.js のローディング、Unsplash 風フィード、SSR に最適。

Loading…

すべての処理はブラウザ内で実行されます — ファイルや入力はサーバへ送信されません。

使い方

ファイルピッカーに画像を投下します — JPEG・PNG・WebP・GIF・AVIF すべて動作します。ブラウザが `<img>` 要素経由でデコードするためです。本ツールは画像を長辺 64 px に縮小し、選んだ X/Y コンポーネント数(既定 4×3)で Wolt の `blurhash` エンコーダを実行し、~28 文字の結果文字列と 256 px のデコードプレビューキャンバスを出力します。コンポーネント数を増やすほど細部を捉えられますが、ハッシュは長くなります: 4×3 は 28 文字、9×9 は 67 文字。4×3 は Unsplash 公開の既定で、ほぼ常に十分です。

エンコードされた BlurHash は base83 文字列で、データベースカラム、API レスポンス、JSX prop に収まります。レンダリング側では同じ `blurhash` ライブラリ(またはドロップイン用の `react-blurhash`)で実際のプレースホルダーサイズにデコードして `<canvas>` に描画するか、Next.js の Image コンポーネントの `placeholder="blur"` として使います。代替とのトレードオフ: 生の 64 px サムネイルは 1〜4 KB で見た目はほぼ同じですが、BlurHash は 30 バイトで他の画像メタデータと同じ JSON レスポンスに入ります — ページごとに 100 以上のサムネイルを返すと差が効いてきます。エンコーダはブラウザ内で完結し、画像データはネットワークエンドポイントに到達しません。

Unsplash 風の 4×3 既定

入力
image:        landscape-photo.jpg (4032 × 3024 px, 2.8 MB)
encode:       4 × 3 components (default)
use case:     general-purpose blur placeholder
出力
hash:         LEHLk~WB2yk8pyo0adR*.7kCMdnj
hash length:  28 characters
bytes:        30 (UTF-8) — fits in a single PostgreSQL TEXT cell
decoded preview: 256 × 192 canvas, looks like a heavily blurred version of the input

4×3 は Unsplash の本番設定で、BlurHash 公開ブログの推奨既定値です。先頭文字(`L`)はコンポーネント数をエンコードし、続く 2 文字は最大 AC 成分(正規化に使用)、残りは DC 成分(平均色)と各チャンネルの AC 成分(勾配項)をエンコードします。4×3 ハッシュは画像の全体的な形状と支配色を十分にとらえるため、フル解像度画像がストリーミングされる間にユーザーは即座のフィードバックを得られます。ハッシュはロケール不変で、同じ画像を macOS と Linux で与えるとバイト同一の出力になります。

高ディテール 9×9 ポートレートハッシュ

入力
image:        portrait.jpg (face occupies center 60% of frame)
encode:       9 × 9 components
use case:     profile photo blur — face shape should be discernible
出力
hash:         LKO2?V%2Tw=w]~RBVZRi};RPxuwH%3t8WC0L0~Lo~SRP$|JE,N9d%6gP0ZJ%R
hash length:  67 characters
bytes:        69
perceptual quality: skin tone, hair shape, background color all distinguishable
encoder time: ~120 ms in browser (vs. ~5 ms for 4×3)

ポートレート、プロフィール写真、商品ヒーローショットなど、フル画像が読み込まれる前に被写体を視聴者に認識させたい場合は、コンポーネントを 6×6 や 9×9 まで上げます。コスト: エンコーダ時間は O(width × height × components_x × components_y) なので、9×9 ハッシュのエンコードは 4×3 より約 30 倍長く — 適切な入力サイズなら 1 秒未満ですが、サーバ側で数千枚を一括エンコードする場合は知っておく価値があります。最大コンポーネントは BlurHash 仕様により 9×9。エンコーダはそれ以上の値も受け付けますが、入力は内部的に 32 × 32 にダウンスケールされるため情報量は増えません。

均一背景 — 最小 1×1

入力
image:        solid-blue-sky.jpg (almost no detail)
encode:       1 × 1 components
use case:     placeholder for known-uniform images (sky, gradient, brand backdrop)
出力
hash:         00OG^x
hash length:  6 characters
bytes:        6
decoded preview: single solid color matching the image's average
encoder time: <1 ms

1×1 は BlurHash を DC 成分のみに縮退させます — 画像の平均色だけです。ハッシュは 6 文字で、結果は CSS の単色 `background-color` と見分けがつきません。実画像を待つ間にレイアウト空間を代表色で確保するだけで十分なプレースホルダーに有用です。ブラウザヒント `<img style="background-color: #...">` は半分のコストで同じことをしますが、BlurHash は既存の画像メタデータパイプラインに色を一元化できます。意味ある構造(ロゴ、商品、顔、風景)を持つ画像には少なくとも 3×3 を使ってください。

よくある質問

BlurHash は誰が作り、なぜ作られたのですか?

BlurHash は 2018 年に **Dag Ågren** によって公開されました。彼は **Wolt**(フードデリバリー、後に DoorDash が買収)のフィンランドのエンジニアです。Wolt のモバイルアプリはリストスクロール中の画像プレースホルダーが必要でした — 遅いモバイル回線でレストランのメニューを閲覧するとき、写真が読み込まれる空のグレーボックスは違和感を与えました。単色の平均色ブロック(単純すぎる)、小さなプリデコードサムネイル(JSON ペイロードで大きすぎる)、SQIP / Polished スタイルの SVG 近似(脆すぎる)を試した後、BlurHash は中間を取りました: 認識できるぼかしにデコードされる ~30 バイト。リファレンス実装は C で、TypeScript、Swift、Kotlin、Python、Go、Rust への移植があります。アルゴリズム自体は base83 にパックされた小さな離散コサイン変換です。**MIT ライセンス** なので商用アプリでも自由に出荷できます。

BlurHash はどうやって画像を 30 バイトまで圧縮するのですか?

**JPEG** の中核と同じ数学である **離散コサイン変換**(DCT)です。ただし高周波係数を積極的に切り捨てます。エンコーダは入力画像を縮小し、小さな画像の DCT を計算し、各 RGB チャンネルの components_x × components_y の最も低周波の係数のみを保持し、値を base83 ASCII にパックします。デコードはその逆です: 係数を読み、IDCT、キャンバスに描画。圧縮比は DCT 係数の約 99% を捨てることから来ます — 結果は数本のなめらかなカラーグラデーション以上のディテールは持ちませんが、それらのグラデーションは小サイズにおける画像の「雰囲気」を運ぶものです。エンコーダは内部で線形光 sRGB を使い色のブレンドを自然に見せ、デコーダはレンダリング前に sRGB に戻します。

BlurHash 対 LQIP / SQIP / ThumbHash — どれを使うべきですか?

**LQIP**(Low-Quality Image Placeholder)はただの縮小 JPEG(品質 5〜10%、通常長辺 16〜32 px)です。data URI でインライン化すると 200〜500 バイト — BlurHash より大きいですが、JavaScript なしでレンダリングでき、Next.js の `placeholder="blur"` でネイティブサポートされます。**SQIP** は画像を近似する SVG プリミティブを生成します。視覚的に独特ですが 1〜3 KB でエンコードも遅いです。**ThumbHash**(2023 年、Figma の Evan Wallace 作)は BlurHash の現代的競合です — ~25 バイト、わずかに視覚品質が良く、透明度に対応し、デコードが速いです。エコシステムサポートが最大限必要なら **BlurHash**(主要全言語にポートあり、Unsplash 統合)。今日始める新規プロジェクトには **ThumbHash**(同じ考え方、わずかに良いトレードオフ、ただしエコシステムは若い)。レンダリングパスで JavaScript を実行しない、または CDN が既に画像を最適化しているなら **LQIP**。

Next.js や React で BlurHash を使うには?

React では **`react-blurhash`** パッケージが最も簡単です: `<Blurhash hash={hash} width={400} height={300} />` がクライアント側で canvas を描画します。サーバレンダリング React の場合、ハッシュをサーバ側で RGBA ピクセルにデコードして base64 データ URL を出力し、それを `<img src=...>` または CSS `background-image` として使います — Next.js の `placeholder="blur"` が静的画像で内部的に行っていることです。Next.js Image に BlurHash を組み込むには、ページの `getStaticProps` / Server Component fetch でハッシュをデータ URL にデコードし、`blurDataURL` として渡し、`placeholder="blur"` を設定します。注意: Next.js の組み込み blur は BlurHash 文字列ではなく base64 JPEG/PNG データ URL を期待します — 先にデコードする必要があります。Vue、Svelte、Solid もそれぞれ類似パッケージがあります: `vue-blurhash`、`svelte-blurhash`、`solid-blurhash`。素の HTML でも動作します: `blurhash` npm パッケージを読み込み、ImageData にデコードし、canvas に描画。

BlurHash をブラウザではなくサーバでエンコードできますか?

はい、本番環境では普通そうします。Node.js の `blurhash` パッケージは本ツールと同じライブラリでブラウザ外で動作するだけです。任意の画像形式をデコードしエンコード前に縮小するには `sharp` と組み合わせます。Python: `blurhash-python`。Go: `github.com/buckket/go-blurhash`。Rust: `blurhash` クレート。典型的なパイプライン: 画像アップロード → `sharp({raw}).resize(64).raw().toBuffer()` → `encode(buffer, 64, 64*h/w, 4, 3)` → DB の画像 URL の隣にハッシュを保存。ここのブラウザツールはアドホックなワンオフエンコード、コンポーネント数の設計検証、または画像アップロードパイプラインを制御できない場合のためのものです。サーバ側エンコードは類似性クエリ用にハッシュをインデックス化できるという利点もあります — DC 成分だけで「支配色が類似する画像を見つける」用の小さなパーセプチュアルハッシュとして機能します。

デコードプレビューが元画像より彩度が高く見えるのはなぜですか?

BlurHash は線形 sRGB 色空間でエンコードされます — アルゴリズムはガンマカーブを除去した *後で* 色を平均化し DCT 変換するので、知覚的に正しい色のブレンドが得られます。デコーダに `punch` 値を 1 より大きく指定すると(`react-blurhash` の既定は 1.0 ですが、一部の統合は 1.5 を既定にします)、AC 成分が増幅され色が元画像より鮮やかになります。忠実な再現には `punch: 1.0` でデコード。実画像が届く前にプレースホルダーを「生き生き」とさせたいときだけ高い punch を使い、スワップ時に短い色シフトが起こることを受け入れます。一部の BlurHash 統合は線形光補正を欠いて代わりに色あせた出力を出すこともあります — 色が変なら参照実装と比較してください。

関連する概念

BlurHash は **プレースホルダー画像** または **プログレッシブ画像ロード** と呼ばれるカテゴリに位置し、その系譜はインターレース GIF / JPEG プログレッシブデコード(1986 年の CompuServe 向け Marc Adler の研究、1994 年の JFIF プログレッシブベースライン)にさかのぼります。共通の目標: 視聴者に *何か* を即座に表示してページが何もロードしていないように見えないようにし、ディテールは時間をかけて到着させる。現代の Web は 2014 年頃にこのアイデアを再訪しました — **Medium** が、小さな埋め込みサムネイルで CSS blur フィルターを駆動する有名なブログ記事を公開しました — これが現在 **LQIP** と呼ばれているものです。そこから: Cloudinary の **ベクトル化 SVG** プレースホルダー(2016)、Tobias Baldauf の **SQIP**(2017)、Wolt の **BlurHash**(2018)、Figma エンジニア Evan Wallace の **ThumbHash**(2023)。各反復はバイト数と知覚品質、エコシステム成熟度のトレードオフを変えました。2024 年以降の世代には **AVIF / WebP プログレッシブロード** が含まれ、これによりブラウザはフル画像が到着する前に同じファイルの低ディテール版をレンダリングできます。

下層の数学は 1974 年に Nasir Ahmed が導入した **離散コサイン変換**(DCT)で、これは JPEG、MP3、MPEG、H.264 ビデオを支える同じ変換です。DCT は空間周波数を分離します: 低周波成分は広いグラデーションと色の遷移を捉え、高周波成分は鋭いエッジや細かいテクスチャを捉えます。高周波を捨てると画像は緩やかに劣化します — 人間は低周波内容のほうをはるかに強く知覚するためです。BlurHash はこれを論理的極限まで進め、RGB チャンネルあたり 9〜81 個の DCT 係数だけを保持して密にパックします。JPEG は数千個保持します。同じ洞察は逆画像検索エンジンで使われるサムネイル生成と画像ハッシュ技術(pHash や dHash といった知覚ハッシュは同様に DCT 係数を切り詰めます)の基礎にもあります。

隣接する 3 つの関心事が BlurHash と交差します。**累積レイアウトシフト**(CLS)は、コンテンツがロードされる際に要素が動くページを罰する Core Web Vitals メトリクスです — 画像プレースホルダーは正確なピクセル空間を予約することで CLS を防ぎます。プレースホルダーが最終画像と同じ幅 × 高さを占めるため、BlurHash はここで有効です。**アクセシビリティ**: BlurHash プレースホルダー自体には alt テキストや意味的コンテンツがありません — `<img alt="...">` とペアにし、スクリーンリーダーが canvas ではなく alt を読むようにしてください。**コンテンツセキュリティポリシー**: BlurHash デコードは `<canvas>` とインライン base64 データ URI を使用し、どちらも厳格な CSP の `script-src` や `img-src` ルールで制限される可能性があります — デコード済み BlurHash サムネイルをデータ URL として配信する場合は、`default-src` が `data:` URI を許可することを確認してください。いずれも BlurHash 採用の障害ではなく、統合時に検証すべき運用上のディテールです。

関連ツール