写真を描いた後で ctx.filter を変えても、その写真の画素は変わらない。グレースケールで描くには、drawImage() を呼ぶ前にフィルターを設定する。
function drawGray(ctx, img) {
if (!("filter" in ctx)) {
throw new Error("Canvas filter is unavailable");
}
ctx.save();
try {
ctx.filter = "grayscale(100%)";
ctx.drawImage(img, 0, 0);
} finally {
ctx.restore();
}
}
ここではデコード済みの画像と、サイズ設定とクリアを済ませた出力 Canvas を使う。座標変換や透明度などは通常の状態とし、元の大きさの画像を左上へ描く。
save() と restore() でフィルターを含む描画設定を元へ戻せる。ただし、restore() は描画済みのグレースケール画像をカラーには戻さない。カラー版が必要なら、元画像から別の結果を描く。
この処理で使うのは 2D コンテキストのフィルターである。Canvas 要素に CSS の filter を指定する方法と混同しないようにする。
MDN は filter を Limited availability としている。例ではプロパティがない環境の処理を中断する。実際に使うブラウザーで出力を確認し、フィルターが必須なら未対応時にカラー画像を返さず、その状況を呼び出し側へ知らせる。