何かを変えるためには習慣を変えるほかないということで、とりあえず毎日1時間ぐらい歩くことをはじめてみてる。

大まかに以下の通り4通りのパターンが考えられる。

  1. 朝、自宅最寄り駅に近い数駅歩く
  2. 朝、会社最寄り駅に近い数駅歩く
  3. 夜、自宅最寄り駅に近い数駅歩く
  4. 夜、会社最寄り駅に近い数駅歩く

しかし通勤時間帯を避けようと思うと、2 は無理。夜歩くと帰宅時間が結構遅くなるので嫌。ということで1になる。

しかし最寄り駅付近は歩いても面白くないという致命的な問題がある。立地の事情により特定ルートを通らざるを得なく続けていると単調になってしまう。

変化

正直いってあんまりない。便通が改善したかもしれない。晴れている日が多くて気持ちいいけど精神的に良くなったりはしてない。

Chrome, Firefox, Safari で調べたところ、

  • Chrome: カラーマネジメントされない ( sRGB は適用されない)
  • Firefox: デフォルカラーマネジメントされない (後述。オプションによる)
  • Safari: sRGB が適用される

Firefox の場合

gfx.color_management.mode

によって挙動が変わる。2がデフォルトだが、2の場合は sRGB が適用されない。1の場合は sRGB が適用される。

  • カラープロファイルがない画像
  • CSS の色指定
  • canvas の色指定

に影響する。

CSS の色と画像の色をあわせるには

現状では画像に ICC Profile をつけないようにするのがベスト。色の再現を捨ててあわせにいく感じ。

CSS の色を sRGB にあわせたい場合は

CSS も含めてあわせるのは無理 (ということにしておくと吉)

備考

Firefox Chrome ともに起動時にディスプレイプロファイルを読みこむので、あとから変えても反映されない。また、プライマリディスプレイのプロファイルしか読みこまないので注意。

CSS の色を sRGB にあわせるには

実は少し可能なことがわかったので「(黒魔術) CSS の色を sRGB にあわせるには」というのをあとで書く → 書いた https://lowreal.net/2017/02/07/4

  1. トップ
  2. tech
  3. CSS の色空間は sRGB のはずだけど…

Chrome と Firefox では CSS の色にカラーマネジメントが適用されず、sRGB の画像と色をあわせることが基本的に無理です。

で、無理なんですが無理ではなくて、実は頑張れば sRGB にあわせることができることがわかりました。

デモ

以下のような感じになっていて、書いてある通りです。Chrome と Firefox だと上3つと下3つの色が異なります。Safari だと全て sRGB 扱いされるので全部同じに見えるはずです。ただしカラーマネジメントが有効かどうかの判定を入れてないので、カラーマネジメントに対応してないシステムでも全部同じになっています。

一番下の色が JS で CSS のルールを書きかえて sRGB にしたものです。

やっていること

要は使う色をあらかじめ sRGB プロファイルの PNG に描いておき、この画像のレンダリング結果を canvas に drawImage して、getPixelData を行うとディスプレイプロファイルが適用されたRGB値を取得することができるので、これを動的に CSS の色として適用すれば sRGB にできます。

sRGB の画像を canvas に描くってところがポイントです。

自動的にCSSから色を抽出して sRGB を適用する

が、これは手動でやろうとすると面倒なので、CSSから色を抽出し、動的に sRGB PNG を作ってRGB値を変換してやるというのをやってみました。実用的かというと実用的ではないんですが、できそうですねってところです。

  1. CSS から色を抽出 (cssRules から)
  2. canvas に全部の色を描く
  3. canvas から toDataURL で PNG を得る
  4. この PNG に sRGB プロファイルを埋めこむ
  5. img 要素で読みこませる
  6. canvas に img 要素を drawImage する
  7. canvas の色を読む
  8. CSS に色を書き戻す

という手順でやります。

document.styleSheets の内容を書きかえているので、要素個別に書かれたスタイルについては対応できてません。

CSS の色を抽出

雑に以下のようにしました。当然完璧ではありませんが…

function scanStyleSheetColors (cb) {
	for (var i = 0, stylesheet; (stylesheet = document.styleSheets[i]); i++) {
		for (var j = 0, rule; (rule = stylesheet.cssRules[j]); j++) {
			for (var k = 0, name; (name = rule.style[k]); k++) {
				var val = rule.style.getPropertyValue(name);
				if (/rgb\((\d+),\s*(\d+),\s*(\d+)\)/.test(val)) {
					var r = RegExp.$1;
					var g = RegExp.$2;
					var b = RegExp.$2;
					var ret = cb(r, g, b);
					if (ret) {
						var newVal = 'rgb(' + ret.join(',') + ')';
						console.log(rule, name, val, '->', newVal);
						rule.style.setProperty(name, newVal, rule.style.getPropertyPriority(name));
					}
				}
			}
		}
	}
}

