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等色関数で現れる負の値の正体

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

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

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

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

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






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

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

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

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

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

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

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

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

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

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

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

何かを変えるためには習慣を変えるほかないということで、とりあえず毎日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 にあわせるには

このエントリの情報は古いです。現行 (2018年11月) のブラウザでは canvas の色の扱いが改善され、すべて sRGB で取り扱われるようになったため、以下のようなハックはできません。(できなくなったことは喜ばしいことです。)

(黒魔術) CSS の色を sRGB にあわせるには | tech - 氾濫原 というエントリを書いてから、ふと「もしかしてユーザー環境の色域 (モニタのプロファイル) を推定することができるのではないか」と思い至ったのでやってみました。

デモ: https://lowreal.net/2017/gamutdetect/

前提

ICC Profile を埋めこんだ画像を canvas に drawImage すると、プロファイル変換されたRGB値が描かれる。getImageData 経由でピクセル値を読むことでプロファイル変換済みのRGB値が得られる。

Chrome と Firefox だけで確認しています。これらのブラウザは上記の前提があてはまるからです。基本的に不具合に近い仕様だと思うので、そのうち動かなくなりそうです。あくまでネタってことです。

Safari と IE は OS レイヤーのカラーマネジメントなのが関係しているのか、putImageData や getImageData も sRGB として扱われていそうです。

戦略

プロファイルに影響される値がとれるということは、間接的にプロファイルを推定できるはずです。具体的には sRGB プロファイルで 0,255,0 という画像データがあったとき、これは sRGB の色域で 0,255,0 という色ですが、もしモニタプロファイルが Adobe RGB など広色域であれば、取得できる値は Adobe RGB の色域のためにもっと小さい (飽和していない) 値になると予想できます。

判定

実際にはモニタプロファイルを推定しているので「Adobe RGB の色域だ!」というのはおかしいのですが、近似として Adobe RGB / DCI P3 / sRGB の3種類の計算値の中から、近そうな色域として判定を出しています。

判定方法は sRGB で 0,255,0 (緑) の色が現在のモニタでどういう RGB 値になるかで行っています。255,0,0 (赤) と 0,0,255 (青) を判定にいれるとどうも変なので判定につかってません。もうちょっと考慮の余地がありそうです。

xy色図に色域をプロットする

sRGB の 200,55,55 / 55,200,55 / 55,55,200 をレンダリングした結果を読みとり、三元一次連立方程式を3つ解いてXYZへの変換マトリクスを逆算し、あらためてRGB各頂点のXYZ値を求めるという方法でxy色図に色域をプロットするようにしてみました。中途半端な値を使っているのは飽和させないためです。


こうするとやっていることが多少わかりやすいかなという気がします。

  1. トップ
  2. tech
  3. JavaScript で閲覧者モニタの色域を推定する

やりたいのは 1文字だけの改行の拒否 - Hail2u のようなことの延長です。長めの見出しがブラウザによって改行されると、どうもバランスが悪くなったり可読性が微妙になることが多い。これをなんとかする。

仕様

  • 元の高さから変わらないこと
    • 非同期にやってもガタガタしないこと
  • 各行ができるだけバランスをとること
    • 文字数 (正確には幅) をあわせる

元の高さから変わらないことというのは行数を変えないということです。これを制約にしてページ全体の高さに影響を与えないようにすることで、非同期的に行数を調整しても閲覧に支障がないようにという意図があります。

「各行のバランス」はできるだけ行ごとの幅を揃えるという意味でいっています。基本的に幅が揃うことはないので、あくまでできるだけです。また、揃わない場合には一番下の行が一番長くなるようにします。これはデザイン上、重心が下になるほうが安定して見えるからです。

実装

  • 改行しても良い単位ごとに文を分割する
  • 各セグメントの文字幅を計算し、各行に埋めていく

デモ

また、このサイトにも適用済みです。

文の分割

いわゆる形態素解析での単語単位の「わかち書き」だと分割されすぎてしまいます。基本的に文節単位で改行するのが適切ではないかと思うので、文節単位のわかち書き機みたいなのが欲しくなります。

