なぜChromeで見る小さなJPEG画像は、他のブラウザと見た目が違うのか?
Why tiny JPEGs look different in Chrome
Why tiny JPEGs look different in Chrome
小さなJPEG画像を表示した際、Chromeでだけ色が微妙に違ったり、表示が崩れたりしているのを感じたことはありませんか?これはChromeのレンダリングエンジンやカラーマネジメントの処理が、他のブラウザと比較して画像データをどう解釈しているかに起因する興味深い現象です。特定の画像圧縮形式における最適化の仕様の違いが、この表示差を生み出す原因となっています。
で、Firefoxはフルレンダリングしてからスケーリングしてるの?それとも何か別の方法で部分的なレンダリングをしてるってこと?片方の側面しか話してない気がする。
ChromeとFirefoxはそれぞれ違うスケーリングアルゴリズムを使ってて、それがこの差にかなり影響してるはず。Chromeは全体的にボヤけがちだけど、Firefoxはシャープな分、リンギングノイズが少し目立つ感じ。個人的にはFirefoxの描画の方が好みだな。
Firefoxにおける縮小時のデコード処理(decompressing at a lower scale)に関する作業は、ここで進められているよ: https://bugzilla.mozilla.org/show_bug.cgi?id=2033250
同じ問題はPNGでも起きるはずだよ。PNGはロスレスだから本来アイコンには最適で、JPEGみたいな圧縮ノイズ(記事にある通り、そもそもJPEGは写真用だしね)も出ないし、アルファブレンディングにも対応してるし。
Chromeがこの「最適化」を導入したとき、それがElectronのリリースに紛れ込んでしまって、うちのプロダクトの至るところでアイコンが崩れるという悲惨なことになったんだ。SVGで置き換えるまでの間、アップグレードを見送らざるを得なかったよ。
SVGはライトモード/ダークモードに対応できる利点もあるしね。ただ、同じ名前のSVG同士でスタイルが競合しないように、それぞれのアイコンを個別のシャドウDOMに入れる必要があって、うちのデザイナーが少し面倒そうにしていたけど。
結局、アイコンとかにJPEGを使うな、というのが教訓だね。
それに、もっと大事なのは表示サイズに合わせた適切な解像度の画像を使うこと。PNGに切り替えたとしても、20x20で表示するアイコンに2000x2000の画像を使うのは無駄だよ。
15pxというサイズなら、ICOファイルを使うのは意外と悪くない解決策かもね。まあPNGやGIFでもいいのは分かってるけど、もしICO形式が今でもFaviconとして複数解像度や綺麗なスケーリングをサポートしているなら、ドキュメント用の画像でも使えたりしないのかな?
レンダリング品質を気にするなら、ブラウザ任せで縮小表示しちゃダメだよ。ブラウザは一貫して最高品質のアルゴリズム(Lanczos 3-lobeとか)を使ってくれるわけじゃないから。これはPartial IDCTとは別の話。ブラウザは基本的にパフォーマンスを優先するし、採用されるアルゴリズムはその時のGPU環境に依存することもある。
まあ、WebでUIを開発する以上、ブラウザやユーザーによって見え方が多少変わるのは許容されるべきだね。Canvasを使って自前で画像レンダラーを書かない限りは。そこまでこだわるならネイティブコードで書くのが一番だよ。
DC成分で1/8に縮小できるのは有名だけど、面白いのはこれが汎用的ってこと。つまり、LF係数の2x2ブロックだけを使えば1/4(4x4ブロックなら1/2)の縮小もできるわけだ。
CSSの「image-rendering」属性で制御できることもあるよ。これを使えばスケーリングアルゴリズムを指定できる。ブラウザによって解釈が違うみたいだけど。高DPIモニターでブラウザごとに画像の見え方が違ったときにこれを見つけたんだ。
普段AIの記事に文句を言ってる人たちは、どうやらこういう技術的なトピックには興味がないみたいだね。