canvas に sRGB プロファイルを適用して PNG の data URL 化

// to PNG data URL with sRGB profile
function applyProfile (canvas) {
	function pngChunk (type, data) {
		var LEN_LENGTH = 4
		var LEN_TYPE = 4;
		var LEN_CRC = 4;
		var buf = new ArrayBuffer(LEN_LENGTH + LEN_TYPE + data.length + LEN_CRC);
		var view = new DataView(buf);

		var pos = 0;
		view.setUint32(0, data.length);
		pos += LEN_LENGTH;
		for (var i = 0, len = type.length; i < len; i++) {
			view.setUint8(pos++, type.charCodeAt(i));
		}
		for (var i = 0, len = data.length; i < len; i++) {
			view.setUint8(pos++, data.charCodeAt(i));
		}
		var crc = CRC32.bstr(type + data);
		view.setUint32(pos, crc);

		return String.fromCharCode.apply(null, new Uint8Array(buf));
	}

	var dataURL = canvas.toDataURL('image/png');
	var matched = dataURL.match(/^data:image\/png;base64,(.+)/);
	var base64 = matched[1];
	var png = atob(base64);
	// sRGB with Perceptual (0) rendering intent
	png = png.replace(/(....IDAT)/, pngChunk("sRGB", "\x00") + "$1");
	return 'data:image/png;base64,' + btoa(png);
}

こんなんでできます。やってることは sRGB チャンクを追加してるだけです。PNG は sRGB に関しては ICC プロファイルを埋めこむ必要なく、13バイト追加するだけですみます。

備考

Safari だと drawImage がうまくいかないです。ちゃんと追ってません。Safari はそもそも sRGB なのでやる必要ないです。

  1. トップ
  2. tech
  3. (黒魔術) CSS の色を sRGB にあわせるには

そういえば一ヶ月前ぐらい?から、ロードとパースに結構時間がかかっているのが嫌だなと思って HatenaStar.js を読みこむのをやめております。

簡単でポジティブなフィードバック手段がなくなったので寂しい気もしますが、しばらくこれでいこうという感じです。モダンブラウザ向けのミニマムな実装を書く気になったら復活するかもしれないけど、今のところそんな気力はない。

なんか他にもポジティブ評価しかできないフィードバック方法があればいいんですけどね。PVには色気がなく、はてブには善意がない。はてなスターはちょうどいいんだけどなあ。

もっとささやかな目標を少しずつ達成する必要があるのではないか。

例えば社会人になってから箸の持ちかたを改善したが、これは主観的に満足度が高かった。誰の得にもならなくても目標を達成できるのは良いことで、人生を良くすると感じる。

「日々の善行」を目標としてみたいが、正直いって荷が重い気がする。自然に毎日達成できるようなことではないからだ。心掛けはできても目標にはできない。善行チャンスを逃すなという心持ちではいたい。

「昨日よりも今日を良い日にする」はまぁまぁいい気がする。定量的な目標ではなく達成条件が比較的曖昧なのは良い。1週間のうち半分以上で達成できれば、全体としてプラスといえる。しかし曖昧すぎて難しい。「良い日」ってなんだろうか?

認知行動療法のうち認知療法はいまいちうさんくさい (結局性格を楽観的にしろとしか言っていないように感じるから) が、マインドフルネスはメタ認知しろという話なので比較的納得感がある。でも独りでマインドフルネス実践するのは難しいように感じる。

瞑想ってのが難しいポイントで、やりなれていなければできないし、やってみても何が正しい瞑想なのかわからない。「これであってるのか?」という疑問をいだきつつやっても不愉快になってしまうしやる気が起きない。

思考は思考で上書きするほうが簡単なので、自動思考が起きたとき他の思考を強制的に挟みこむように解決できないんだろうか。メタ認知は今起きていることの受容と洞察がキモだと思うけど、瞑想を通すと難しい。

立川 → 阿豆佐味天神社 → 東京都薬用植物園。

途中で南極・北極科学館というのを見かけたのでふらっと入ったけど面白かった。

機械遺産の極点到達雪上車が展示されているんだけど、なんと驚くことに中に入れる。4人分の寝るスペースが一応ある車なんだけど、とても狭い。機材がちょっと残っていてコリンズKWM-2Aという真空管無線機が置いてあった。

