写真の明るさ・コントラスト・彩度を直す
写真のファイルを選ぶ
この枠の中に写真を落としても読みます。
選んだ写真はどこにも送りません。読むのはこのブラウザの中だけで、直すのも保存もこの画面で終わります。20,971,520バイト(20MiB)までにしてあります。
写真を選ぶと、明るさ・コントラスト・彩度のつまみが出ます。 画面に出ている絵と、保存されるファイルはまったく同じ計算から作るので、保存して初めて違う絵になることはありません。
よくある質問
プレビューと保存で、違う絵になることはありますか?
ありません。よくある作り方は、画面のプレビューをCSSの`filter`で作り、保存するときだけcanvasで計算し直します。この2つは色の扱いが違うので、わずかにずれることがあります。このページは最初から1枚のcanvasだけを使い、プレビューに描くのも保存するのも同じ関数(core/imgAdjust.tsのadjustPixels)です。保存ボタンは、いま画面に出ているcanvasをそのままファイルにするだけです。
彩度を0にすると本当に白黒になりますか?
なります。彩度のつまみは、色をそのままの色(100)と、輝度(明るさの度合いだけを取り出した灰色)の間を行き来する仕組みで、0にすると完全に輝度側に寄るので、赤も青も緑も同じ灰色になります。輝度の式はITU-R BT.709という国際規格で決まっている0.2126×赤 + 0.7152×緑 + 0.0722×青です。
コントラストを上げすぎたら、あとで元に戻せますか?
このページを開いたままなら戻せます。つまみは常に、最初に読み込んだ元の写真から計算し直しているので、コントラストを0に戻せば元どおりになります。ただし、いったん保存してしまうと話が変わります。255や0に張り付いた画素は、保存されたファイルの中では「元は何色だったか」の情報自体が消えていて、あとから別の画像編集ソフトでコントラストを下げても、その差は戻ってきません。
選んだ写真はどこかに送られますか?
送りません。この道具はファイルをブラウザの中で読み、縮小も明るさの計算も、保存するファイルを作るのも、すべてこの画面の中だけで完結します。fetchも XMLHttpRequestも使っていないので、公開していない写真でもそのまま試せます。
大きな写真を選ぶとどうなりますか?
長い辺が1024pxを超える写真は、比率を保ったまま長い辺が1024pxになるように縮小してから計算します。つまみを動かすたびに写真ぜんぶの画素を計算し直すので、大きいままだと重くなってしまうためです。縮小したかどうかと、実際の大きさは画面に出します。保存される画像もその大きさになります。
保存した画像はどんな形式・大きさになりますか?
PNG形式で保存します。写真によっては透明な部分(PNGやWebPの一部)を持つことがあり、PNGならそれをそのまま保つことができるためです。受け取れるファイルの大きさは20,971,520バイト(20MiB)までです。
写真を選ぶと、明るさ・コントラスト・彩度のつまみでその場に直せます。画面に出ている絵と、保存されるファイルはまったく同じ計算から作ります。選んだ写真はどこにも送りません。
プレビューと保存を、同じ1つの計算にしている理由
写真を直す道具の多くは、画面に出すプレビューと、保存するファイルを別々の場所で作っています。 よくあるのは、 プレビューはCSSのfilter: brightness()のような機能で手早く出し、 保存するときだけ改めてcanvasで色を計算し直す作り方です。
この2つは色の扱いが同じではありません。どちらも「明るさを上げる」という見た目にはなりますが、 内部の計算の順番や丸め方が違うため、画面で見た色と、保存したファイルの色が、わずかにずれることがあります。見た目では気づきにくいまま、ファイルだけ違う絵になっている、という状態です。
このページは、その2つを最初から1本の道にしています。選んだ写真を縮小して1枚のcanvasに描き、つまみが動くたびにcore/imgAdjust.tsの1つの関数で計算し直して、画面に見えているcanvasそのものを書きかえます。 保存ボタンは、その同じcanvasをファイルにするだけです。 別の経路で 「保存用の絵」を作り直すことは一度もありません。
彩度を0にすると白黒になる仕組み
色には、明るさだけを取り出した値(輝度)という考え方があります。 彩度のつまみを0にすると、色はすべてこの輝度の値に置きかわるので、 赤も青も同じ濃さの灰色になります。
たとえば濃いオレンジ色(赤255・緑140・青0)の輝度は
0.2126 × 255 + 0.7152 × 140 + 0.0722 × 0 = 154(小数点以下を丸めた値)
なので、彩度0のこの色は赤・緑・青がすべて154の、同じ灰色になります。
この0.2126・0.7152・0.0722という3つの重みは、ITU-R BT.709(新しいタブで開きます)という国際規格が定めている値です。 緑の重みがいちばん大きいのは、人の目が緑をいちばん明るく感じるからです。
ウェブページの文字が読みやすいかを判定する「相対輝度」という数値も、同じ3つの重みを 使いますが、色をいったんガンマ補正で線形に戻してから足す別の計算です。ここで使っているのは、写真データに入っている値へそのまま重みを掛けたBT.709の輝度信号で、混同しない別ものです。
コントラストを上げると、情報が静かに消えます
コントラストのつまみは、明るいところと暗いところの差を広げます。差を広げるということは、もともと255や0の外にはみ出した値を、255や0で止めるということでもあります。
たとえば明るさを+30すると、もとは240だった画素も255だった画素も、どちらも255で止まります。
240 + 30 = 270(255を超えるので255で止める) / 255 + 30 = 285(同じく255で止める)
止まる前は240と255という、15違う値でした。止まったあとはどちらも同じ255です。2つの違う画素が、区別のつかない1つの値になった ── これが「情報が消える」ということです。下側(暗いほう)でも同じことが起こります。
5 − 50 = -45(0を下回るので0で止める)
このページを開いたままなら、いつでも元どおりに戻せます。つまみは常に、最初に読み込んだときの元の写真から計算し直しているからです。 コントラストを0へ戻せば、240と255の違いも読み直せます。ただし、いったん保存すると事情が変わります。保存されたファイルには、255という値しか残っていません。 そのファイルをあとで別の道具で開き、コントラストを下げても、「元は240だったのか255だったのか」という情報は戻ってきません。写真の仕事でRAW形式を残しておく人が多いのは、この「戻せなさ」があるからです。
コントラストを一番下(−100)まで下げると、逆のことが起こります。真っ黒に近い色も鮮やかなピンクも、どんな写真もただ1色の灰色(128, 128, 128)になります。実際につまみを一番左まで動かして、確かめてみてください。
調整のあとで255や0に張り付いた画素がどれだけ増えたかは、 上の道具の中に小さいグラフと数で出しています。
大きな写真は縮小してから計算しています
つまみを1つ動かすたびに、写真の画素すべてを計算し直しています。 スマートフォンの写真は4000pxを超えることも珍しくなく、そのまま計算すると つまみを動かしてから絵が変わるまでに時間がかかり、動きがカクカクします。
そこでこのページは、長い辺が1024pxを超える写真を、比率はそのままに1024pxまで縮小してから計算しています。縮小したかどうかと、実際に計算している大きさは、 写真を選ぶと画面に数字で出します。保存される画像もこの大きさです。元の写真をそのままの解像度で保存する道具ではないことは、ここではっきり書いておきます。
数値の出どころ: 輝度の重み(0.2126・0.7152・0.0722)はITU-R BT.709-6 の item 3.2(新しいタブで開きます)から。同種のツール(digrart.jp・imagy.app)を実際に開いて、 数値入力・ヒストグラム・縮小の扱い・プレビューと保存の一致について何を書いているかを 比べたうえで、このページの説明を書いています。