2017年 05月 12日

BLE のエラーコード一覧

Bluetooth Explorer とかで見ることができる disconnect 時などのエラーコード

Bluetooth 4.2 の Spec PDF を落として、Vol 2 → Part D と辿ると一覧がある。

よくある系

  • 0x08 Connection Timeout
  • 0x16 Connection Terminated by Local Host
  • 0x22 LMP (Link Manager Protocol) Response Timeout / LL (Logical Link) Response Timeout
2017年 05月 11日

サイトの写真の表示方法の変更

サイトのCSS・JSのちょっとした変更。1ヶ月前ぐらいから写真まわりにちょいちょい変更をいれてる。

  • 写真の高さを 100vh に制限するようにした
  • ある程度以上のスクリーンサイズのときは16MPをロードするが、時間がかかるため、あらかじめ同等の大きさの灰色の画像を表示するようにした
  • ロード中にロード中とわかるようにアニメーションをつけた (Spinner)

アスペクト比を維持した画像のリサイズがむずかしい

このサイトの画像 (img 要素) は以下のようになっている

  • max-width max-height を指定
  • width: auto; height: auto を指定
  • 十分に大きなサイズの画像を指定

これにより、max-width/max-height を超えない限り最大の大きさで、アスペクト比を保って表示することができる。しかし問題点がある。

問題点:ロード時にレイアウトが確定しない

img 要素にはロード先画像の width 及び height を属性値で指定してあるのだが、CSSで auto を指定しているため、実際に画像のサイズが得られるまで、レイアウトが確定しない。つまり画像ロードのタイミングで不定期にリフローが起こり、ページ全体の高さが変わる。

JS では実行タイミングがどうしても遅くなるので、できればCSSで対応したいが、うまい方法がない。

せっかくwidth/height 属性値でサイズを指定していて、アスペクト比がわかっていて、理論上は幅と高さを確定することができるはずなのに、これが現状ではできそうにない。

現行の対策

いい方法が思いつかなかったため、JSで動的に対処した。img 要素の width/height 属性をもとに canvas で画像を生成して、まずはこれを表示する。

これによって本来の画像を読みこむ前に、HTMLの情報だけでレイアウトを確定させることができるため、画像がロードされるたびにページの高さが変わるということはなくなる。

しかし JS でやっているため、高さが未確定の状態で1度レンダリングされてしまう。

2017年 04月 20日

Sierra にしたらリモートの日本語が化けるようになった

以下のような環境で日本語が化けるようになった。

  • macOS Sierra
  • リモートで screen を使っている
  • ssh host -t screen -r で復帰している

問題ないケース

  • Sierra にする前は問題なかった
  • ssh host して手動で screen -r

解決方法

どうやら ssh -t したとき、特定の環境変数がリモートに渡されなくなったみたいだった。以下のように ~/.ssh/config に追記した

SendEnv LANG

Sierra での man ssh から抜粋。複数書く場合はスペース区切りか SendEnv 自体を複数書けば良い。

Specifies what variables from the local environ(7) should be sent to the server. The server must also support it, and the server must be configured to accept these environment variables. Note that the TERM environment variable is always sent whenever a pseudo-terminal is requested as it is required by the protocol. Refer to AcceptEnv in sshd_config(5) for how to configure the server. Variables are specified by name, which may contain wildcard characters. Multiple environment variables may be separated by whitespace or spread across multiple SendEnv directives. The default is not to send any environment variables.

2017年 04月 14日

Ruby Sequel で生 SQL をメインに使う

Sequel はドキュメント見ると SQL そのまま書くやりかたもとクエリビルダを介すやりかたも許されていると感じるので (別に他のライブラリでも可能だろうが)、導入負荷が低くてよさそうです。結構機能はもりだくさんありますが必要なければ使わないのも許されてる感じもよさそうです。

Sequel でのクエリ発行のしかたは sequel/querying.rdoc at master · jeremyevans/sequel · GitHub を読むとだいたい網羅できるが、特に自分に重要なところだけ別途メモしておく。

