Canvas 2D 画像処理:ブラウザでのピクセル操作の原理と実践
画像処理における Canvas の役割
ブラウザには 3 つの画像処理パスがあります:
| 方式 | パフォーマンス | 柔軟性 | 用途 |
|---|---|---|---|
| CSS filter | 高(GPU) | 低(プリセットフィルター) | シンプルな視覚効果 |
| Canvas 2D | 中 | 高(ピクセル単位) | 圧縮、クロップ、形式変換 |
| WebGL | 最高 | 高(シェーダー必要) | 複雑なフィルター、リアルタイム処理 |
ToolsKu の画像ツール(圧縮、クロップ、形式変換、ウォーターマーク)はすべて Canvas 2D API を基盤としています。
基本的な処理フロー
// 1. 画像を読み込む
const img = new Image();
img.src = URL.createObjectURL(file);
await img.decode();
// 2. Canvas を作成して描画
const canvas = document.createElement('canvas');
canvas.width = img.width;
canvas.height = img.height;
const ctx = canvas.getContext('2d')!;
ctx.drawImage(img, 0, 0);
// 3. 目的の形式でエクスポート
const blob = await new Promise<Blob>((resolve) =>
canvas.toBlob(resolve, 'image/webp', 0.85) // 品質 85%
);
画像圧縮の原理
Canvas による圧縮は本質的に再エンコードです:
元の PNG (2MB, 可逆)
↓ Canvas に drawImage
↓ toBlob('image/jpeg', 0.8)
圧縮 JPEG (400KB, 非可逆 80% 品質)
| 形式 | 圧縮方式 | 典型的な圧縮率 | 透明度 |
|---|---|---|---|
| JPEG | 非可逆 DCT | 60-80% | ❌ |
| WebP | 可逆/非可逆 | 70-90% | ✅ |
| PNG | 可逆 DEFLATE | 10-30% | ✅ |
| AVIF | 可逆/非可逆 | 80-95% | ✅ |
ToolsKu の 画像圧縮ツール は WebP/JPEG の一括圧縮に対応。デフォルト品質 85% でファイルサイズと画質のバランスを最適化しています。
ピクセル単位の操作
ImageData で RGBA ピクセルを直接操作:
const imageData = ctx.getImageData(0, 0, width, height);
const data = imageData.data; // Uint8ClampedArray, 4 バイト = 1 ピクセル
for (let i = 0; i < data.length; i += 4) {
// グレースケール化
const avg = (data[i] + data[i+1] + data[i+2]) / 3;
data[i] = data[i+1] = data[i+2] = avg;
}
ctx.putImageData(imageData, 0, 0);
OffscreenCanvas によるパフォーマンス最適化
メインスレッドの Canvas 操作は UI をブロックします。OffscreenCanvas は Worker 内で実行できます:
// worker.ts
const offscreen = new OffscreenCanvas(width, height);
const ctx = offscreen.getContext('2d')!;
ctx.drawImage(imageBitmap, 0, 0);
const blob = await offscreen.convertToBlob({ type: 'image/webp', quality: 0.85 });
postMessage({ blob }, [blob]); // Transferable
50 枚の画像を一括処理する場合、OffscreenCanvas + Worker によりメインスレッドのブロックを 10 秒から 0 に短縮できます。
よくある質問
圧縮後に画像がぼやけるのはなぜ?
JPEG/WebP の非可逆圧縮は高周波のディテールを失います。品質パラメータを上げる(0.9+)か、PNG/WebP の可逆モードを使用してください。
Canvas にサイズ制限はある?
ほとんどのブラウザでは Canvas の 1 辺の最大が 16384px、総面積は約 268MP です。この制限を超える場合はタイル分割処理が必要です。
EXIF の向き情報はどう処理する?
スマートフォンで撮影した写真には EXIF Orientation が含まれることがあります。描画前に EXIF を読み取り Canvas を回転しないと、画像の向きが正しくありません。ToolsKu の 画像形式変換 は EXIF を自動処理します。
まとめ
Canvas 2D はブラウザ側画像処理の標準的なアプローチです。drawImage → toBlob のエンコードパイプライン、ImageData によるピクセル操作、OffscreenCanvas による Worker オフロードを理解することが、高性能な画像ツール構築の核心です。
ブラウザローカルツールを無料で試す →