そこで TinySegmenterMaker を使ってみました。TinySegmenter を任意の学習データから生成できる優れものです。TinySegmenter 自身は言語非依存のアルゴリズムのため、一般的な形態素解析の分割位置とは違う分割でも学習さえさせれば動いてくれそうです。

適当なコーパスを用意できなかったため、とりあえず自分で書いた日記 (これ) の過去ログを全て MeCab で解析し、副詞などを結合する処理を加えたあとにスペース区切りで出力し、TinySegmenterMaker の入力としました。学習データ的に汎用性は落ちますが、そもそも自分のサイト用なのでまぁいい気もします。

そんなに元データは多くありませんが結構時間がかかりました。

なお分割時の MeCab 辞書に mecab-ipadic-neologd も入れてます。不必要な分割が減ることを期待しています。

各行に埋める

1行に収まっている場合は処理しません。

場合によって全く改行位置を調整できないケースも生じます。つまり各行に文字がいっぱいっぱいに詰まっている場合、調整できません。この場合も諦めてブラウザにまかせます。ただ、最後のセグメントには改行禁止ゼロスペース文字を入れることで1文字だけ残るというのは可能な限り避けます。

文字幅の計算には canvas の measureText を使っています。カーニングやリガチャなどが適切に反映されない可能性がありますが、現時点だとこれ以上良い方法がない気がします。

Webフォントを使う場合、ロードされていることを実行前に保証する必要があります。document.fonts.ready がちゃんと使えればいいんですが、Safari の挙動がおかしいので使えませんでした。

そこで以下のようにしてWebフォントのロードを判定しています。

function webfontReady (font, opts) {
	if (!opts) opts = {};
	return new Promise(function (resolve, reject) {
		var canvas = document.createElement('canvas');
		var ctx = canvas.getContext('2d');
		var TEST_TEXT = "test.@01N日本語";
		var TEST_SIZE = "100px";


		var timeout = Date.now() + (opts.timeout || 3000);
		(function me () {
			ctx.font = TEST_SIZE + " '" + font + "', sans-serif";
			var w1 = ctx.measureText(TEST_TEXT).width;
			ctx.font = TEST_SIZE + " '" + font + "', serif";
			var w2 = ctx.measureText(TEST_TEXT).width;
			ctx.font = TEST_SIZE + " '" + font + "', monospace";
			var w3 = ctx.measureText(TEST_TEXT).width;
			console.log(w1, w2, w3);
			if (w1 === w2 && w1 === w3) {
				resolve();
			} else {
				if (Date.now() < timeout) {
					setTimeout(me, 100);
				} else {
					reject('timeout');
				}
			}
		})();
	});
}

もっと良くできるか?

本当は各形態素境界ごとにスコアリングして、読みやすい順に改行を加えるみたいなことができればいいんですが、僕の技術力だとむずかしそうです。クライアント幅によるという性質上、処理はクライアントサイドでやる必要がありますが、そうすると実行ファイルサイズも問題になってきます。

そもそも学習データとして「適切な改行位置」を与えるのが難しい問題があります。Cabocha を使えばもうちょっとマシになるでしょうか?

「下のほうを長くする」という方針がいまいちだと思います。意味的に区切れるところを優先して区切るのが正しいと思われます。

備考: TinySegmenterMaker のマルチスレッドバージョン

なんかどうも boost_system も必要でした。以下のようにコンパイルしました。

g++ -I/usr/local/include -L/usr/local/lib -DMULTITHREAD -lboost_thread-mt -lboost_system -O3 -o train train.cpp

あと train に引数を与えないとマルチスレッドで処理されませんでした。8スレッドでやるなら -m 8 を加えます。

./extract < /tmp/corpus.txt > features.txt
./train -t 0.001 -n 10000 -m 8 features.txt model
./maker javascript < model

レポジトリ

https://github.com/cho45/midashi-kaigyo あまり整理されてません。

追記: budou

ブコメ で教えてもらいましたが、Google がまさに同じことをやってました