モデルを使っても使わなくても SQL クエリはそのまま発行できる。複雑な JOIN も安心。

モデルを使わない場合

SQL を発行して Hash として取得できる。

dastaset = DB["SELECT * FROM foo"]
dataset.all # 全インスタンス化

モデルを使う場合

任意の SQL を発行しつつあるモデルとしてインスタンス化したい場合

class Foo < Sequel::Model(:foo)
end

dataset = Foo.with_sql("SELECT * FROM foo")
dataset.all # 全インスタンス化

Sequel::Model(:foo) の :foo はテーブル名を渡す。何も渡さないとクラス名を複数形にしたものを探そうとする。が明示したほうが良いと思います。

どういうときにモデルを使うか

使いたいときに使う。単にクエリ投げたいだけならモデルはいらないし、特に JOIN がからむなら余計なことせず Hash で返ってくるのは気楽で良い。

機能的な面からいえば、DBからひいてきたインスタンスにメソッドを生やしたいというときはモデルを使ったほうが楽。既存の行を update したいときもモデルがあったほうが楽。

Sequel のモデルも若干マジカルで、DBコネクションがないとモデル定義できなかったりする。キモいけどテーブル情報を使ってアクセサを定義したりするっぽい。

JavaScript で MQTT するなら MQTT.js が良い

https://github.com/mqttjs/MQTT.js

  • ブラウザ (MQTT over WebSocket) でも node.js でもほぼ同じ使いかたができる
  • 自動でリコネクトしてくれる
  • API がモダン

Eclipse Paho の JS 版を一時期使っていたが、完全に乗り換えました。

MQTT over WebSocket の場合

ドキュメントの通りだけど以下のようにする。TLS なら wss にするだけ。

		const client = mqtt.connect("ws://" + location.hostname + ":" + (location.port || 80) + "/mqtt", {
			username: USER,
			password: PASS,
			reconnectPeriod: 500
		});
2017年 04月 13日

Material Design Lite のテキストフィールドと Vue.js の相性があんまりよくない

Material Design Lite のテキストフィールドの input 要素を Vue.js で扱うとき、普通に v-model で two way binding すると、ラベル位置が更新されなくて文字が重なってしまったりする。つまりこれは Vue.js側の更新処理がMDL側に適切に伝わっていないために起こる。

MDLのソースを軽く読んだ解決として、mdl-js-textfield クラスがついている親要素に v-mdl 属性を追加し、以下のようにカスタムディレクティブを定義すると解決する。あんまり美しくないがしかたない。

静的な要素だけなら upgradeElementは必須ではないが、動的になると必須になるためついでにやっている。

Vue.directive('mdl', {
	bind: function (el) {
		componentHandler.upgradeElement(el);
	},

	update: function (el, binding, vnode) {
		const textfield = el.MaterialTextfield;
		if (textfield) {
			Vue.nextTick(function () {
				textfield.checkDisabled();
				textfield.checkValidity();
				textfield.checkDirty();
				textfield.checkFocus();
			});
		}
	}
});
2017年 04月 05日

Google Photos の ICC カラープロファイルの扱いの続き

Google Photos の ICC カラープロファイルの扱い | tech - 氾濫原 の続きです。前回のまとめとしては

  • Google Photos は基本的に sRGB に変換
  • s0 (オリジナル同等サイズ) のみ元々のカラープロファイルが保持される
  • 500px 未満の場合はカラープロファイルが削除される

でした。

ただしある程度時間が経つまではオリジナルのプロファイルの画像が配信されることがあることがわかりました。

検証の試行錯誤

今日追試してみたところ、前回わかったルールよりもうすこし複雑なようだぞという挙動にみえ、ついでにいうと法則性がわかりませんでした。

あらたなファイルをアップロードして検証

今日あらたにアップロードしたファイルで検証してみました。以下のようにして s0 の部分をかえています。

