はじめに
Spotifyでアルバムを開いたとき、背景がジャケットの色にふわっと馴染む演出を見たことはありませんか。ユーザーがアップロードした画像に合わせてカードの背景色が変わる、サムネイルに調和したグラデーションが敷かれる——ああいう「画像に寄り添うUI」は、デザイナーが1枚ずつ色を指定しているわけではありません。画像から代表色をプログラムで抽出しているのです。
これを自前で実装しようとすると、Canvasにピクセルを展開して、量子化アルゴリズムを書いて……と意外に大変です。そこで登場するのがColor-Thief。その名の通り、画像から色を「盗み出す」ライブラリで、GitHubスター13.6kを超える定番中の定番です。2026年7月リリースのv3.4ではDisplay P3(広色域)対応も入り、モダンなAPIに生まれ変わっています。
Color-Thiefとは
Color-Thiefは、画像や動画からドミナントカラー(支配的な色)やカラーパレットを抽出するJavaScriptライブラリです。ブラウザでもNode.jsでも動作し、ランタイム依存ゼロという軽量さが魅力です。
主な特徴
- 依存ゼロで軽量 - ランタイム依存パッケージがなく、バンドルサイズへの影響が最小限です
- リッチなColorオブジェクト - v3では戻り値が単なるRGB配列ではなく、
.hex()や.oklch()での形式変換、WCAGコントラスト比、推奨テキスト色まで持つオブジェクトになりました - 動画のライブ抽出に対応 -
observe()で再生中の動画から色を追従抽出でき、アンビエント演出が簡単に作れます - TypeScript・Web Workers・AbortSignal対応 - モダンなフロントエンド開発にそのまま組み込めます
インストール
npmを使う場合は次の1行です。
npm install colorthief
ビルド環境を用意せずに試したい場合は、CDNからUMDビルドを読み込めます。
<script src="https://unpkg.com/colorthief@3/dist/umd/color-thief.global.js"></script>
Node.jsで使う場合は、画像デコードのためにピア依存のsharpも入れておきます。
npm install colorthief sharp
基本的な使い方
ドミナントカラーを1色取り出す
ブラウザでは、読み込み済みの<img>要素を渡すだけです。同期版のgetColorSync()が使えます。
import { getColorSync } from 'colorthief';
const img = document.querySelector('#album-art');
img.addEventListener('load', () => {
const color = getColorSync(img);
console.log(color.hex()); // '#e84393'
console.log(color.css()); // 'rgb(232, 67, 147)'
console.log(color.isDark); // false
console.log(color.textColor); // '#000000' ← この色の上に置く文字色の推奨値
});
ポイントはtextColorです。抽出した色を背景に使うとき、「文字は白と黒どちらが読めるか」をライブラリが判定してくれるので、コントラスト計算を自分で書く必要がありません。
カラーパレットを取り出す
複数色が欲しいときはgetPaletteSync()です。
import { getPaletteSync } from 'colorthief';
const palette = getPaletteSync(img, { colorCount: 6 });
palette.forEach((c) => console.log(c.hex()));
Node.jsでの利用
Node.jsではファイルパスやBufferを渡せます。APIは非同期のみです。
import { getColor, getPalette } from 'colorthief';
const color = await getColor('/path/to/image.jpg');
console.log(color.hex());
const palette = await getPalette('/path/to/image.jpg', { colorCount: 5 });
ビルド時にOGP画像から記事のテーマカラーを事前計算しておく、といった静的サイトでの活用にも向いています。
クロスオリジン画像の注意点
外部ドメインの画像を扱う場合、CanvasのセキュリティによりCORSの制約を受けます。画像サーバー側でAccess-Control-Allow-Originを設定したうえで、img要素にcrossorigin属性を付けてください。
<img src="https://cdn.example.com/photo.jpg" crossorigin="anonymous" />
これを忘れると、色の抽出時に例外が発生します。ローカル開発でファイルをfile://で直接開いた場合も同様に失敗するので、必ず開発サーバー経由で確認しましょう。
実践的なユースケース
冒頭のSpotify風カードを作る
アルバムアートからドミナントカラーを取り出し、背景グラデーションと文字色に反映してみます。コピペで動く最小構成です。
<div id="card" style="padding: 2rem; border-radius: 12px;">
<img id="album-art" src="/images/album.jpg" width="200" />
<h2 id="card-title">Album Title</h2>
</div>
<script src="https://unpkg.com/colorthief@3/dist/umd/color-thief.global.js"></script>
<script>
const img = document.querySelector('#album-art');
const applyTheme = () => {
const color = ColorThief.getColorSync(img);
const card = document.querySelector('#card');
card.style.background =
`linear-gradient(180deg, ${color.css()} 0%, #121212 100%)`;
document.querySelector('#card-title').style.color = color.textColor;
};
if (img.complete) {
applyTheme();
} else {
img.addEventListener('load', applyTheme);
}
</script>
img.completeのチェックを入れているのは、キャッシュ済み画像ではloadイベントが発火しないことがあるためです。実務で組み込むときの定番の書き方として覚えておくと安全です。
セマンティックな色分類で「使える色」だけ拾う
ドミナントカラーは便利ですが、「一番多い色」が地味なグレーだった、ということもよくあります。v3のgetSwatches()は、抽出色をVibrant(鮮やか)やMuted(落ち着いた)など6つの意味的な役割に分類してくれます。
import { getSwatches } from 'colorthief';
const swatches = await getSwatches(img);
// アクセントカラーには鮮やかな色を優先し、なければドミナントにフォールバック
const accent =
swatches.Vibrant?.color.hex() ?? getColorSync(img).hex();
document.documentElement.style.setProperty('--accent', accent);
CSSカスタムプロパティに流し込めば、サイト全体のテーマカラーを画像駆動にできます。
動画に追従するアンビエント背景
YouTubeの「アンビエントモード」のように、再生中の動画の色を背景に滲ませる演出もobserve()だけで実現できます。
import { observe } from 'colorthief';
const video = document.querySelector('video');
const controller = observe(video, {
throttle: 200, // 200msごとに抽出(負荷とのバランス調整)
colorCount: 5,
onChange(palette) {
document.body.style.background =
`radial-gradient(circle at top, ${palette[0].css()}, #000)`;
},
});
// 不要になったら止める(コンポーネントのアンマウント時など)
controller.stop();
throttleで抽出頻度を制御できるため、パフォーマンスを犠牲にせずリッチな演出が入れられます。ReactやVueで使う場合は、クリーンアップ処理で必ずcontroller.stop()を呼ぶのを忘れないでください。
まとめ
Color-Thiefを使えば、これまでデザイン工数や複雑な画像処理コードが必要だった「画像に馴染むUI」が、ほんの数行で手に入ります。
getColorSync()/getPaletteSync()で画像から即座に色を抽出できます- Colorオブジェクトが
textColorやコントラスト比まで教えてくれるので、アクセシビリティ対応も楽になります getSwatches()で「鮮やかな色だけ欲しい」といった実務的な要求に応えられますobserve()を使えば動画連動のアンビエント演出まで作れます
まずはCDN版をHTMLに1枚貼って、手元の画像でgetColorSync()を叩いてみてください。抽出された色がUIに流れ込む瞬間の気持ちよさは、一度体験すると手放せなくなるはずです。