Google の NL APIを使っているみたいです。

追記

文字を変形させるという発想がなかったのですが、編集系の識者のかたから長体かけつつ字送り詰めて押し込んだりしますという意見をいただきました。また、これを実現する方法として CSS transform を使えばいいのではないかという意見もいただきました。

  1. トップ
  2. tech
  3. 見出しの改行位置を適正化する試み

最近の Android 端末だと RAW 撮影に対応していることがある。あまり対応アプリケーションがないのだが Lightroom Mobile を使うと DNG (Adobe が策定した RAW 画像形式) 撮影して、そのまま現像もすることができる。

DNG 撮影すれば、たとえスマフォ撮影でも後処理はしやすくなる。通常ユースでは全くいらないかもしれないが突発的に時間ができて手元にスマフォしかないみたいな場合でも救えるケースがでてくるかもしれない。

スマフォでも一昔前のコンデジぐらいの画質はあることが多いので、RAW で撮影すればそこそこ見れる写真になることが期待できる。

端末の DNG 対応

端末が DNG 対応しているかどうか調べられないか? と思ったら、Lightroom Mobile だとちゃんと DNG 対応しているかどうかを表示するところがあった。まぁもちろん実際の撮影設定で DNG に設定できるなら対応ということなんだけど。

DNG 対応してない場合は以下の通り

Android DNG

API Level 21 (5.0 Lolipop) から ImageFormat.RAW_SENSOR や DngCreator というのが入っていたらしい。

現実的には CameraDevice が RAW をサポートしているかどうかで実際に出力できるか変わりそうだが、いまいち市場での対応状況はわからない。スペックに RAW 撮影対応かどうか書いてあるのを見たことがない。

手元の ZenFone 3 だと Lightroom Mobile で DNG が生成できることは確認できた。ただ、 ZenFone 3 はそもそもカメラの性能がいまいちなのでそれほどテンションあがるわけではない。

  1. トップ
  2. tech
  3. Android 版 Lightroom Mobile の DNG 撮影

「他の人ってちゃんと目標があったりしてすごい」イラストレーター・べつやくれいさんに聞く仕事の話 - はたらく女性の深呼吸マガジン「りっすん」 この記事がおもしろかった。こういう記事って媒体に載りにくいんだよな。運だから…… 全ての成功は完全に運なのだが、才能がない人 (正確には現代の極めて狭い評価範囲での能力値が低い人) をマウンティングするために、社会的には努力で勝ちとるというストーリーってのが好まれている。

自分ができることを「努力すれば誰でもできる」と考えるのは、謙遜しているように見えて背後に「おれは努力したんだ」という自尊心が隠れている。実際は半分ぐらいは運が良かっただけなので、これは明確に驕りである。努力は努力する環境と努力する才能によっているため、残りの半分にも本人の意志なんてものはなにもありはせず、運で構成される。与えられたものに気付かないのはきつい。


プログラマってのも努力っていうより才能が支配的ではないかと感じることが多くなってきた。もともとは「プログラムなんてのは目覚し時計の設定と同じで慣れれば誰でも書けるようになる」派で、まぁこれは今もある程度は間違っていないと思うが、特に優れた人ってのはやはり才能によっていると思う。

いまいちITは産業として成熟していないので「フツーの人がフツーに生きていく」というモデルは構築されておらず「あの人を目標にして生きていこう」みたいな考えかたは難しい。目立つ人は極めて優秀なことが多い。プログラマの生産性の違いについて見たことある人はいるだろう。この業界は才能ある人に強く支えられている。その差は埋められないのに埋められると信じて生きるのはきつい。個人的には「フツーの人がフツーに生きていく」というモデルは IT 企業以外の企業で内製サービスのプログラマをやるというので実現されるような感じがするが、まだそういうところまでIT化がすすんでいないように思う。