curl https://lh3.googleusercontent.com/-4gapCD_T4ag/WOT-_iAPFkI/AAAAAAAAu-I/KXcMpxSoEcMurTrZ3umFh8nfOfOV88knQCE0/s0/IMG_7343-16MP-2.jpg | exiftool -
  • s320 - なし
  • s480 - なし
  • s499 - なし
  • s500 - sRGB IEC61966-2-1 black scaled
  • s1024 - sRGB IEC61966-2-1 black scaled
  • s1280 - sRGB IEC61966-2-1 black scaled
  • s1919 - sRGB IEC61966-2-1 black scaled
  • s1920 - オリジナルのプロファイル (ただし EXIFやXMP などは削除)
  • s1921 - sRGB IEC61966-2-1 black scaled
  • s2047 - sRGB IEC61966-2-1 black scaled
  • s2048 - オリジナルのプロファイル (ただし EXIFやXMP などは削除)
  • s2049 - sRGB IEC61966-2-1 black scaled
  • s0 - オリジナルのプロファイル (ただし EXIFやXMP などは削除)

前回のファイルを再度検証

一方、前回検証したときに使ったファイルを再度検証してみましたが、こちらは前回と変わりませんでした。

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 -
  • s320 - なし
  • s480 - なし
  • s499 - なし
  • s500 - sRGB IEC61966-2-1 black scaled
  • s1024 - sRGB IEC61966-2-1 black scaled
  • s1280 - sRGB IEC61966-2-1 black scaled
  • s1919 - sRGB IEC61966-2-1 black scaled
  • s1920 - sRGB IEC61966-2-1 black scaled
  • s1921 - sRGB IEC61966-2-1 black scaled
  • s2047 - sRGB IEC61966-2-1 black scaled
  • s2048 - sRGB IEC61966-2-1 black scaled
  • s2049 - sRGB IEC61966-2-1 black scaled
  • s0 - オリジナルのプロファイル (ただし EXIFやXMP などは削除)

よくわからないので、前回と同じファイルをアップロードしなおしてみましたが変わらず。

同じ内容ですこし違うファイルを再アップロード

しかし s0 をダウンロードしたものを再度アップロードすると今度は以下のような結果に…

curl https://lh3.googleusercontent.com/-ykbJTkOQRME/WOUC9VszXHI/AAAAAAAAu-g/E5q6Ds_DJu06zrYiOK8J2FKNbmMjlU34ACE0/s2049/IMG_9415-16MP-AdobeRGB.jpg | exiftool -
  • s320 - なし
  • s480 - なし
  • s499 - なし
  • s500 - オリジナルのプロファイル (ただし EXIFやXMP などは削除)
  • s1024 - sRGB IEC61966-2-1 black scaled
  • s1280 - sRGB IEC61966-2-1 black scaled
  • s1919 - オリジナルのプロファイル (ただし EXIFやXMP などは削除)
  • s1920 - オリジナルのプロファイル (ただし EXIFやXMP などは削除)
  • s1921 - オリジナルのプロファイル (ただし EXIFやXMP などは削除)
  • s2047 - オリジナルのプロファイル (ただし EXIFやXMP などは削除)
  • s2048 - オリジナルのプロファイル (ただし EXIFやXMP などは削除)
  • s2049 - オリジナルのプロファイル (ただし EXIFやXMP などは削除)
  • s0 - オリジナルのプロファイル (ただし EXIFやXMP などは削除)

なぜか s500 でオリジナルが適用されていたり、だいたいオリジナルが適用されるかと思いきや s1024 や s1280 では sRGB になったりと意味不明です。

落ち着く

あきらかに挙動に疑問があるので、一旦冷静になります。さすがに Google といえどファイル内容を見てプロファイルを埋め込むかどうかを判定しているわけではないだろうし、なぜこんなことに……

と少し時間が経過してから再度検証してみたところ、結局 s0 以外は全て sRGB になりました。つまり

  • 動的にリサイズする場合はプロファイルが保持される (s0 はリサイズしないのでそのまま)
  • リサイズ結果は sRGB となり静的にキャッシュされる

が真相のようでした。動的にリサイズする場合はプロファイル変換までやるとオーバーヘッドがあるためプロファイルを埋め込むみたいな戦略なんでしょうかね?

2017年 03月 30日

Safari 10.1 から CSS でも広色域対応