阿豆佐味天神社はそれほど面白くなかったので特筆するようなことはなし。

東京都薬用植物園は季節も季節なのであまり見所はなかった。初夏あたりが一番良いのかな? でも混んでなかったのでよかった。






  1. トップ
  2. photo
  3. 立川散歩

RGB等色関数のグラフではRGBの値が負の値をとることがある。つまり3原色ではこの色を再現できないということなのだが、意味がよくわかっていなかった。なぜ負になるのか? なぜ再現できない色が生じるのか? 改めて納得できるまで調べてみた。

短い結論

錐体細胞の感度のうち L錐体 と M錐体 の感度が近いため、RGBのうち特にG(緑)は純粋に緑とはみなせないから。

等色関数とは?

単一波長の光 (例えばレーザーのような) と、混色光 (RGB光) を比較して、どう混色すれば単色光と「同じ」に見えるかを関数化したもの。

人間の目の網膜のうち、色を感じる細胞である錐体細胞は3種類しかない。このため単色光で3つの錐体細胞が受ける刺激値を、3つの波長からなる混色光で再現できるならば、この単色と混色の光は人間の目には同一に見える (区別ができない)。

RGB等色関数とは以下のようなものである。ここでは 1931 CIE RGB 等色関数とした。このときの RGB の波長はそれぞれ 700nm/546.1nm/435.8nm。

一部の領域で R が負の値になることがわかる。これはBやGをどのように混色しても、この波長域の色を再現できず (具体的には彩度が足りない)、単色光のほうにRを足して等色したことを表している。

すなわちマイナスが含まれる領域はRGBで再現できない色となる。

備考 1931 CIE RGB 等色関数

上のグラフは厳密には 1931 CIE XYZ 等色関数を CIE RGB に変換するマトリクスをかけて求めたもの。XYZ 等色関数は LMS Fundamentals から変換した「生理学的に妥当な」ものが新しいものとしてあるが、これを CIE RGB に変換するとそれぞれの原色光のとき他の原色の値が0にならない。

XYZ から CIE RGB (白色点は等エネルギー点である E) への変換は以下の通り

人間の網膜細胞の感度

色を感じる細胞である錐体細胞には、L錐体 (Long=赤) M錐体 (Medium=緑) S錐体 (Short=青) と波長別に3つの種類がある。暗所で働く杆体という細胞もあるが、これは色には関係しないので今回は無視する。

それぞれの錐体にはRGBに波長のピークがあるが、実際の感度では重なりあう領域も大きい。特にL錐体とM錐体はかなりピークが近く、感度も似ている。これは進化の途中で一度M錐体相当のものを失い、再度L錐体から変異する形で獲得しなおしたという経緯があるためといわれている。

RGBの三原色で作り出せない単色光

錐体の感度と、等色関数を並べて、CIE RGB の原色光の波長に線をひいてみた。原色とは前にも書いた通り

  • 435.8 nm 青
  • 546.1 nm 緑
  • 700 nm 赤

青と緑の混合色で青緑の単色光を作ろうとしても彩度が足りないので再現ができないのはなぜか?

LMS のうち L錐体 と M錐体は感度ピークが近いことから、原色の緑とした 546.1nm の単色光は実は M錐体だけではなく、 L 錐体も反応させてしまう。例えば 500nm の単色光で のL 錐体での感度よりも、546.1nm でのL錐体の感度のほうが高いため、錐体への赤みの刺激が相対的に多くなり、純粋に青緑の色ではなくなってしまう。すなわち彩度が下がる。

LMS Fundamentals のグラフ 546.1nm のL錐体の感度は、500nm のときのL錐体の感度よりも大きい (赤みが強い)。

言い換えると、536.1nm は純粋にM錐体を刺激できるような「緑の光」ではないため、これを青と混色しても高彩度の青〜緑は再現できない。

青〜緑の波長領域のL錐体の感度が、546.1nmでのL錐体の感度よりも低い場合、その波長は青と緑の混色光では再現できないことになり、Rは負の値をとる。

ref

  1. トップ
  2. tech
  3. RGB等色関数で現れる負の値の正体

自分のことを尊重してくれない社会を尊重しようと思うか。

倫理観はこれで失われる。

Google は機械だけど、クラウドソーシングは人間なわけで、Google が「ハック」されないで勝つためには、Google の機械は人間を超えてないといけない。そうしなければハックされていない検索結果は出せない。この点だけでも、検索エンジンは人知を超えなければ生きのこれないことがわかる。