できないことや、やりたくないことを明確にして、消去法で「できそうだ」「やれそうだ」ということを明確にするような、例えばただの木の塊から仏像を掘るような輪郭のとりだしかたもあって当然で、それは全く間違えていないのに、消去法にネガティブなイメージがあるのはいまいち良くない。3Dプリンタみたいに積み重ねれば目標が達成できるような世界観で生きれたらそりゃ幸福だろうが、そんなのは簡単な生きかたである。

写真の右下に exif 情報を出すようにしてみた。どう表示させるのがいいのか悩んだけど、とりあえず常時表示してみることに。ほんとは最初の時点では表示させたくないんだけど、hover で出るってのもなんかなあという感じだった。

Google Photos の画像の exif を得る

Google Photos の画像から exif 情報を得るのは簡単ではない。表示しているサムネイルのURLから exif 情報をとれるのが一番簡単なのだが、これはたぶんできない。URL にオリジナル画像や、後述するAPIリクエストに必要な情報が含まれているように見えない。

幸いこの日記では picasa へのリンク ( https://picasaweb.google.com/[userid/[albumid]#[photoid] みたいな形式 ) は保存してあったので、これを利用することにした。

exif を取得したい場合大きくわけると2つの方法がある

  • オリジナル画像をダウンロードして自力で exif を解析する
  • API 経由で取得する

が、オリジナル画像の URL を取得するためには API リクエストをしないといけないので、とにかく API リクエストを行う必要がある。オリジナル画像の URL を取得するレスポンスには exif のメタデータも含むため、これで足りるならわざわざオリジナル画像をダウンロードする必要はない

Invalid な albumid を回避する

Picasa API という既にメンテされていないAPIを使わなければならないのだが、userid albumid photoid 全てがわかっていないと画像のメタデータを取得することができない。

保存されている picasa へのリンクに全てあるのだが、albumid に invalid なものが含まれることがある。これは Google Picker API 経由で取得したものなので、 Picker API がなんか不思議な URL を返すようだ。意味がわからないんだけどなぜかそうなっている。

これじゃあ無理かと思いつつ試していたところ、albumid は valid で存在してさえいれば、photoid の親でなくとも良いということがわかった。画像が含まれるアルバムのIDというのを知る必要はないのだ。

ということで、userid は簡単に調べられるし、albumid には適当に存在する albumid を指定しておけばよいということなので、実質的には photoid だけでメタデータを取得できた。

  1. トップ
  2. tech
  3. Google Photos の画像の exif を API 経由で得て表示

電源回路がほんと難しい。スイッチング電源を設計通りに動作できたことがないので大変に苦手意識がついている。

ちょっと LED ドライバ用に昇圧させようというだけなのだが、どこかの設計ミス〜実装ミスで十分な性能が出ていない。しかしどこのミスなのかわからない。うーん。

電源は避けて通れないんだけどなあ。

その後いろいろ調べた結果、インダクタンスが不足していたことがわかった。データシートに出てくる方程式は必ず一通り計算しつくしておくこと。

フロントエンドはブラウザの実装と普及に律速されるので、それほど急にできることが増えたりはしない。全てのブラウザに実装がのったとしても、十分に普及するには年単位で時間がかかる。なので急いで何かを覚える必要があるってことはまずない。


破壊と再生が繰替えされてるのは、実現性に影響するようなクリティカルな部分ではなくて、便利ツールとか便利な考え方とかの部分なので、不便を感じはじめるまで評価を遅延しても良い。

ウェブフロントエンドは動きが早いように見えるけど、あれは暇な人がそういうふうに見えるようにしているだけで、実際はそうでもない。「今はこれを覚えるべき!」みたいなのが時々あるが、いいたいだけで内容がないのであまり気にしないこと。

ずっと追いかけていないと取り残されるみたいな焦燥感を持つ必要はない。人生有限なので他に楽しそうなことがあればそっちやっていくほうが良い。

Raspbian 2016-11-25 のリリースから ssh がデフォルトで無効になっていて port 22: Connection refused となる。

起動してからキーボードで有効化してもいいが、boot パーティション (FAT) のルートに "ssh" という名前のファイルを作っておけば、sshd が起動するようになっている。

たとえば (OS X ) 以下のように

touch /Volumes/boot/ssh
sudo umount /Volumes/boot 
  1. トップ
  2. tech
  3. 最近の Raspberry Pi はデフォルトで ssh が無効

松田山ハーブガーデン。何度か来てる。今回で3回目か4回目ぐらい。河津桜は終わり気味なので人は少なめ。しかし自分にはちょうど良かった。人だかりで満開なときよりは、散り気味で人がすくないときに行ったほうが満足度が高い。



あぐりパーク嵯峨山苑 (内藤園) ここは初めていった。ハーブガーデンからさらに急な坂を歩く必要があって結構つらい。園内も急斜面で道が狭いのでちょっとこわい。しかしほんとに絶景だった。

寒田神社


  1. トップ
  2. photo
  3. 松田山

SIGMA 単焦点広角レンズ Art 35mm F1.4 DG HSM キヤノン用 フルサイズ対応 340544 - シグマ(Sigma)

シグマ(Sigma)

5.0 / 5.0

かなり久しぶりに EF マウントのレンズを買った気がする。ほんとは 50mm を無駄に買い足ししたかったが、手元に EF 50mm F1.4 は一応あるし、35mm は手放して手元になかったので 35mm にした。

噂通りでピント面の解像度はとても高い。そして解放で使ってもそれほどコマ収差がない。

35mm は久しぶりに使ったけど結構苦手意識がある。寄ったとき背景を整理するのが難しい。使ってて気楽な 100mm は主題以外あんまり考えてなくていいゆとり仕様なんだよなと思った。

この前の松田山 には 35mm と 100mm を持っていったけど、結局 35mm だけで撮った。

  1. トップ
  2. photo
  3. SIGMA 35mm F1.4 DG HSM | Art を買った

最近は Google 以外のサイトのパスワードを一切覚えないという運用を試しています。つまり

head /dev/random| shasum | base64  

のように完全ランダムで生成してパスワードを設定し、ブラウザ (Chrome) に覚えさせてログインします。

SHA1 の Base64 で 61 文字のパスワードになります。ときどきパスワードの全長に制限をかけているクソサイトとかがあるので、そういうときは適当にぶった切ります。まぁとにかく保存するのでなんでもいいんです。アカウント復旧に必要なメールのパスワード強度より強くしても無駄です。

パスワードが保存されず、セッションが切れた場合

ときどき Chrome でちゃんとパスワードが保存されないことがあります。これでセッションが切れるとどうにもなりません。

こういうときは諦めて毎回パスワード再発行をします。だいたいの場合メールがきてすぐ再設定できるので「パスワードを忘れるリスク」はパスワードが簡単でハックされるリスクよりもかなり低いのです。

これはつまりメールのパスワードが全体のセキュリティを決めます。gmail など信用できるサービスで2要素認証を使うなどしてここをとにかく強くしておきます。

スマフォアプリ

この方法だとスマフォのネイティブアプリでパスワードを入力する際に困ったことになります。そもそもネイティブアプリでパスワードを入力させるのとかクソだと思いますが (ブラウザに飛ばして戻ってくるように設計するのが正しいと思う)、それはともかく現実的に困ります。

解決方法はあって、Google Chrome で保存したパスワードは、実はブラウザ上からすべて見ることができるようになっていますので、これを使います。

大変わかりやすいドメインでありがたいですね。Google のパスワードさえ覚えていれば、保存済みの全てのサイトのパスワードを閲覧することができるという破滅的ページとなっています。

とにかく、ここで表示するアイコンを押してコピーすればどこにでも入力できます。

良い点

Google アカウントは万が一それ自身のパスワードを忘れた場合の復旧手順や、2要素認証の方法を失った場合の復旧手順がしっかりしています。BAN されない限りはかなり強力なバックアップです。

悪い点

ウェブサイトがないサービスのパスワードは覚えることができません。

Google に完全に依存します。Google なしで他のサイトにログインすることができなくなります。一番こわいのは BAN されて復旧できないことなので品行方正に生きていきましょう。まじで詰みます。