New Web Features in Safari 10.1 | WebKit

Editor’s Draft の CSS Color Module Level 4 を実装する形で Safari に color() が入ったみたい。

color() = color( [ <ident>? [ <number>+ | <string> ] [ / <alpha-value> ]? ]# , <color>? )

Apple はデバイスの DCI P3 対応をすすめてるのでその一貫なのかな。写真はもちろん広色域表示が現状でも可能なんだろうが、これがウェブのCSS色でも可能になる。広色域な画像とサイトのCSS色とを完全に一致させる方法は今までなかったが、これによって実現できるようになる。

2017年 03月 22日

Android O から広色域ディスプレイがサポートされる

デベロッパープレビューのそのようなことが書いてあった。

Wide-gamut color for apps: Android developers of imaging apps can now take advantage of new devices that have a wide-gamut color capable display. To display wide gamut images, apps will need to enable a flag in their manifest (per activity) and load bitmaps with an embedded wide color profile (AdobeRGB, Pro Photo RGB, DCI-P3, etc.).

https://android-developers.googleblog.com/2017/03/first-preview-of-android-o.html

アクティビティごとに設定が必要らしい。Lightroom Mobile みたいなアプリが恩恵をうけそうだ。ブラウザは対応するだろうか?

2017年 03月 18日

長年の悩みだったレンズ前玉の汚れが落ちた……

5年ぐらい前 (というか買った直後ぐらい)に EF 100mm F2.8 MACRO に傷をつけてしまっていて、ずっとそのことについては心にトゲが刺さったような気持ちだった。まぁとても小さい傷なので画質に問題はないだろうと思いそのまま使っていたし、実際撮影画像見ても一切わからないので、純粋に心のトゲの問題である。

過去に試した方法

傷?汚れ?をつけてしまったあとに試したのはハクバのレンズペンだったが、これでは落ちなかった。

ハクバ HAKUBA メンテナンス用品 レンズペン3 【レンズ用】 ブラック KMC-LP12B - ハクバ

ハクバ

3.0 / 5.0

指紋は綺麗に落ちるので、ついてしまったのが落ちないのは汚れではなく傷になってしまっているからだろうとこの時思い込んでしまっていた。

今日、試した方法

ふと思いついて無水エタノールをキムワイプにつけて優しく何度かこすってみたところ、傷だと思っていたものはみるみるうちにあっさり消滅した。つまり傷だと思いこんでいたものは落ちにくい汚れだったというオチであった。

健栄製薬 無水エタノールP 500ml(掃除) - 健栄製薬

健栄製薬

5.0 / 5.0

ほかの方法

レンズコーティングがどういうものなのかわからない以上、無水エタノールも絶対に安全とはいえず、界面活性剤タイプが一番安全なはず。

界面活性剤タイプだとフジのがよく使われているっぽい。揮発しないので完全に拭き取らないといけないところが面倒なところ。

FUJIFILM レンズクリーニングリキッド 30CC LENS CLEANING LIQUID 30CC - 富士フイルム(FUJIFILM)

富士フイルム(FUJIFILM)

3.0 / 5.0

しかし調べた感じだとレンズコーティングはそんなに簡単に剥れたりするものではない (溶剤よりも摩擦を心配すべき) っぽい。ので無水エタノールでも良いのではないかという結論にいたった。

無水エタノールはかなり揮発性が高いので余計なものが恒久的に表面に残るという心配がないのは安心。

ペーパーは「ダスパー」というレーヨンでつくられたものが良いらしい。今回は使わなかったが次回からこれを使いたい。

日本製 レンズ クリーニングペーパー 小津産業 Dusper(ダスパー)K-3 標準サイズ - 小津産業

小津産業

3.0 / 5.0

安全な方法

安全な順に

  1. メーカーに清掃修理依頼を出す
  2. 乾式のレンズクリーナーを使う
  3. 界面活性剤タイプの洗浄剤を使う
  4. 無水エタノールを使う

さらに強力な方法もあるが、プラスチックを侵すので無水エタノールでダメなら諦めたほうがいいと思う。