「ネットの口コミ」を探すとき、今の Google は使えない。Amazon のレビューも信用できない。Twitter で検索したほうが遥かに「ハックされてない」生の口コミが手に入る。そして、結局詳しい情報を得たいなら自分で触ってみるという原点に戻るしかなくなってしまった。

Google はページ滞在時間で有益性を評価していたりするみたいだけど、この評価軸が正しいとは思えない。では何を評価に使うか、何がページの有益性を示すか、というとよくわからない。有益だったかどうかはユーザの心の内にしかなく、極めて主観的で、外から取得することができない。

ここで「何が有益か」を人間が定めると、人知を超えないので結局人間によってハック可能になる。しかし機械学習には正解が必要で、有益さを評価できるナニかがなければ学習することができない。

昨年の4月にデザインの調整ということで、写真の最大サイズを 1024px まで上げていたのですが、これは Google Photos の無料アップロードサイズが長辺 2048px とされていたために、それまでアップロードしてきたものを鑑みつつ高解像度環境を見こんで半分としたものでした。

しかし Google Photos が最大 16MP まで無料アップロード可能となりしばらく16MPでのアップロードも増えてきたので、この度さらに最大サイズを 1600px まで上げました。ウィンドウサイズが 1650px を超えると、サイト全体の横幅が拡大し、photo カテゴリのエントリについては最大1600pxで表示されるようにしました。

現時点では仮対応という感じで、2048px の画像へのリクエストが走ったのちに、JavaScript で s0 (最大サイズ) をロードするようにしています。

画像の大きさ

1650px と中途半端なところでレスポンシブなのは、Retina 13-inch MacBook を「スペースを拡大」設定で使っている場合の横幅が 1680px なので、丁度これぐらいというところにあわせてあります。この日記の最大の読者である自分の環境というわけです。

大きな画像っていうのはそれだけで強い主張があります。かつてあった「体験」を呼び起こす力が画像の大きさと解像度にはあります。そこにいて、そこでこう見たのだという主張のため、とにかく大きいのは正義なのです。

現像環境と閲覧環境とのギャップ

写真は適切な閲覧環境とセットで成立すると思います。大画面で現像した結果をアップロードして縮小した画像を見てみたりすると「何か違うな」と思うわけです。視野に占める画像の大きさと、細かいところが見えるかという要素で、写真への没入感がかなり変わってしまいます。細かいところでいうと、本来出力サイズによってシャープネスのかけかたが変わってきます。

ウェブ公開の場合、閲覧環境をこれと指定することはできません。写真の閲覧に関する体験は閲覧者環境の画面の大きさや発色などの影響されるので、発信者はどこかで諦めるポイントがあります。

4K までのスケールアップ

ついでに 4K モニタ程度までの対応として以下のように transform で scale() をかけて徐々に拡大していくようなメディアクエリを入れてみました。

body {
    transform: scale(2); 
    transform-origin: center top;  
}

これは Chrome や Firefox だと綺麗にいくのですが Safari (10.01) だとなぜかボヤけることがあります。ボヤけないこともあるので、なにかしら条件があると思うのですが、よくわかりませんでした。transform はまだ鬼門かもしれません。

  1. トップ
  2. tech
  3. サイトの画像サイズを再びアップグレード

Google Photos は配信画像は基本的にすべて sRGB でなっています。

そこで ICC のテスト用 jpeg ファイル や、手元でいくつかカラースペースを変えた画像を Google Photos にアップロードしてどうなるか検証してみました。

結果

全ての画像で適切にカラースペースを変換しているようです。Google Photos は v2 でも v4 でもちゃんと認識して sRGB に変換しているようです。

ただし 500px 以上でアップロードした場合、s0 はオリジナルのカラープロファイルがそのまま残っています。また 500px 未満の場合 ICC プロファイルが削除されます。

ちなみに2015年2月ぐらいのPicasaでは元画像にsRGBを無条件に適用して色化けを起こしていました。地味に改善されてるみたいです。

出力のメタデータ

明示的に「オリジナル画像」としてダウンロードしない限りは EXIF などのメタデータ類はすべて削除されます。これは s0 (オリジナルサイズ) も同様です。

オリジナル画像

「オリジナル画像」の URL は Picasa の古いAPI から取得可能です。imgmax=d を指定して画像個別のフィードを取得すると、media:content に含まれています。

URL を知っていればクッキーなしで取得可能なようです。ただし、この画像は必ず Content-Disposition: attachment がついているため、ブラウザでは直接表示できず、ダウンロードするようになっています。

出力画像の ICC プロファイル

やや奇妙な挙動をすることがあって気になっていたので調べてみました。どうもサムネイルサイズによって含まれるかどうかが変わるようです。

  • s320 - なし
  • s480 - なし
  • s499 - なし
  • s500 - sRGB IEC61966-2-1 black scaled
  • s1024 - sRGB IEC61966-2-1 black scaled
  • s0 - オリジナルのプロファイル (ただし EXIFやXMP などは削除)

Google Photos を見ていると、拡大画面とリスト画面で色が変わることがあるのですが、どうやらサイズによってカラープロファイルの有無が変わることが関係していそうです。Google Chrome の場合、画像に ICC プロファイルが含まれていなければカラーマネジメントをしない (sRGB 扱いにしない) ので色が変わることがあります。

s0 はオリジナルプロファイルが適用されるようなので、sRGB 以外でアップロードした場合には使用に注意がいりそうです。

どこかで明示的にアナウンスされているわけではないので、仕様は突然変わったりする可能性はあります。

出力検証のメモ

以下のようにして exiftool で含まれるメタデータを全て確認しました。s0 とか s500 と言っているのは、この URL 中にあるサイズ指定の部分のことです。

$ curl https://lh3.googleusercontent.com/-BDMfJtqE7Mw/WIlEQ29H7II/AAAAAAAAnw0/2ZUwqimJUcQUbiLomaBrvwcrAebJFSjWQCE0/s0/IMG_9415-16MP-AdobeRGB.jpg | exiftool -
$ curl https://lh3.googleusercontent.com/-pEtCDwM8HhQ/WIlEQ5CSwLI/AAAAAAAAnw8/rAyZIkuFVzEk3x68vRLPAkkevHUxEicJQCE0/s2048/IMG_9415-16MP-ProPhotoRGB.jpg | exiftool -
  1. トップ
  2. tech
  3. Google Photos の ICC カラープロファイルの扱い

なんで今まで使っていなかったのか…… と思いました。

前提として、Google Photos はアシスタントを有効にしていると、適当にアップロードするだけで自動的にアルバムを作ってくれます。旅行のときは位置情報も参照してアルバム名も適切に設定されたりします。これは勝手につくってくれて、作ったら勝手に通知がくるので、特に面倒なことは一切ありません。

この状態で、作られたアルバムを共有設定にするだけで、共有相手の Google Photos にも即座に共有され、表示できるようになります。ここまででやることはアルバムの共有設定だけ。

そして実は、共有された側からアルバムを開くと、Google Photos 内にアルバムに追加できそうな写真が自動的にサジェストされて、数タップで追加できます。そうすると共有アルバムで相互に写真共有されます。

旅行とかにいくとお互いにスマフォで撮った写真は端末に別々に保存されてしまうわけですが、Google Photos の共有だと、ほんとにわずかなステップで共有できて便利です。

通知も細かくて、共有設定をしたら相手に通知がいくのはもちろんのこととして、共有したアルバムを開いたときには「見たよ」という通知が返ってきます。

制限

1つのアルバムにつき2000枚までしか追加できないみたいです。通常あんまりひっかからないと思いますが、1つのアルバムに全部つっこんで共有ってのは難しいので、ちゃんと細かい単位でアルバムにしたほうが良いです。粒度的にはアシスタントがやるような感じで、1日1アルバムか、1旅行1アルバムとかになりそうです。

経緯

これまで Dropbox 経由で家族写真を妻と共有するようにしていましたが、容量制限が厳しいので限られた写真しか共有できていませんでした。基本的には Lightroom で厳選して現像したものだけを共有してて、大部分の写真は (共有していないという意味では) 実質的に捨てていたわけです。

一方、基本的に撮った写真は全て Google Photos にアップロードしていました。16MP までは無料ということで特に迷いなくただただアップロードしていただけです。

アルバム機能は知ってはいましたが基本的に無視をしていて、使っていませんでした。なぜ無視をしていたかというと、共有設定しても妻側でちゃんと見れるのかを確かめるのが面倒くさかったからというのがあります。

しかし今や Google Photos は独立サービスになっており、Android の写真バックアップの中心的なアプリケーションになっているわけなので、既に使われており、特に面倒なことはありませんでした。共有設定するだけで何も問題なく通知が飛んで見れる状態になっていました。

みたいなことを言う人がいるわけですがね、そういうことをせざるを得ない状態になったことがない、他人の気持ちがわからないならせめてお前がまず黙っていてくれ。